The Goal of Object-Oriented (OO) Design Patterns • Our goal is to design good OO software systems. Here, “good” means reusable and flexible. • We want source files that require no modification when used in future systems. • Contrary to initial expectations (ca., 1990), OO design is difficult. Creating reusable designs is even more difficult. • Inexperienced designers tend to overuse inheritance. Rearranging the inheritance hierarchy of an existing system is very traumatic. There is an alternative. • Each pattern is the result of many iterations, by experts, which eventually resulted in reusable designs. By understanding them, our “first” designs can be reusable. OODP.1
The Risks of Patterns • If you don’t need reusable and flexible designs, don’t use these patterns. They add complexity. • Don’t apply them without careful analysis. • They can complicate a system and reduce performance. • Use them only when the added reusability and flexibility is worth the cost. OODP.2
The Form and Structure of a Pattern • Each pattern has several parts: – Name (and aliases) – Motivation (with examples) – Applicability: how the pattern addresses the problem – Structure: UML diagram – Participants: interfaces, classes, and methods – Collaborations (between participants) – Consequences: pros and cons of using the pattern – Implementation Choices – Sample Code – Known Uses – Related Patterns: similar and dependent patterns OODP.3
Patterns in The BSU CS Curriculum • We offer a senior-level elective, CS 472 (Object-Oriented Design Patterns): Reviews object-oriented design principles, explains the goals and form of design patterns, and examines several well-known patterns. • However, other courses use rudimentary patterns: – CS 121: Java’s Swing API – CS 221: Iterator(257), Adapter(139), and Bridge(151) – CS 354: Interpreter(243) OODP.4
The History of Patterns (1 of 2) • OO design patterns were modeled after Christopher Alexander’s brick-and-mortar construction patterns, 1977: pub/ch1/ca-cover.pdf pub/ch1/ca-face.pdf Each pattern describes a problem that occurs over and over again in our environment, and then describes the core of the solution to that problem, in such a way that you can use this solution a million times over, without ever doing it the same way twice. OODP.5
The History of Patterns (2 of 2) • James Coplien’s Advanced C++ Programming Styles and Idioms , 1992. • Erich Gamma’s Ph.D. dissertation (in German), 1992. He also worked on JUnit and Eclipse. • Erich Gamma, Richard Helm, Ralph Johnson, and John Vlissides wrote the Gang of Four (GoF) book, in 1995: pub/ch1/gof.pdf “... the most popular computer book ever published, with over one million copies in print.” It contains 23 patterns, in 3 categories: – Creational patterns determine how objects are created. – Structural patterns determine how objects look. – Behavioral patterns determine how objects act. OODP.6
How Design Patterns Solve Design Problems (1 of 2) • Patterns help us decompose a system into objects: – An object encapsulates data, and methods that operate on the data. – An object’s data should be private. Only an object’s methods can change it. – OO design methodologies typically produce designs where objects correspond to nouns in the problem statement or real-world entities. But, good designs often end up with objects that have no real-world counterpart (e.g., Adapter). Patterns help us include these objects in our designs, increasing flexibility and reusability. OODP.7
How Design Patterns Solve Design Problems (2 of 2) • They help us determine object granularity: – An object can be tiny or huge. We may need one object of a class, or thousands. – Some patterns describe objects that create objects, compose objects, or implement requests between objects. • They help us specify object interfaces: – A method’s name, argument types, return type, and exceptions compose its signature . – The set of public-method signatures defined by an object is its interface . – A type is a name denoting an interface. OODP.8
The GoF Principles of Object-Oriented Design 1. Program to an interface, not an implementation. This reduces coupling and allows an implementation to be replaced. 2. Favor object composition over class inheritance. Using has-a , rather than is-a , preserves encapsulation and allows classes and class hierarchies to remain small. It leads to more reusable designs, where reuse can occur dynamically, at run time. OODP.9
Delegation • With inheritance, a subclass can defer requests to a superclass, by not overriding a superclass method. • Delegation is the object-composition way of doing this. • A Delegator object can delegate a request to a Delegate object. • Thus, object composition can always replace inheritance for code reuse. • This is very common: pub/ch1/LightSwitch.java Here, an object of class LightSwitch delegates part of the init request to an object of class ToggleButton. OODP.10
The Iterator Pattern(257) (1 of 4) • Aliases: It is also known as Cursor or Enumerator. • Motivation/Applicability: – You want to access an aggregate’s content without exposing representation. – You want concurrent traversals. – You want polymorphic iteration. • Structure: pub/patterns/Iterator.pdf OODP.11
The Iterator Pattern(257) (2 of 4) • Participants: – Iterator: This is the interface for access and traversal. – ConcreteIterator: This implements Iterator for a particular aggregate. It records the current position in an aggregate. – Aggregate: This is the interface for creating an Iterator object. – ConcreteAggregate: This implements the interface for creating an Iterator object. OODP.12
The Iterator Pattern(257) (3 of 4) • Consequences: – It supports different traversals of a single data structure. – It simplifies the Aggregate interface. – It supports concurrent traversal, because each ConcreteIterator maintains state. OODP.13
The Iterator Pattern(257) (4 of 4) • Implementation: – There are external and internal iterators: ∗ With an external iterator, the client performs an action on each element. ∗ With an internal iterator, the client tells the iterator what to do with each element. ∗ External iterators are more flexible, but internal iterators are more convenient. – Robust iterators allow elements to be added or removed during traversal. – Of course, you can provide additional methods (e.g., prev ) or fewer methods (e.g., merge next and isDone ). OODP.14
The Iterator Pattern(257) • This is a simple Java program, demonstrating the pattern: pub/ch2/Iterator.java pub/ch2/BoxIterator.java pub/ch2/Aggregate.java pub/ch2/Box.java OODP.15
Recommend
More recommend