Download presentation
Presentation is loading. Please wait.
1
Unit 1 General Introduction
Summary prepared by Kirk Scott
2
This general introduction covers two chapters in the book:
Chapter 1: Introduction Chapter 26: Introducing Extensions
3
Design Patterns in Java Chapter 1 Introduction
Summary prepared by Kirk Scott
4
Intended Audience, Coverage, etc.
The classic book, Design Patterns, was written by Gamma, Helm, Johnson, and Vlissides This book covers the same set of 23 patterns The book is intended for software programmers/developers who know Java and want to improve their skills as designers
5
What is a Pattern? A pattern is a way of doing something
It can be thought of as a technique for accomplishing some goal This book dwells on the intent of patterns as an organizing characteristic The chapters have been reorganized for the purposes of this course to emphasize common structure rather than common intent
6
Where do Patterns Come From?
Software development is repetitive: Quite often, different programmers have to solve the same problem Experienced programmers have compared notes and discovered that they arrived at common solutions to the same problem Over time, these common solutions, have been documented as the best known approach to solving a given problem
7
Why Design Patterns? Observe that in school, you learn to program first and learn about design later When you compare your solution to a problem with someone else’s solution, you may realize that the other solution is simpler, more efficient, or more desirable in some other way In practice, it is helpful to have knowledge of design before trying to code a solution to a problem
8
Why Design Patterns? Cont’d.
Design patterns are one step up from straight code writing They represent recognized software solutions in terms of (small) collections of classes related in a certain way and containing certain sets of methods It is important to keep in mind that the implementation is not the pattern—a pattern is the abstract design which embodies the intent
9
Why Design Patterns? Cont’d.
Design patterns have been developed most extensively in the object-oriented realm The authors point out that there are currently over 100 documented design patterns The 23 covered in the book have been chosen for historic reasons They are certainly worth knowing, whether they are absolutely the most important
10
Why Design Patterns? Cont’d.
In particular, whether the most important or not, the 23 chosen patterns provide a broad introduction to and illustration of what patterns are and what they’re good for The authors assert that if a person wants to become a good Java programmer, it is necessary to study design patterns Design patterns are the first step out of the swamp of syntax that an introduction to programming is
11
Why Java? Java is a consolidation language
This means that it is a kitchen sink language in the footsteps of C and C++, and for this reason, if no other, it is popular Object-oriented programming is based on classes and instances, and this paradigm is currently the most popular approach to implementing graphical user interfaces, for example Java’s characteristics make it likely that future popular languages will follow in Java’s footsteps
12
UML Implementations of patterns are done in code
However, the pattern itself consists of the relationships among classes and so on UML is one of several notations for diagramming notations, but it is certainly a popular one The point is that some abstract representation of patterns is desirable, rather than appealing always to the code of a particular implementation
13
Challenges The book contains questions
These may be short answer questions They may also be programming questions based on the book’s example code This course will not give these challenges as assignments Instead, the challenges and the authors’ solutions will be examined to see what can be gained from them
14
The Organization of the Book
The patterns in a book of this kind could be given in the same order as the original design patterns book They could also be grouped together according to similarity in structure This book organizes the patterns according to the intent which the authors ascribe to them
15
The Organization of This Book, cont’d.
This raises the question of how to classify intent The authors suggest that categories of patterns can be recognized according to how the patterns make it possible to go beyond the basic characteristics built into the structure of Java They use as an initial example the idea of interfaces
16
The Organization of This Book, cont’d.
Suppose you have a class/method which requires an object of a class which implements a given interface Suppose that you would like to apply the above to an object of a class which does not implement the required interface Short of rewriting the given class, what approach could be taken?
17
The Organization of This Book, cont’d.
The answer is that there is a pattern known as the Adapter pattern (not to be confused with adapter classes in Java) which accomplishes this goal The Adapter pattern, and others with similar intents, are classified in an intent category known as Interfaces To recapitulate, these patterns help the programmer accomplish things using interfaces, going beyond the syntax provided in Java
18
The Organization of This Book, cont’d.
The book classifies patterns into these five categories: Interfaces Responsibility Construction Operations Extensions
19
The Organization of This Book, cont’d.
The book, as a consequence is organized in the same way The authors admit that various patterns may fit more than one category In such cases, the pattern is given in detail in the first category where it fits, and is mentioned briefly in subsequent sections The classification of patterns is not an absolute, but some classification is useful and necessary, and is a starting point for suggesting alternative classifications
20
The Organization of This Book, cont’d.
What follows is a complete preview of the contents of the book Intent Category: Interfaces. Patterns: Adapter, Façade, Composite, Bridge Intent Category: Responsibility. Patterns: Singleton, Observer, Mediator, Proxy, Chain of Responsibility, Flyweight
21
The Organization of This Book, cont’d.
Intent Category: Construction. Patterns: Builder, Factory Method, Abstract Factory, Prototype, Memento Intent Category: Operations. Patterns: Template Method, State, Strategy, Command, Interpreter Intent Category: Extensions. Patterns: Decorator, Iterator, Visitor
22
The Organization of the Course
Structural Category: Construction and Cloning. Patterns: Singleton, Prototype, Builder, Proxy Structural Category: Generic Interfaces and Encapsulation. Patterns: Mediator, Façade, Adapter, Flyweight, Decorator, Command, State
23
Structural Category: Java Interfaces.
Patterns: Template, Iterator, Strategy Structural Category: Dynamic Binding and Polymorphism. Patterns: Factory Method, Abstract Factory, Bridge Structural Category: Threads. Patterns: Strictly speaking, this is not a pattern
24
Structural Category: Composite and Related Patterns.
Patterns: Composite, Chain of Responsibility, Interpreter, Visitor Structural Category: Model-View-Controller Related Patterns. Patterns: Observer, Memento
25
Welcome to Oozinoz! The book’s examples are based on an integrated code base which is collectively known as Oozinoz (oohs and ahs), which deals with software needed for the production of fireworks The authors’ examples will be studied, but as noted already, the challenges will not be given as assignments
26
Summary This is the book’s summary of the chapter, verbatim:
Patterns are distillations of accumulated wisdom that provides a standard jargon, naming the concepts that experienced practitioners apply. The patterns in the classic book Design Patterns are among the most useful class-level patterns and are certainly worth learning.
27
Summary, cont’d. This book explains the same patterns as those documented in Design Patterns but uses Java and its libraries for its examples and challenges. By working through the challenges in this book, you will learn to recognize and apply an important part of the wisdom of the software community.
28
Summary prepared by Kirk Scott
Design Patterns in Java Part V Extension Patterns Chapter 26 Introducing Extensions Summary prepared by Kirk Scott
29
The Introduction Before the Introduction
The stated purpose of the chapter is to introduce what the book calls extensions patterns Since the material is being given in structural order rather than order by intention, this purpose isn’t so important It’s not clear whether this purpose is effectively served anyway…
30
In part, the book also uses the chapter to do a little review of specific patterns that have been introduced so far That isn’t of too much value What is interesting, though, is the introduction of some more object-oriented design principles
31
Object-Oriented Constructs and Principles
The concept of encapsulation arises early in object-oriented programming and design, and it will recur throughout the book In addition, interfaces, polymorphism, and dynamic binding are fundamental ideas which will be reiterated
32
Responsibility The book will also introduce the idea of responsibility
In simple terms, classes/objects should be self-contained They should have all of the instance variables and methods needed in order to manipulate them fully and accomplish desired goals with them
33
This is the norm, known as distributed responsibility
Responsibility can also be usefully concentrated in some cases Various design patterns will illustrate both distributed and concentrated responsibility
34
Coupling There is a related concept, known as coupling
Ideally, objects are independent of each other This generally desirable condition is known as loose coupling Loose coupling might be thought of as meaning fewer connections This would mean fewer places where you had to worry about a change in one object propagating to another
35
On the other hand, sometimes a change in one object will trigger a change in another
As usual, there are also cases where tighter coupling is desirable Various design patterns will illustrate both loose and tight coupling
36
The Liskov Substitution Principle and the Law of Demeter
This chapter adds two major items to the list of object-oriented design principles: The Liskov Substitution Principle The Law of Demeter
37
These principles are interesting in their own right
They draw together some important insights that apply to OO design in general As the design patterns are introduced, at various points it may become apparent that the patterns, in general, are bounded by these principles There may also be places where a given pattern can be seen to push the boundaries of one of the principles in order to achieve a particular goal.
38
Introducing Extensions
Book material: In general, extension is based on this idea: You rarely write code in a vacuum You have an existing code base and your task is to add new features, classes, applications to it In this sense, the term extension basically just means programming within the context of given code
39
The book’s motivation for introducing general object-oriented design principles at this point is the following: As a programmer, extending a code base, it would be helpful to have some rules of thumb to decide whether or not the code you are adding is any good
40
Extension may also refer to specific techniques for adding features to a code base
In addition to looking at general principles, the book does two other things in this chapter: It looks back at some earlier patterns that have an element of extension to them It previews some of the extension design patterns that will be covered in the rest of the section
41
Principles of Object-Oriented Design
For people interested in the topic of patterns, the book cites this Web site: There is no need to go there for the purposes of this course From that page there is a link to a Wiki with a collection of patterns that goes beyond the ones covered in the book
42
The Liskov Subsitution Principle (LSP)
One of the aspects of object-orientation that should be familiar to you is the following: A subclass is in an “is-a-kind-of” relationship with its superclass In general, a subclass is a more specific kind of the superclass At the very least, it has the same set of instance variables, since instance variables can’t (or shouldn’t) be overridden
43
The subclass is made more specific by having more instance variables
It is also made more specific by adding or overriding methods, if necessary In Java, it’s always syntactically possible to have a superclass reference to a subclass object
44
The superclass reference won’t have access to the instance variables and unique methods of the subclass However, the superclass reference will have access to any methods inherited by the subclass It will also have access to any methods overridden in the subclass
45
The ability to have superclass references is important when defining method parameters in an inheritance hierarchy A method defined in a superclass with a superclass explicit parameter doesn’t have to be overridden in the subclass, with the explicit parameter re-typed to the subclass, in order to be used with a subclass explicit parameter
46
The book states that subclasses should be logical, consistent extensions of their superclasses
Trying to define the meaning of logical and consistent leads to the Liskov Substitution Principle The book paraphrases the principle as follows: “An instance of a class should function as an instance of its superclass.”
47
As noted, Java expects this and supports it syntactically
The real question is whether or not the internal logic of classes for a given problem domain agree with this The book gives two problematic examples which are shown on the next overhead
49
The Machine/UnloadBuffer example illustrates questions that arise in the problem domain
Superficially, you might want to class UnLoadBuffers with Machines Without knowing how machines and buffers are designed, it’s not clear whether this a correct design
50
However, the book gives the following additional information:
According to the way their fireworks factory is set up, you can’t add tubs to an UnloadBuffer This implies that you also could not get tubs associated with an UnloadBuffer However, the Machine class has an addTub() and a getTubs() method
51
If all machines except for UnloadBuffer have this characteristic, you have a design problem
Do you force the implementation of addTub() and getTubs() into each subclass of machine except for UnloadBuffer, when all of that code will be duplicate? Do you implement the UnloadBuffer class outside of the Machine hierarchy? Do you leave the UnloadBuffer in the hierarchy and leave the methods in Machine, but somehow ignore the methods for UnloadBuffer?
52
The UML diagram shows the last choice, with addTub() and getTubs() overridden in UnloadBuffer
What should you do if it is not really possible to call these methods on an UnloadBuffer, throw an exception? This puts the burden on client code to catch exceptions for a faulty design
53
An alternative would be to have the overridden versions of the method do nothing at all
This is even worse What happens to a tub after a call has been made to add it to an UnloadBuffer? Does it go into outer space?
54
The point is that this is a bad design, and the problem with the design can be identified as a violation of the Liskov Substitution Principle The problem is that it is not possible to use an instance of an UnloadBuffer anywhere that you use an instance of a machine The UnloadBuffer class doesn’t seem to be a proper subclass of the Machine class
55
The book continues by observing that it may sometimes be useful to violate the principle
This seems to be eternally true in software development The additional requirement when you do this is to clearly identify the violation Justify it And identify and deal with all possible consequences
56
In the chapter on bridges/drivers, a somewhat analogous situation will arise
The choice will have to do with how many methods you put into an interface Do you put a subset of methods in, so that all implementing classes could implement them? Or do you put a superset of methods in, forcing some of the implementing classes to have bogus implementations?
57
The second option is more flexible, in the sense that all possible methods are supported in all cases where they are valid The shortcoming is that they also exist in cases where they aren’t valid As long as the invalid cases don’t cause any harm—or it is possible to detect and deal with invalid cases in client code, then the advantages might outweigh the disadvantages
58
Challenge 26.1 A circle is certainly a special case of an ellipse, or is it? Say whether the relationship of the Ellipse and Circle classes in Figure 26.1 is a violation of LSP.
59
Solution 26.1 In mathematics, a circle is certainly a special case of an ellipse. However in OO programming, an ellipse has certain behaviors that a circle does not. For example, an ellipse may be twice as wide as it is tall; a circle can’t do that. If that behavior is important to your program, a Circle object won’t function as an Ellipse object and will represent a violation of LSP.
60
Note that if you’re considering immutable objects, this may not be apply.
This is simply an area in which naïve mathematics is not a smooth fit for the semantics of standard type hierarchies.
61
The Law of Demeter (LoD)
From Wikipedia, the free encyclopedia
62
In Greek mythology Demeter (pronounced /dəˈmiːtər/; də-MEE-tər; Greek: Δημήτηρ, Dēmētēr, probably "earth-mother")[1][2] was the goddess of the harvest, who presided over grains, the fertility of the earth, the seasons (personified by the Hours), and the harvest. Though Demeter is often described simply as the goddess of the harvest, she presided also over the sanctity of marriage, the sacred law, and the cycle of life and death. She and her daughter Persephone were the central figures of the Eleusinian Mysteries that also predated the Olympian pantheon. Her Roman cognate is Ceres.
64
The book quotes a paper by Lieberherr and Holland on the Law of Demeter:
“Informally, the law [of Demeter] says that each method can send messages to only a limited set of objects: to argument objects, to the [this] pseudovariable, and to the immediate subparts of [this].”
65
Stated more explicitly, the law goes like this:
When writing method code, you may be working with the implicit parameter You can call methods directly on the implicit parameter Because the code you’re writing is in the class of the implicit parameter, you have direct access to the instance variables of the implicit parameter You can also call methods on the instance variables of the implicit parameter
66
When writing method code, you may also be working with an explicit parameter
You can also call methods directly on the explicit parameter If the explicit parameter is not of the same type as the class that the method occurs in, then you don’t have direct access to its instance variables In that case, you can’t call methods on the instance variables of the explicit parameter
67
In summary, you’re allowed to call methods on objects that you have a direct reference to
You shouldn’t be calling methods second-hand In other words, if you have to call a get method to get a reference to an instance variable of something, you shouldn’t then be calling a method on that object
68
Illustrating a Violation of the Law of Demeter
The book points out that this can be easier to understand if you consider cases that would violate the Law of Demeter They set up this scenario There is a MaterialManager object with a method X that takes a Tub object (named tub in the book) as an explicit parameter Tub objects have a location instance variable
69
A location is a machine, for example
A machine has an instance variable that tells whether the machine is up or down In the code for method X, you might write code like this: if(tub.getLocation().isUp()) { … }
70
According to the Law of Demeter, it’s OK to call tub.getLocation()
That’s just one level deep into the explicit parameter That call returns a reference to the location instance variable of the tub The Law of Demeter says that calling a method on that reference is not OK In other words, the code as written violates the law
71
Challenge 26.2 Explain why the expression tub.getLocation().isUp() might be viewed as unhealthy.
72
Solution 26.2 The expression tub.getLocation().isUp() might lead to programming errors if there are any subtleties around the value of a tub object’s Location property. For example, the location might be null or might be a Robot object if the tub is in transit. If location is null, evaluating tub.getLocation().isUp() will throw an exception.
73
If the location is a Robot object, the problem may be even worse, as we try to use a robot to collect a tub from itself. These potential problems are manageable, but do we want the ensuing code to be in the method that uses the tub.getLocation().isUp() expression?
74
No. The necessary code may already be in the Tub class! If not, it belongs there, to prevent us from having to recode around the same subtleties in other methods that interact with tubs.
75
Comment mode on: A simple-minded but possibly effective way of think about the Law of Demeter is that it is concerned with encapsulation when dealing with the internals of classes. Recall that a truly correct get() method for an object reference would return a clone(), not the original
76
If you then called a method on the clone, what effect would that have on the original?
The answer is, no effect But of course, the point is that you really want to operate on the original because an effect is desired But to operate on the original of a reference which you obtained with a get() call would violate encapsulation
77
The book’s challenge solution is complete and correct
It might benefit from a summary If method X deals with tubs, then it would be nice if it were protected from having to deal with the internals of tubs The book’s challenge solution suggests a general approach
78
The general idea of “the logic may already be in the Tub class” goes like this—or if it isn’t already there, it might be put there as follows: If method X deals with tubs, and is ultimately concerned with whether or not a tub’s location is up or down, then maybe a new method should be added to the Tub class
79
It could be tentatively named something like, isMyLocationUpOrDown()
Then, formally, at least, method X could be written without violating the Law of Demeter Instead of this: tub.getLocation().isUp() You could write this: tub.isMyLocationUpOrDown()
80
The code for method X is protected from having to know what the interface or internals of the Location class are It only has to know the interface for the Tub class, which is the class that it works with directly
81
The book goes on to say that the Law of Demeter is more subtle than this:
“Expressions of the form a.b.c are bad.” This is clear It would certainly be possible to write expressions of the form a.b.c which didn’t violate the Law of Demeter.
82
The law is based on an understanding of things like coupling and responsibility, where you are actively trying to avoid foreseeable problems that would result if you didn’t follow the law As always, there may be cases where you know you are violating the law, but some other consideration causes you to do so In other words, there may be cases where a.b.c does violate the law, but you choose to use such an expression anyway
83
Removing Code Smells The title of this subsection is unfortunate
To the same degree, the content is also unfortunate The book mentions that some authors have identified certain signs of poorly written code They mention one source in particular, “Refactoring: Improving the Design of Existing Code” by Fowler et al. This reference contains 22 signs that code can be improved by refactoring
84
As for referring to the signs as smells, could you get any more childish?
The only outcome of that approach that I can foresee is a dialog along these lines: “Your code smells.” “No, your code smells.” It’s a completely unproductive way of looking at things
85
If you have to resort to the term “smells” in order to describe what’s wrong, it’s a sign that your analytical or expressive abilities are lacking The book has a challenge in this subsection I refuse to dignify it by including it in the overheads It’s useless anyway There’s no way to answer it unless you’re already familiar with one of the 22 signs (smells)…
86
In general, these overheads follow the contents of the book chapters that they cover.
At this point, the chapter refers specifically to the extension patterns, presented as a group with related intentions. Since the material is being covered in a different order, these details aren’t important. The relevant overheads are saved for future reference after “The End”, but they will not be covered.
87
Summary The authors describe code writing as a process of extension followed by refactoring Fair enough I always describe it as copying existing code, adapting it, and then debugging—repeat as necessary… The authors also state that there is no complete, objective technique for assessing code quality
88
The Liskov Substitution Principle provides one guideline for writing good code
It should always be possible to substitute a subclass object for a superclass object You need to be able to identify and justify and violations of this that might exist in code you write
89
The Law of Demeter is another guideline for writing good code
You shouldn’t be calling methods on references to instance variables you obtained by calling get() methods The authors summarize this by saying that applying the Law of Demeter reduces dependencies between classes This goes back to distributed responsibility and loose coupling as the default ideals for OO code design You need to be able to identify and justify and violations of this that might exist in code you write
90
Other authors have identified problems that occur in code design
They have also identified preferable refactorings Some of the refactorings are similar to recognizable design patterns Lots of design patterns can be understood as tools for extending existing pieces of code or coordinating the tasks of different programmers in developing a complete system
91
The End
92
Beyond Ordinary Extensions
This is the subsection where the authors want to review patterns that have already been given and relate them to the idea of extensions They go all the way back to the great-granddaddy of patterns, our friend, Adapter
93
One developer may provide a service and an interface for using it
Other developers may write the application code that makes use of the service The extension point of view may be applied in lots of situations where code writing responsibility is divided among different developers
94
The authors review patterns already given that exhibit extension characteristics by means of the challenge contained in the table on the following overhead
96
Solution 26.4 One set of solutions is: [See the following overhead.]
98
The book now introduces the extension design patterns that will be covered in the remaining chapters by means of the table on the following overhead
Similar presentations
© 2025 SlidePlayer.com. Inc.
All rights reserved.