Software Engineering - Design Patterns basics
UML Basics
The Unified Modeling Language (UML) is a standardized notation for modeling software systems. It can be used by developers to sketch designs when discussing at the whiteboard, or for documenting designs and architectures in specification documents.
Martin Fowler has written an excellent introductory book on UML, called “UML Distilled: A Brief Guide to the Standard Object Modeling Language” (2018 edition).
Basic notations
Class Diagram
- Association - I have a relationship with an object.
- Plain Arrow
- Composition - I own an object and I am responsible for its lifetime. If I die, the object die.
- Black Diamond
- The object can be owned by one object-owner at a time (no sharing)
- Aggregation - I have an object which I’ve borrowed from someone else. If I die, the object may live on.
- White Diamond
What is the difference between association, aggregation and composition?
- Resonsibilities - What does the object do
--
are basically comments in UML
Composition
- For composition, when the multiplicity is not mentioned, it is always 0…1
- No sharing rule
- An instance of Point may be part of a polygon or may be the center of a circle, but it cannot be both.
- I own an object and I am responsible for its lifetime. If I die, the object die.
- if you delete the polygon, it should automatically ensure that any owned Points also are deleted.
Composition is a good way of showing properties that own by value, properties to value objects, or properties that have a strong and somewhat exclusive ownership of particular other components. Aggregation is strictly meaningless; as a result, I recommend that you ignore it in your own diagrams. If you see it in other people’s diagrams, you’ll need to dig deeper to find out what they mean by it. Different authors and teams use it for very different purposes.
Interface and Abstract class
Object Diagram
An object diagram is a snapshot of the objects in a system at a point in time. Because it shows instances rather than classes, an object diagram is often called an instance diagram.
Consider this class diagram:
- This class diagram is actually a tree structure!
Note that
underlining object means instance.
- instance name : class name
- If you use only the class name, you must include the colon e.g.
:Person
underlining method means static.
Object diagrams are useful for showing examples of objects connected together. In many situations, you can define a structure precisely with a class diagram, but the structure is still difficult to understand. In these situations, a couple of object diagram examples can make all the difference.
Tree Structure:
Package Diagram
- In a UML model, each class is a member of a single package. Packages can also be members of other packages
- Package diagrams are extremely useful on larger-scale systems to get a picture of the dependencies between major elements of a system.
Sequence Diagrams
-
Sequence diagram captures the behavior of a single scenario
-
Read from Left to Right and Top-down
State Machine Diagrams
- State diagrams are good at describing the behavior of an object across several use cases.
- State diagrams are not very good at describing behavior that involves a number of objects collaborating.
Activity diagrams
- Activity diagrams are a technique to describe procedural logic, business process, and work flow.
Design Patterns
Book: Design Patterns: Elements of Reusable Object-Oriented Software by Gang of Four
-
Reusable designs to frequently occuring design problems
- in detailed design
-
Forms
- Problem / Intent
- Solution
- Structure (often expessed using UML)
- Static (e.g. interfaces)
- Dynamic (e.g. call sequences)
- Structure (often expessed using UML)
- Consequences
- Positive
- Negative
- opportunity / example
- other patterns that extend the design
-
Document
- hierarchical structure of glyphs
- pages
- paragraphs
- lines
- elements (char, images, drawings)
- Treat all document parts uniformly
- selecting parts
- drawing
- layout
- …
- hierarchical structure of glyphs
Example: Designing a document editor
Responsibility | Operation |
---|---|
Apperance | void draw(window) |
Selection | bool intersects(coor) |
Hierarchical structure | void insert(glyph) void remove(glyph) [glyph] children() glyph parent() |
Composite Pattern
Problem / Intent
- Hierarchical structure with all elements having uniform interface
Applicability
- Objects must be composed recursively
- No distinction between individual and composed elements
- Objects in the structure can be treated uniformly
- Tree Structures!
Solution
- A Composite can have multiple children, but A component can only have at most 1 parent
- the
{forall g in children g.operation();}
indicate the pseudocode
Consequences
- +ve: Uniformity
- flexible design
- +ve: Extensibility
- easy to add new types of components
- -ve: May allow too many combinations
- -ve: too many objects
Implementation variants
- Uniform interface for leaf & composite (how and where are add and remove implemented)
- Do composites have parent field?
Look at this class diagram:
- This class diagram is actually a tree structure!
Look at this object diagram:
Look at the variant, are those valid?
- Can the new Column instance be a object component into the row instance?
- Yes! the column instance is still a Glyph so can it be a object component into the row instance!
- Can the composition relationships done in cycle?
- No! Composition relationships cannot form a cycle!
- Can the composition relationships share?
- No! The No sharing rule! The object instance cannot be shared by multiple owners!
Decorator pattern
Problem / Intent
Augment objects with new functionality while keeping uniform interface
- Key point: Adding new function (embellishment)!
- Decorator = “Transparent” Wrapper’’
Applicability
- When extension by subclassing is impractical
- For responsibilities that can be withdrawn
Solution
Decorator = Transparent Wrapper’
- Note that Decorator can only be one
How does the extension look in object diagram:
Consequences
- + Responsibilities can be added/removed at run-time
- + Avoids subclass explosion
- + Recursive nesting allows multiple responsibilities
- – Interface occlusion
- Does not inherit child methods, and thus need to implement forwarding methods
- – Split identity (aka identity crisis, object schizophrenia)
- Clients might by accident point to the child rather than the decorator
What is identity crisis?
- Let’s say Client is pointing to the Row originally. When docorator pattern is used, the Client should be pointing to the docorator object (Frame). But the developers could forgot about it and did not update the references such that Client is still pointing to the Row!
This is another example of Decorator pattern!
Adapter Pattern
Problem / Intent:
- Convert the interface of a class into another interface clients expect.
Applicability
- When we want to reuse classes in an application that expects a different interface, we do not want to (and often cannot) change the reusable classes to suit our application.
- Adapter lets classes work together that couldn’t otherwise because of incompatible interfaces.
Solution
Participants:
- Target : Defines the application-specific interface that client uses
- Client : Collaborates with objects conforming to the target interface
- Adaptee : Defines an existing interface that needs adapting
- Adapter : Adapts the interface of the adaptee to the target interface
Example:
- Adding Assoication
Consequences
- + Adapting existing code into target interface
- - Write the code for adaption
Template Method
Intent
- Define the skeleton of an algorithm in an operation, deferring some steps to subclasses
Applicability
- Inheritence heavy (because a base class is needed)
- fragile base class problem
The fragile base class problem is a fundamental architectural problem of object-oriented programming systems where base classes (superclasses) are considered “fragile” because seemingly safe modifications to a base class, when inherited by the derived classes, may cause the derived classes to malfunction. The programmer cannot determine whether a base class change is safe simply by examining in isolation the methods of the base class. See https://en.wikipedia.org/wiki/Fragile_base_class
Consequences
- + Code reuse
- + Leads to inversion of control
- - fragile base class problem
Strategy Pattern
Intent
Define common interface for different algorithm
-
Encapsulate each algorithm, let clients and algorithms vary independently
-
Object composition
- clear interfaces, more flexible
Applicability
- When an object should be configurable with one of several algorithms, and all algorithms can be encapsulated, and one interface covers all encapsulations
Solution
Consequences
- + Greater flexibility, reuse
- + Can change algorithms dynamically
- - communication overhead
- - Inflexible strategy interface
Example:
- Movie is the Context
- MovieType is the Strategy
- StrategyA : Regular, StrategyB: NewRelase, StrategyC: Children
Another example:
- Route planning strategies
Abstract Factory Pattern
Intent
To have multiple Look & Feels: create families of related objects without specifying class names
- E.g. to show different look according to the OS, setting all UI elements at once but no hardcoding things
Applicability
- When clients cannot anticipate groups of classes to instantiate
Solution
Abstract the process of creating object
Participants:
- AbstractFactory
- An interface for operations that create abstract product objects
- Modularized for client
- ConcreteFactory
- Implements the operations to create concrete product objects
Example:
- Instead of
Scrollbar sb = new MotifScrollbar();
- use
Scrollbar sb = factory.createScrollbar();
where factory is an instance ofMotifFactory
Consequences
- + flexibility
- + Abstraction
- - Hard to extend factory interface to create new products
Observer Pattern
Intent
- Define 1-to-many dependency between objects so that when one object change state, all its dependent are notified and updated automatically
Applicability
- When changing one object require the change of others
Solution
Consequences
- + Modularity : subject and observers may vary independently
- + Extensibility : can define and add any number of observers
- + Customizability : different observers provide different views of subject
- - Unexpected updates : observers don’t know about each other
- - Update overhead : operations to notify
MVC uses observer pattern!
Practice Questions - Design Patterns
What is the main difference between composite and decorator in terms of their class structure? (one line of text should suffice)
Composite can have many components;
Decorator just one
What is the main difference between decorator and adapter? (one line of text should suffice)
Adapter changes the interface of the wrapped component
Decorator keeps it unchanged
Consider the UML class diagram below.
Consider the class diagram below.
Name the relationship between A and B:
Composite
What is incorrect about it?:
Cardinality/Multiplicity next to the black diamond should not be 2, it should be 1
Why?:
A child object can be component of at most 1 object at a time (no sharing rule)
Which design pattern suffers from the fragile base class problem?
Template Method. It is because Template Method relies on a base class.
Suppose that you are developing a graphical user interface library. The library will provide different kinds of widgets, including a text box (displaying text), a list box (displaying a list), and a combo box (displaying several widgets contained in it). What design pattern would you use to create the class hierarchy for the widgets? Please draw the resulting class diagram.
- Look for sign: We want to create a class hierarchy here!
- Composite is good for class hierarchy!
Extend the diagram from the previous question with two more widgets: scroll bars (adding scroll bars to any widget) and frame (adding a frame to any widget). What design pattern would you use for this extension? You don’t need to redraw the whole class diagram from the previous question; repeat only the class(es) necessary to do the extension.
- Look for sign: We want to extend (new functionality)!
- Decorator will work well here!