CS 326 Design Patterns What Is a Design Pattern? Example 1

CS 326 Design Patterns What Is a Design Pattern? Example 1

What is a Design Pattern? • A standard solution to a common programming problem CS 326 Design Patterns Stephen Freund Example 1: Encapsulation Example 2: Inheritance • Problem: Exposed properties can be directly • Problem: Repetition in implementations manipulated – Similar abstractions have similar components – Violations of the representation invariant • Solution: Inherit default members from a – Dependences prevent changing the implementation superclass • Solution: Hide some components – Select an implementation via run-time dispatching – Constrain ways to access the object • Disadvantages: • Disadvantages: – Code for a class is spread out, and thus less – Interface may not (efficiently) provide all desired understandable operations to all clients – Hard to design and specify a superclass ahead of time – Indirection may reduce performance – Run-time dispatching introduces overhead 1 Example 3: Iteration Example 4: Generics • Problem: To access all members of a collection, need a • Problem: specialized traversal for each data structure – Well-designed data structures only hold one type of – Introduces undesirable dependences object – Does not generalize to other collections • Solution: • Solution: – Programming language checks for errors in contents – The implementation provides traversal abstraction, does bookkeeping – Set<Int> instead of just Set – Results are communicated to clients via a standard interface • Disadvantages: (eg: Sequence methods) – More verbose types • Disadvantages: – Sometimes less understandable error messages – Iteration order fixed by the implementation and not under the control of the client Other Examples Design Pattern in More Detail • Reuse implementation without subtyping • A standard solution to a common programming • Reuse implementation, but change interface problem • Permit a class to be instantiated only once – A design or implementation structure that achieves a • Constructor that might return an existing object particular purpose • Constructor that might return a subclass object – A high-level programming idiom • Combine behaviors without compile-time • A technique for making code more flexible extends clauses – Reduce coupling among program components • Shorthand for describing software design • You could come up with a solution to all of these – connections among components, heap structure, ... on your own, but why reinvent the wheel??? • Vocabulary for communication and documentation 2 When To Use A Design Pattern Canonical Reference • Rule #1: Delay to avoid over-thinking – Get something basic and concrete working first – Improve or generalize it once you understand it • Design patterns can increase / decrease understandability – Improves modularity and flexibility, separates concerns, eases description – But usually adds indirection, increases code size • If you encounter a design problem, consider • aka: "Gang Of Four" Book design patterns that address that problem Three Kinds Of Patterns Creational Patterns • Creational patterns • Initializers are inflexible – constructing objects – Can't return a subtype of class they belong to • Structural patterns – Create new object, and never re-use existing one – combining objects, controlling heap layout • Behavioral patterns • Factory Patterns – communicating among objects, affecting object – ADT creators that are not Swift init()s semantics • Sharing Patterns: – Reuse objects to save space or share common state 3 Factories: Changing Implementations A Factory • Supertypes support multiple implementations class MatrixFactory { public static func createMatrix() -> Matrix { – protocol Matrix { ... } ... – class SparseMatrix : Matrix { ... } return SparseMatrix() – class DenseMatrix : Matrix { ... } } • Clients use the supertype (Matrix) but still create } objects: • Clients call MatrixFactory.createMatrix() – let m : Matrix = SparseMatrix() or instead of a particular constructor – let m : Matrix = DenseMatrix() or ... +To switch implementation, change only one place • Switching implementations requires changing +createMatrix() can do arbitrary code computations to decide what kind of matrix to make Example: Bicycle race Factory Method for Bicycles class Race { public init() { class Race { let bike1 = Bicycle() func createBicycle() -> Bicycle { let bike2 = Bicycle() Bicycle() … class TourDeFrance : Race { } class TourDeFrance : Race { } public init() { init() { func createBicycle() -> Bicycle { … let bike1 = RoadBicycle() let bike1 = RoadBicycle() } } let bike2 = RoadBicycle() createBicycle() … … class Cyclocross : Race { let bike2 = } } public init() { … createBicycle() let bike1 = MountainBicycle() class Cyclocross : Race { } … let bike2 = MountainBicycle() func createBicycle() -> Bicycle { … } MountainBicycle() … } } … … } } } 4 Factory Object for Bicycles Passing Factory Objects Around class BicycleFactory { func createBicycle() -> Bicycle { ... } class Race { func createWheel() -> Wheel { ... } init(factory : BicycleFactory) { func createFrame() -> Frame { ... } let bike1 = factory.createBicycle() } let bike2 = factory.createBicycle() … class RoadBicycleFactory: BicycleFactory { } override func createBicycle() -> Bicycle { } RoadBicycle() } class TourDeFrance : Race { } init() { super.init(factory: RoadBicycleFactory()) } } class MoutainBicycleFactory: BicycleFactory { class Cyclocross: Race { override func createBicycle() -> Bicycle { init() { super.init(factory: MountainBikFactory()) } MoutainBicycle() } } } Separate Control of Bicycles / Races External Dependency Injection class Race { • Java Example: init(factory : BicycleFactory) { – BicycleFactory f = new UnicycleFactory(); let bike1 = factory.createBicycle() – Race r = new TourDeFrance(f); let bike2 = factory.createBicycle() … • With external dependency injection: } – BicycleFactory f = ((BicycleFactory) } DependencyManager.get("BicycleFactory")); – Race r = new TourDeFrance(f); class TourDeFrance : Race { init(factory : BicycleFactory) { • Plus an external file: super.init(factory: factory) <service-point id="BicycleFactory"> } <invoke-factory> <construct class="Bicycle"> init() { super.init(factory: RoadBicycleFactory()) } <service>Tricycle</service> } </construct> </invoke-factory> + Change the factory without recompiling let race = TourDeFrance(factory: unicycleFactory) </service-point> - External file is essential part of program 5 External Dependency Injection Factories: Summary • Interface Builder and Storyboards... • Problem: Want more flexible abstractions for what class to instantiate. • Factory method – Call method that can do any computation and return any subtype • Factory object – Bundles factory methods for a family of types – Can store factory object, pass to constructors, etc. • Dependency Injection – Put choice of subclass in a file to avoid source-code changes or even recompiling when decision changes Design Patterns for Sharing Singleton • Problem: Swift initializers always return a new • Only one object of the given type exists object, never a pre-existing object • Good for unique, shared resources – UserDefaults.standard – DispatchQueue.main • Singleton: only one object exists at runtime – UIApplication.sharedApplication() – Factory method returns the same object every time – Logger for diagnostic messages • Better than lots of global properties • Interning: only one object with a particular – logically group related values (abstract) value exists at run time – Can use initializer / factory to customize – Factory method returns an existing object, not a new – eg: Internationalization: messages in a particular one language 6 Creating Singletons Interning pattern • In Swift class: • Reuse existing objects instead of creating new ones – public constant property to hold singleton object "Stephen Freund" name – private initializer street: "47 Lab Campus Drive" address town: "Williamstown, MA 01267" class Logger { ... static public let instance = Logger() "Bill Lenhart" private init() { ... } name street: "47 Lab Campus Drive" } address town: "Williamstown, MA 01267" • In client: class Address : Hashable { let street : String – Refer to the single instance of the Singleton class let town : String – Logger.instance.print("button clicked") ... } Interning pattern Simple Interning Mechanism • Reuse existing objects instead of creating new ones • Maintain a collection of all objects "Stephen Freund" • name If an object already appears, return that instead street: "47 Lab Campus Drive" var interned = Set<Address>() address town: "Williamstown, MA 01267" func intern(_ n : Address) -> Address { ... // inserts if not present, returns elem == n in set. "Bill Lenhart" let (_, memberAfterInsert) = interned.insert(n) name return memberAfterInsert address } • Less space • objects can be compared with === instead of == • Create the object, but perhaps discard it and • Sensible only for immutable objects return another when interning. 7 java.lang.Boolean and Interning public class Boolean { private final boolean value; Should have never been // construct a new Boolean value public Boolean(boolean value) { made public this.value = value; } // Singletons for true and false public static Boolean FALSE = new Boolean(false); public static Boolean TRUE = new Boolean(true); // factory method that uses interning public static Boolean valueOf(boolean value) { return value ? TRUE : FALSE; } Boolean b = Boolean.valueOf(true); } vs Boolean b = new Boolean(true); 8.

View Full Text

Details

  • File Type
    pdf
  • Upload Time
    -
  • Content Languages
    English
  • Upload User
    Anonymous/Not logged-in
  • File Pages
    8 Page
  • File Size
    -

Download

Channel Download Status
Express Download Enable

Copyright

We respect the copyrights and intellectual property rights of all users. All uploaded documents are either original works of the uploader or authorized works of the rightful owners.

  • Not to be reproduced or distributed without explicit permission.
  • Not used for commercial purposes outside of approved use cases.
  • Not used to infringe on the rights of the original creators.
  • If you believe any content infringes your copyright, please contact us immediately.

Support

For help with questions, suggestions, or problems, please contact us