A practical description of the software design patterns as they are mentioned in the 1994 book "Design Patterns - Elements of Reusable ObjectOriented Software" by the author group Gamma, Helm, Johnson and Vlissides (also called "Gang of Four", GoF for short). All patterns are explained in detail by means of examples and also critically appreciated. Furthermore, design principles of object-oriented programming are described and considered. All examples are commented in detail in the source code and are executable under Java 16. In part, newer features of Java up to and including version 16 are also explained and used.
Author(s): Olaf Musch
Edition: 1
Publisher: Springer Vieweg
Year: 2023
Language: English
Pages: 358
City: Wiesbaden
Tags: Programming; Object-Oriented Development; Java; Design Patterns; Gang Of Four; Software Development
A Warm Welcome to You!
Contents
1: The Term “Design Pattern”
1.1 What Are Design Patterns?
1.1.1 Historical and Intellectual Background
1.1.2 Advantages and Disadvantages of Patterns
1.1.2.1 Patterns Transport and Preserve Knowledge
1.1.2.2 Patterns Create a Common Vocabulary
1.1.2.3 Patterns Help to Understand a Programming Language Better
1.1.2.4 Patterns May Lead to Inappropriate Designs
1.1.3 A Pattern Is Not a Code Is Not a Pattern
1.1.4 So What Are “Design Patterns”?
1.1.5 Patterns in Practice
1.2 Categorize and Describe Design Patterns
1.2.1 Different Categories of Patterns
1.2.2 Defining a Sample Template
1.3 Summary
2: Object-Oriented Programming and Design Principles
2.1 Object-Oriented Programming
2.2 Programming Against Interfaces
2.3 Single Responsibility Principle (SRP)
2.4 Inheritance May Be Evil
2.5 Open/Closed Principle (OCP)
2.6 Principle of the Right Sense of Proportion
3: Singleton
3.1 The Task of the Singleton Pattern
3.2 A First Version of the Singleton
3.3 Synchronize Access
3.4 Double Checked Locking
3.5 Early Instantiation – Early Loading
3.6 Singleton – The UML Diagram
3.7 Antipattern
3.7.1 Criticism of the Singleton
3.7.2 Is Singleton an Antipattern?
3.8 Summary
3.9 Description of Purpose
4: Template Method
4.1 How Template Method Works
4.1.1 A First Approach
4.1.2 The Second Approach
4.1.3 The Hollywood Principle
4.1.4 Introducing Hook Methods
4.2 The “ListModel” Interface
4.3 Template Method – The UML Diagram
4.4 Summary
4.5 Description of Purpose
5: Observer
5.1 Introduction
5.2 A First Realization
5.3 Extending the Approach
5.4 Observer in the Java Class Library
5.5 Concurrent Access
5.5.1 Synchronize Accesses
5.5.2 Copying the Database
5.5.3 Use of a Thread-Safe List
5.6 Observer as Listener
5.7 Listener in GUI Programming
5.8 The Model-View-Controller Pattern
5.9 Observer – The UML Diagram
5.10 Summary
5.11 Description of Purpose
6: Chain of Responsibility
6.1 A Real World Example
6.2 First Code Example: Grocery Shopping
6.2.1 The Foodstuffs Required
6.2.2 The Sellers
6.2.3 The Client
6.2.3.1 Extension of the Project
6.2.3.2 Variations of the Pattern
Designing Hierarchies and Selecting any Entry Point
Links in the Chain Modify the Request
6.3 An Example from the Class Library
6.4 Chain of Responsibility – The UML Diagram
6.5 Summary
6.6 Description of Purpose
7: Mediator
7.1 Distinction from the Observer Pattern
7.2 Task of the Mediator Pattern
7.3 Mediator in Action – An Example
7.3.1 Definition of a Consumer
7.3.2 Definition of a Producer
7.3.3 Mediator Interface
7.3.4 Testing the Mediator Pattern
7.4 Mediator in Action – The Second Example
7.4.1 Mediator in GUI Programming
7.4.2 Structure of the GUI
7.5 Mediator – The UML Diagram
7.6 Criticism of Mediator
7.7 Summary
7.8 Description of Purpose
8: State
8.1 Excursus: The Enum Pattern
8.1.1 Representing a State by Numerical Values
8.1.2 Representing a State by Objects
8.1.3 Implementation in the Java Class Library
8.2 Changing the State of an Object
8.2.1 A First Approach
8.2.2 A Second Approach
8.3 The Principle of the State Pattern
8.3.1 Defining the Role of All States
8.3.2 The Project from the Client’s Point of View
8.3.3 Changes to the Project
8.3.3.1 Manage State Objects Centrally in Context
8.3.3.2 State Objects as Return Values of Method Calls
8.4 The State Pattern in Practice
8.5 State – The UML Diagram
8.6 Summary
8.7 Description of Purpose
9: Command
9.1 Encapsulating Commands in Classes
9.1.1 Version 1 – Basic Version
9.1.2 Other Suppliers Appearing
9.1.3 Encapsulating a Command
9.2 Command in the Class Library
9.2.1 Example 1: Concurrency
9.2.2 Example 2: Event Handling
9.3 Reusing Command Objects
9.3.1 The “Action” Interface
9.3.2 Use of the “Action” Interface
9.4 Undo and Redo of Commands
9.4.1 A Simple Example
9.4.2 A More Extensive Example
9.4.3 Discussion of the Source Code
9.4.3.1 The Classes Involved
9.4.3.2 Task of the GUI
9.4.3.3 Operation of the Command Classes
9.4.3.4 Undo and Redo
9.4.4 Undo and Redo Considered in Principle
9.5 Command – The UML Diagram
9.6 Summary
9.7 Description of Purpose
10: Strategy
10.1 A First Approach
10.2 Strategy in Action – Sorting Algorithms
10.2.1 The Common Interface
10.2.2 The Selection Sort
10.2.3 The Merge Sort
10.2.4 The Quick Sort
10.2.5 The Context
10.2.6 Evaluation of the Approach and Possible Variations
10.3 The Strategy Pattern in Practice
10.4 Strategy – The UML Diagram
10.5 Distinction from Other Designs
10.6 Summary
10.7 Description of Purpose
11: Iterator
11.1 Two Ways to Store Data
11.1.1 Storing Data in an Array
11.1.2 Storing Data in a Chain
11.2 The Task of an Iterator
11.3 The Interface Iterator in Java
11.3.1 The Iterator of the Class MyArray
11.3.1.1 Test of the Iterator
11.3.1.2 Benefits and Variations of the Iterator
11.3.2 The Iterator of the Class MyList
11.3.2.1 Test of the Iterator
11.3.2.2 Benefits of the Iterator
11.4 The Iterable Interface
11.5 Iterator – The UML Diagram
11.6 Summary
11.7 Description of Purpose
12: Composite
12.1 Principle of Composite
12.2 Implementation 1: Security
12.3 Implementation 2: Transparency
12.4 Consideration of the Two Approaches
12.5 Going One Step Further
12.5.1 Creating a Cache
12.5.2 Referencing the Parent Components
12.5.3 Moving Nodes
12.6 Composite – The UML Diagram
12.7 Summary
12.8 Description of Purpose
13: Flyweight
13.1 Task of the Pattern
13.2 The Realization
13.3 A More Complex Project
13.3.1 The First Approach
13.3.2 Intrinsic and Extrinsic State
13.4 Flyweight in Practice
13.5 Flyweight – The UML Diagram
13.6 Summary
13.7 Description of Purpose
14: Interpreter
14.1 The Task in This Chapter
14.2 The Scanner
14.2.1 The Defined Symbols
14.2.2 The Scanner Converts Strings into Symbols
14.3 The Parser
14.3.1 Abstract Syntax Trees
14.3.2 Expressions for the Parser
14.3.3 Parse Stroke Calculation
14.3.4 Parse Point Calculation
14.3.5 Consider Brackets
14.4 Interpreter – The UML Diagram
14.5 Discussion of the Interpreter Pattern
14.6 Summary
14.7 Description of Purpose
15: Abstract Factory (Abstract Factory)
15.1 Create Gardens
15.1.1 The First Attempt
15.1.2 The Second Attempt – Inheritance
15.1.3 The Third Approach – The Abstract Factory
15.1.4 Advantages of the Abstract Factory
15.1.5 Defining a New Garden
15.2 Discussion of the Pattern and Practice
15.3 Chasing Ghosts
15.3.1 The First Version
15.3.1.1 The Player
15.3.1.2 The Four Cardinal Points
15.3.1.3 Building the House
15.3.1.4 The “House” Class for Controlling the Game
15.3.2 The Second Version of the Project
15.3.3 Version 3 – Introduction of Another Factory
15.3.3.1 Spells
15.3.3.2 The New Factory for Doors with Spells
15.3.3.3 The New Component: A Door with a Magic Spell
15.3.4 Version 4 – The Haunted House
15.4 Abstract Factory – The UML Diagram
15.5 Summary
15.6 Description of Purpose
16: Factory Method
16.1 A First Example
16.2 Variations of the Example
16.3 Practical Application of the Pattern
16.3.1 Recourse to the Iterator Pattern
16.3.2 At the Abstract Factory
16.4 A Larger Example – A Framework
16.4.1 And Another Calendar
16.4.2 The Interfaces for Entries and Their Editors
16.4.3 The Class “Contact” as an Example of an Entry
16.4.4 The FactoryMethod Class as a Client
16.5 Difference to Abstract Factory
16.6 Factory Method – The UML Diagram
16.7 Summary
16.8 Description of Purpose
17: Prototype
17.1 Cloning Objects
17.1.1 Criticism of the Implementation
17.1.1.1 The Cloneable Interface
17.1.1.2 The Problem of Equal References
17.1.1.3 What Happens During Cloning
17.1.2 Cloning in Inheritance Hierarchies
17.2 A Major Project
17.2.1 Discussion of the First Version
17.2.2 The Second Version – Deep Copy
17.2.3 Defining Your Own Prototypes
17.3 Prototype – The UML Diagram
17.4 Summary
17.5 Description of Purpose
18: Builder
18.1 An Object Creates Other Objects
18.1.1 Telescoping Constructor Pattern
18.1.2 JavaBeans Pattern
18.1.3 Builder Pattern
18.2 A More Complex Design Process
18.2.1 Converting XML Files into a TreeModel
18.2.2 Displaying XML Files as HTML
18.3 Builder – The UML Diagram
18.4 Summary
18.5 Description of Purpose
19: Visitor
19.1 A Simple Example
19.1.1 The Power Unit
19.1.2 The Visitor
19.1.3 The Client
19.1.4 Another Visitor
19.1.5 Criticism of the Project
19.2 Visitor – The UML Diagram
19.3 Summary
19.4 Description of Purpose
20: Memento
20.1 Task of the Memento Pattern
20.1.1 Public Data Fields
20.1.2 The JavaBeans Pattern
20.1.3 Default Visibility
20.2 A Possible Realization
20.3 A Major Project
20.4 Memento – The UML Diagram
20.5 Summary
20.6 Description of Purpose
21: Facade
21.1 An Example Outside IT
21.2 The Facade in a Java Example
21.2.1 Introduction of a Facade
21.2.2 A Closer Look at the Term “System”
21.3 The Facade in the Class Library
21.4 The “Law of Demeter”
21.5 Facade – The UML Diagram
21.6 Summary
21.7 Description of Purpose
22: Adapter
22.1 An Introductory Example
22.2 A Class-Based Design
22.3 An Object-Based Design
22.4 Criticism of the Adapter Pattern
22.5 A Labeling Fraud
22.6 Adapter – The UML Diagram
22.7 Summary
22.8 Description of Purpose
23: Proxy
23.1 Virtual Proxy
23.2 Security Proxy
23.3 Smart Reference
23.3.1 The Basic Version
23.3.2 Introduction of a Proxy
23.3.3 Introducing a Second Proxy
23.3.4 Dynamic Proxy
23.3.4.1 The Reflection API
23.3.4.2 The InvocationHandler
23.3.4.3 The Proxy Class
23.4 Remote Proxy
23.4.1 Structure of RMI in Principle
23.4.2 The RMI Server
23.4.2.1 The PiIF Interface
23.4.2.2 The PiImpl Server Class
23.4.2.3 The Class ServerStart Starts the Server
23.4.3 The RMI Client
23.4.4 Making the Project Work
23.5 Proxy – The UML Diagram
23.6 Summary
23.7 Description of Purpose
24: Decorator
24.1 Build Cars
24.1.1 One Attribute for Each Optional Extra
24.1.2 Extending with Inheritance
24.1.3 Decorating According to the Matryoshka Principle
24.1.3.1 Defining the Basic Models
24.1.3.2 Defining the Optional Extras
24.1.3.3 The Client Plugs the Components Together
24.2 Practical Examples
24.2.1 The “JScrollPane” Class
24.2.2 Streams in Java
24.2.2.1 Streams as Decorator
24.2.3 Streams as Non-Decorator
24.3 Decorator – The UML Diagram
24.4 Summary
24.5 Description of Purpose
25: Bridge
25.1 Two Definitions
25.1.1 What Is an Abstraction?
25.1.2 What Is an Implementation?
25.1.3 A Problem Begins to Mature
25.2 The Bridge Pattern in Use
25.2.1 First Step
25.2.2 Second Step
25.2.2.1 Extending the Abstraction
25.2.3 Extending the Implementation
25.3 Discussion of the Bridge Pattern
25.3.1 Bridge in the Wild
25.3.2 Distinction from Other Patterns
25.4 Bridge – The UML Diagram
25.5 Summary
25.6 Description of Purpose
26: Combine Patterns
26.1 The Example
26.2 Singleton: Logging
26.3 Abstract Factory: Building the Sensors
26.4 Observer: The Trigger
26.5 Adapter: Send Notifications
26.6 Command: Actuators and Remote Control
26.7 A Sensor Triggers
26.8 Class Diagram
26.9 The Client
26.10 Considerations
26.11 Summary
Concluding Remarks