UML软件工程组织

A Few More Patterns

Outline


Introduction

  • Christopher Alexander - Architect (Father of Pattern Movement)
  • Christopher Alexander says:

    "Each pattern describes a problem which 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"

  • Alexander’s books (late 1970’s)
  • OOPSLA 1987
  • Gang of Four (GOF) book 1995
  • The Quality Without A Name

    … the feeling you get when you know that a design is good and right and elegant. It is a feeling that transcends description …

Types of Patterns

    • Design (You Are Here)
    • Analysis
    • Organizational

Granularity of Patterns

Idioms (low level)

      • for(;;)
      • Linked list, tree
      • Composition, delegation (maybe)
      • Polymorphism, inheritance (maybe)
      • Coplein’s Handle/Body Idiom (precursor)

Design Patterns (medium level)

      • Here Be Patterns (In the middle)

Framework (high level)

      • Model View Controller (MVC)(big pattern)(cannonical "Input/Process/Output" trichotomy?)
      • OWL
      • MFC

Types of Design Patterns

Structural

  • Bridge
  • Composite

Creational

  • Singleton
  • Builder
  • Factory
  • Abstract Factory
  • Prototype

Behavioral

  • Visitor


Pattern Map

23 patterns (GOF)

(Most diagrams are from the GOF CD)

LSP - Liskov Substitution Principle (Barbara Liskov)

  • IS-A relationaship
  • proper inheritance (require no more, promise no less; keep the contract)
  • AKA total polymorphsm
  • in c++, use public inheritance
  • any subclass (derived) class may be used in any correct program.
  • you can always pass a reference to a derived object to a function that expects a reference to a base (or super) class.

DIP - Dependency Inversion Principle (Robert Martin)

  • Adds a level of indirection
  • Reverses dependencies
  • Almost all patterns add one or more levels of indirection
  • DIP diagram (before)
    • Client---->Server
    • Client depends on Server
  • DIP diagram (after)
    • Client----->SeverInterface<------ServerImplementation
    • Client depends on ServerInterface
    • ServerImplementation depends on ServerInterface
    • Changes in the ServerImplementation do not affect the Client


Structural Patterns

Bridge (AKA Handle/Body - Coplien)

Bridge

  • Intent
    • Decouple an abstraction from its implementation so that the two can vary independently.
  • Motivation
    • If an astraction can have one of several possible implementations then usually we use inheritance.
    • An abstract class defines the interface to the abstraction and concrete subclasses implement it in different ways.
    • Inflexible - inheritance binds an implementation to the abstraction permanently, which makes it difficult to modify, extend, and reuse abstractions and implementations independently.
  • Consequences
    • Vary implementation at run-time (Plug and Pray)
    • Hides implementation
  • Relation to Adapter
    • The Adapter pattern makes things work after they're designed;
    • Bridge makes them work before they are designed.

Bridge Class Diagram

Bridge.java

Open/Closed Principle (Bertrand Meyer)

  • open for extension
  • closed for modification

Composite

Compose objects into recursive tree structures to represent part-whole hierarchies. Composite lets clients treat individual objects and compositions of objects uniformly.

Problem

  • you want to represent part-whole hierarchies of objects.
  • you want clients to be able to ignore the difference between compositions of objects and individual objects.

Solution

  • The key to the Composite pattern is an abstract class that represents both primitives and their containers.

Consequences

  • Makes the client simple. Clients can treat composite structures and individual objects uniformly.
  • Makes it easier to add new kinds of components.
  • May make your design overly general (harder to restrict the components) .
  • Keeps type information at the expense of safety.

Composite Class Diagram

Equipment.java

Equipment Diagram


Creational Patterns

Creational Patterns

  • Abstract the instantiation process.
    • A class creational pattern uses inheritance to vary the class that's instantiated
    • An object creational pattern will delegate instantiation to another object.
  • Recurring Themes
    • Encapsulate knowledge about which concrete classes the system uses.
    • Hide how instances of these classes are created and put together.
  • Consequences
    • Flexibility in
      • who creates it
      • what gets created
      • how it gets created
      • when it gets created.

Singleton

  • Simplest
  • Restrict the number of instances.

Singleton Class Diagram

Singleton.java

Direction.java

Enumerated Types in Java

Good News: You can do anything you want
Bad News: You have to do everything you want

Enumerated Types - Type.java

Meanwhile back in the Dungeon

Maze Diagram

Maze.java (without patterns)

Maze Diagram

Analysis

The create() function is pretty complicated, considering that all it does is create a maze with two rooms.
Inflexibility. It hard-codes the maze layout.


The creational patterns show how to make this design more flexible, not necessarily smaller.
Suppose you wanted to reuse an existing maze layout for a new game containing enchanted mazes.
How can you change CreateMaze easily so that it creates mazes with these new classes of objects?

Use Creational Patterns


Creational patterns provide different ways to remove explicit references to concrete classes from code that needs to instantiate them:


If CreateMaze calls virtual functions instead of constructor calls to create the rooms, walls, and doors it requires, then you can change the classes that get instantiated by making a subclass of MazeGame and redefining those virtual functions. This approach is an example of the Factory Method pattern.


If CreateMaze is passed an object as a parameter to use to create rooms, walls, and doors, then you can change the classes of rooms, walls, and doors by passing a different parameter. This is an example of the Abstract Factory pattern.


If CreateMaze is passed an object that can create a new maze in its entirety using operations for adding rooms, doors, and walls to the maze it builds, then you can use inheritance to change parts of the maze or the way the maze is built. This is an example of the Builder pattern.


If CreateMaze is parameterized by various prototypical room, door, and wall objects, which it then copies and adds to the maze, then you can change the maze's composition by replacing these prototypical objects with different ones. This is an example of the Prototype pattern.

Abstract Factory

Abstract Factory Class Diagram

AbstractFactory.Java

Builder

Builder Class Diagram

Builder.java

Factory

Factory Diagram

Factory.java


Behavioral Patterns

Visitor

Intent

  • Represent an operation to be performed on the elements of an object structure.
  • Visitor lets you define a new operation without changing the classes of the elements on which it operates.

Consequences

  • Most Complex
  • Resolves lost type information
  • Avoids downcast

Double Dispatch

  • Some languages do this
  • Java does not
  • Java has single dispatch
  • Virtual function dispatches on actual run-time type of the object
  • No dispatching on arguments

You call me, I’ll call you back

Vistor Class Diagram

Two class hierarchies:

  • one for the elements being operated on (the Element hierarchy)
  • one for the visitors that define operations on the elements (the Visitor hierarchy).

Create a new operation by adding a new subclass to the visitor class hierarchy.
If Node hierarchy does not change, we can add new functionality simply by defining new NodeVisitor subclasses.

Visitor Timing Diagram

Vanilla

Visitor visitor=new ConcreteVisitor1(); // roll up a new Visitor that is-a ConcreteVisitor1

Element element=new ConcreteElementA(); // roll up a new Element that is-a ConcreteElementA

element.accept(visitor); // first dispatch, polymorph on type of element (i.e. ConcreteElementA)

visitor.visitConcreteElementA(this); // second dispatch, polymorph on type of visitor

// (i.e. ConcreteVisitor1) - come visit me, here i am

Vanilla.java

Pizza (A Little Java, A Few Patterns)

Pie.java
PieManager.java
PieVisitor.java
TestVisitor.java

Martin's Visitor (triple dispatch)

MartinsVisitor.Java


Review

  • Fundamental Software Building Blocks
  • No Silver Bullet
  • Design at a Higher Level of Abstraction
  • Increased Communication (Pattern Language)
  • Programmers Handbook
  • Patterns appear at many levels (fractal design methodology?)
  • Just Another Way of Being Inefficient


Bibliography

  • "Design Patterns : Elements of Reusable Object-Oriented Software by Erich Gamma, Richard Helm, Ralph Johnson, John Vlissides, (Gang of Four)
  • "Design Patterns CD : Elements of Reusable Object-Oriented Software" by Gamma et. al. (Most of the diagrams in this document were taken from this source)
  • "Pattern Hatching" by John Vlissides
  • "Pattern Languages of Program Design" I ,II, III
  • "A System of Patterns" by Buschmann et. al. (Siemens, Gang of Five)
  • "The Patterns Handbook: Techniques, Strategies, and Applications" by Linda Rising
  • "A Little Java, A Few Patterns" by Matthias Felleisen and Daniel P. Friedman.
  • "Patterns in Java Volime I" by Mark Grand
  • "Advanced C++ Programming Styles and Idioms" by James O. Coplien
  • "Designing Object-Oriented C++ Applications Using The Booch Method" by Robert C. Martin
  • "C++ FAQS" by Marshall P. Cline and Greg A. Lomow
  • http://st-www.cs.uiuc.edu/users/patterns/patterns.html


Outline

    

版权所有:UML软件工程组织