1 / 206

Busy iOS Developer's Guide to Design Patterns in Swift

Busy iOS Developer's Guide to Design Patterns in Swift. Ted Neward Neward & Associates http://www.tedneward.com | ted@tedneward.com. Credentials. Who is this guy? Principal, Neward & Associates ask me how I can help your project, your team or your firm

hollyduncan
Download Presentation

Busy iOS Developer's Guide to Design Patterns in Swift

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Busy iOS Developer's Guide to Design Patterns in Swift Ted Neward Neward & Associates http://www.tedneward.com | ted@tedneward.com

  2. Credentials Who is this guy? • Principal, Neward & Associates ask me how I can help your project, your team or your firm • Microsoft MVP (F#, C#, Architect); Java Expert (JSRs 175, 277) • Author Professional F# 2.0 (w/Erickson, et al; Wrox, 2010) Effective Enterprise Java (Addison-Wesley, 2004) SSCLI Essentials (w/Stutz, et al; OReilly, 2003) Server-Based Java Programming (Manning, 2000) • Blog: http://blogs.tedneward.com • Writing: http://www.newardassociates.com/#/writing • Twitter: @tedneward • For more, see http://www.newardassociates.com/#/about

  3. Objectives Before we leave, we want to have seen... • ... some discussion about patterns • ... some classic GOF patterns in Swift implemented several different ways • ... how patterns evolve • ... how patterns can still be useful

  4. Patterns What are they, exactly?

  5. Patterns Overview Patterns • originally "discovered" by Erich Gamma's PhD thesis • later turned into a book by "the Gang-of-Four" book • "Design Patterns" (Addison-Wesley) • Gamma • Richard Helm • Ralph Johnson • John Vlissides • then turned into a movement in the mid-2000s • ... which didn't really pay off well, unfortunately too much hype and mania

  6. Patterns Overview Patterns vs Idioms • patterns are language-agnostic; idioms are language-specific • patterns are often tweaked; idioms are usually used as-is • patterns can sometimes turn into idioms

  7. Pattern Goals Why would we do this?

  8. Patterns Goals Opening your eyes • "you won't ever think about object-oriented design in the same way" • "you'll have insights that can make your own designs more flexible, modular, reusable, and understandable"

  9. Patterns Goals Concepts, not code • "don't worry if you don’t understand this book completely on the first reading" • "this isn't a book to read once and put on a shelf"

  10. Patterns Goals This means trying to "reuse" patterns as code don't work out well • this meant that patterns were a failure to many people However, they are still useful • specifically, they help identifiable reusable ideas/concepts • so long as we don't expect too much out of them... most notably, not reusable code • ... there's much good stuff that can come from them

  11. Patterns Goals Common lexicon • we can use patterns to describe designs at a higher level • "use a Builder to create a Chain of Responsibility" • "you were thinking Visitor? I was thinking more Strategy, myself" • ... and so on

  12. Pattern Forms How shall I describe thee? Let me count the ways....

  13. Patterns Forms "Patterns Form" • I prefer the simplest distillation: "a probem, within a certain context, that was solved using a solution that yielded certain consequences" • Problem • Context • Solution • Consequences

  14. Patterns Forms "GOF (Long) Form": • Name (and Classification) • Intent • Also Known As • Motivation • Applicability • Structure • Participants • Collaborations • Consequences • Implementation • Sample Code • Known Uses • Related Patterns

  15. Creational Patterns Instantiating object instances

  16. Creational Creational patterns • Creational class patterns defer some part of object creation to subclasses • Creational object patterns defer object creation to another object

  17. Creational Creational Class Patterns • Factory Method (121) Creational Object Patterns • Abstract Factory (99) • Builder (110) • Prototype (133) • Singleton (144)

  18. Abstract Factory Creational Object

  19. Abstract Factory Intent "Provide an interface for creating families of related or dependent objects without specifying their concrete classes"

  20. Abstract Factory Applicability • a system should be independent of how its products are created, composed, and represented • a system should be configured with one of multiple families of products • a family of related product objects is designed to be used together, and you need to enforce this constraint • you want to provide a class library of products, and you want to reveal just their interfaces, not their implementations

  21. Abstract Factory Consequences • It isolates concrete classes • It makes exchanging product families easy • It promotes consistency among products • Supporting new kinds of products is difficult

  22. Abstract Factory Abstract Factory (in Swift): AbstractProduct class Shape { let id = total++; func Draw() { preconditionFailure("Should never be invoked!") } static var total = 0; }

  23. Abstract Factory Abstract Factory (in Swift): ConcreteProduct class Circle : Shape { override func Draw() { print("circle \(id): draw") } } class Square : Shape { override func Draw() { print("square \(id): draw") } } class Ellipse : Shape { override func Draw() { print("ellipse \(id): draw") } } class Rectangle : Shape { override func Draw() { print("rectangle \(id): draw") } }

  24. Abstract Factory Abstract Factory (in Swift): AbstractFactory class Factory { func CreateCurvedInstance() -> Shape { preconditionFailure("Should never be invoked!") } func CreateStraightInstance() -> Shape { preconditionFailure("Should never be invoked!") } }

  25. Abstract Factory Abstract Factory (in Swift): ConcreteProduct class SimpleShapeFactory : Factory { override func CreateCurvedInstance() -> Shape { return Circle() } override func CreateStraightInstance() -> Shape { return Square() } } class RobustShapeFactory : Factory { override func CreateCurvedInstance() -> Shape { return Ellipse() } override func CreateStraightInstance() -> Shape { return Rectangle() } }

  26. Abstract Factory Abstract Factory (in Swift): Usage let factory = SimpleShapeFactory() // or RobustShapeFactory() let shapes = [ factory.CreateCurvedInstance(), factory.CreateStraightInstance(), factory.CreateCurvedInstance() ] for s in shapes { s.Draw() }

  27. Abstract Factory But... don't forget about "class" modifiers instead of "static" • these can be overridden (!) in derived classes

  28. Abstract Factory Abstract Factory (in Swift): Factory (revisited) class ClassFactory { class func CreateCurvedInstance() -> Shape { preconditionFailure("Should never be invoked") } } class SimpleClassShapeFactory : ClassFactory { override class func CreateCurvedInstance() -> Shape { return Circle() } }

  29. Abstract Factory Abstract Factory (in Swift): Usage let factory2 = SimpleClassShapeFactory.self // now we are using the metatype of SimpleClassShapeFactory let shapes2 = [ factory2.CreateCurvedInstance(), factory2.CreateCurvedInstance() ] for s in shapes2 { s.Draw() }

  30. Builder Creational Object

  31. Builder Intent "Separate the construction of a complex object from its representation so that the same construction process can create different representations"

  32. Builder Applicabilty • the algorithm for creating a complex object should be independent of the parts that make up the object and how they're assembled • the construction process must allow different representations for the object that's constructed

  33. Builder Consequences • lets you vary a product's internal representation • isolates code for construction and representation • gives you finer control over the construction process

  34. Builder Additional Notes: FluentBuilder perhaps this is actually a different pattern? • Applicability: allows for a more client-driven construction process • Applicability: the construction process should be more client-readable

  35. Builder Builder (in Swift): Product class Product { var parts : String = "" }

  36. Builder Builder (in Swift): AbstractCreator class Builder { func BuildPart() { preconditionFailure("Should never invoke this") } func GetResult() -> Product { preconditionFailure("Should never invoke this") } }

  37. Builder Builder (in Swift): ConcreteCreator class ConcreteBuilder : Builder { override func BuildPart() { product.parts = product.parts + "Adding part #\(part++)\n" } override func GetResult() -> Product { return product } var part = 0 var product = Product() }

  38. Builder Builder (in Swift): Director and Usage class Director { func Construct() -> Product { for _ in 1 ... 5 { builder.BuildPart() } return builder.GetResult() } let builder = ConcreteBuilder() } let director = Director() let product = director.Construct() print(product.parts)

  39. Builder Builder (in Swift): FluentBuilder class FluentBuilder { var product = Product() func Begin() -> FluentBuilder { product = Product() return self } func Engine() -> FluentBuilder { product.parts = product.parts + "Engine\n" return self } func SteeringWheel() -> FluentBuilder { product.parts = product.parts + "SteeringWheel\n" return self } func Tire() -> FluentBuilder { product.parts = product.parts + "Tire\n" return self } func Construct() -> Product { return product } }

  40. Builder Builder (in Swift): FluentBuilder Usage let vehicleBuilder = FluentBuilder() let motorcycle = vehicleBuilder.Begin() .Engine() .SteeringWheel() .Tire() .Tire() .Construct() print(motorcycle.parts)

  41. Factory Method Creational Class

  42. Factory Method Intent "Define an interface for creating an object, but let subclasses decide which class to instantiate. Factory Method lets a class defer instantiation to subclasses."

  43. Factory Method Applicability • a class can't anticipate the class of objects it must create • a class wants its subclasses to specify the objects it creates • classes delegate responsibility to one of several helper subclasses, and you want to localize the knowledge of which helper subclass is the delegate

  44. Factory Method Consequences • Eliminate the need to bind application-specific classes into your code • Clients might have to subclass the Creator class just to create a particular ConcreteProduct object • Provides hooks for subclasses • Connects parallel class hierarchies

  45. Factory Method Additional Notes • Applicability: client may want/need to parameterize construction • Applicability: construction system may want to open itself up for extension from unknown sources

  46. Factory Method Factory Method (in Swift): Product class Product { func DoSomething() { preconditionFailure("Should never be invoked") } }

  47. Factory Method Factory Method (in Swift): ConcreteProduct class ConcreteProduct : Product { override func DoSomething() { print("ConcreteProduct did something\n") } }

  48. Factory Method Factory Method (in Swift): Creator and ConcreteCreator class Creator { func FactoryMethod() -> Product { preconditionFailure("Should never be invoked") } } class ConcreteCreator : Creator { override func FactoryMethod() -> Product { return ConcreteProduct() } }

  49. Factory Method Factory Method (in Swift): Usage let creator = ConcreteCreator() let product = creator.FactoryMethod() product.DoSomething()

  50. Factory Method Sometimes we want some slightly different semantics • parameterized construction of Products • open-ended construction possibilities James Coplien called a variant of this his "Exemplar" idiom in the LSD book

More Related