Download Understanding Object-Oriented Design: Abstraction & Inheritance in Class & System Design and more Study Guides, Projects, Research Software Engineering in PDF only on Docsity!
Object-Oriented
Design
Design
Design is something you do when your brain is too small to
hold the entire project.
Design is about managing complexity: a design method
helps you to split big projects into manageable chunks the
will fit in your brain.
Design methods provide a notation, which allows you to
store (for example, on paper or on computer) and
communicate design decisions.
An Example of Abstraction
- I can teach someone to drive any car by using an abstraction.
- I teach about the ignition and steering wheel
- I eliminate the details, such as the particular engine in this car
or the way fuel is pumped to the engine where a spark ignites
it, it explodes pushing down a piston and driving a crankshaft.
- Problems usually have levels of abstraction.
- We can see a car at a high level of abstraction for driving but
mechanics need to work at a lower level of abstraction: they do
care about details and need to know about batteries and engines.
An Example of Abstraction
However, there are abstractions at the mechanic’s level too.
The mechanic might test or charge a battery without caring
that inside the battery there’s a complex chemical reaction
going on.
A battery designer would care about these details but
wouldn’t care about, say, the electronics that go into the
car’s radio.
We can look at the details such as the battery or radio design,
and see that they are separated in manageable chunks.
And by using abstraction and ignoring the details, we can
also look at the whole car as a manageable chunk.
Class
- Classes are useful because they act as a blueprint for objects.
- If we want a new Square, we use the Square class and simply fill in the particular details (i.e. its color and position).
- The diagram below represents the Square class.
- This class has two attributes: a color and an array of points,
- and two operations: setColor() and draw(). Square :color :point[4] setColor() draw()
Class
• Imagine that, as well as Squares, we have^ Triangles.
• There’s some difference between^ Triangles and Squares.
• Triangles have three vertices; Squares have four.
• Also, the way that these shapes are drawn is different.
Triangle :color :point[3] setColor() draw()
Class
To do this we move the important common parts out of these
classes into a new class called Shape.
Square :point[4] draw() Triangle :point[3] draw() Shape :color setColor() draw()
Class
This sort of abstraction is called inheritance.
The lower-level classes (known as subclasses or derived
classes) inherit state and behavior from this higher-level
class (known as a superclass or base class).
So, for example, a Triangle object will have a color, a
set_color() operation, three Points and a draw() operation.
Aggregation
We can also abstract by combining objects inside a new
object.
In the car example, a car combines a battery, engine and
other objects into a new object and provides a simple
interface for driving that hides these details.
Example: picture editor
One requirement is that we can have several windows
showing the picture at one time.
The important thing about multiple views is that when the
picture changes (through the user editing it in one window),
all of the windows are updated.
The problem is to model how this update occurs in our
program.
Let’s think about the objects that might be involved.
We’ve been talking about pictures and views so we’ll use
the words Picture and PictureViewer as classes
Class Diagram
- Now we can draw a class diagram to see how the Picture and PictureViewer classes are related.
- Notice that a Picture must communicate with a number of PictureViewers.
- It must also know which PictureViewers are associated with it.
- The topmost black circle and line captures this information: it means that Picture “has” a number of PictureViewers.
- This doesn’t mean that Picture actually contains the PictureViewers: it might look them up in a table or database or use some other object to store them. Picture draw() update() PictureViewer 0..N update() 1 has has
Class
• You might be thinking that these diagrams are trivial and that there’s no
point in drawing them.
• However, the class diagram clearly shows an important problem: Picture
and PictureViewer depend on each other and so cannot be used separately.
• The classes are^ tightly coupled.
• Tight coupling means that if you change one, both must be recompiled.
• Tight coupling is not always a bad thing, for example, we would expect
list and list_iterator to be tightly coupled.
• It doesn’t make sense to have one without the other.
Abstraction
• Picture now only relies on PictureObserver.
• If we re-use Picture we take PictureObserver along too, but
PictureObserver only contains the interface of the update() function - that’s useful
• the DTPdocument might need to reformat itself if the picture changes
so it would inherit from PictureObserver.
• Another benefit of this abstraction is that we can have different types of
observers.
• For example, if we wanted to add a statistics window showing say,
amount of memory used by the picture and how many shapes were in it, we would want it to update as the window was changed, and, to do so, we simply derive a StatsViewer class from PictureObserver.
Example: Picture Editor
- The user can create a new picture
- The new picture will contain no shapes
- A^ window will be opened displaying the new picture
- The user can add a shape to the picture
- The user can create a “new view” of a picture
- This means there may be several windows showing the same picture at one time
- Changes to the picture made via one window must be reflected in all windows showing that picture
- The user can select a number of objects (the objects are known as the selection)
- A^ rectangle is drawn around shapes that are selected
- Each window has its own unique selection
- The user may move the selection
- The user may delete the selection.