Lecture Overview
Design
- Software Design
- Each module or component has an interface and a body. The interface is all elements of a module available to the users of the module. The body is the internal details.
- Information hiding: the interface should be separated from the body and users of the module should only rely on the interface.
- Low Coupling: modules should be largely independent of each other.
- High Cohesion: similar functions should be grouped together into a module
- Top Down and Bottom Up
- Top Down: divide the task into subtasks, divide subtasks into subsubtasks, and so on. Eventually, each subtask becomes a function or a method or an object.
- Bottom Up: specify and build some useful functions and/or objects and/or methods, without knowing exactly where the functions/objects/methods will be used. Then link these functions/objects/methods together to form larger useful objects (maybe as well without a clear design goal), link objects together to form modules, link modules together to form the program, eventually obtaining the complete program.
- Object Oriented Programming is a natural fit for bottom up design. In OOP, you look at the
- problem domain and then design some objects that you expect will be useful. You then create more useful objects that make use of your existing objects. In this way, you can gradually build enough tools to complete the program.
- Most of the time a program is designed using a combination of top down and bottom up design.
Example
A larger example of classes and objects:
The problem is to simulate the Predator-Prey Relationship using python. The specific example is fish and bears. The following are the rules of the simulation:
- The fish and bears are tracked on a rectangular grid with at most one animal per position.
- Each turn, the animals move one grid location randomly.
- If a bear is next to a fish, it eats it.
- If a bear does not eat in 20 turns, it dies.
- If three fish are next to each other, one of the fish dies. (This is to simulate not enough habitat or resources for the prey.)
- Every fixed number of turns (10 for fish, 21 for bears), each animal breeds by creating a new animal.
The design is bottom up: first we will create classes for Fish and Bears with some useful methods without a clear picture of how they will be used. For example, the Bear class will need properties x
and y
for its location, a property for how long it has been since the bear has eaten, a method to check if there is a fish to eat, and so on. After listing these properties and methods for the Fish and Bear class, we notice that there are several similarity (e.g. both store x
and y
and have to move randomly). So bottom up design say create a class for this similarity: we create an Animal class and then make both the Fish and Bear class inherit from the Animal class. Note that in bottom up design, we made the Animal class after we initially designed the fish and bear classes. The results of this design are in day27_animals.py
. Note that I created day27_animals.py
without a clear picture of where these classes will exactly be used.
The next thing we need is a World class to track the positions of the Fish and Bears. Note that the World class can take advantage of the pre-existing classes without having to care about the details of Fish and Bears, just that each class implements the rules for Fish and Bears. We then give the world some useful methods like adding and killing animals, drawing the animals on the screen. This is day27_world.py
.
Finally, in day27_simulation.py
, we combine all of these tools into our program.
Exercises
No homework, finish up the project.