51 / 115 public String ClamType() { } } {1}",ClamType(), cheese); return String.Format("fancy clam pizza with {0} and public String Describe() { } return String.Format("fancy {0}",clam); } 1. Dependencies this .cheese = cheese; this .clam = clam; public FancyClamPizza (IClam clam, ICheese cheese) { private ICheese cheese; private IClam clam; public class FancyClamPizza: IClamPizza { namespace DITest { }
52 / 115 container.Register(Classes } } } .WithServiceAllInterfaces()); .InSameNamespaceAs <IoCInstaller >() .AllowMultipleMatches() .FromThisAssembly() .WithServiceAllInterfaces()); 2. Registration .InNamespace("DITest.NYStyle") .FromThisAssembly() container.Register(Classes store) { public void Install(IWindsorContainer container , IConfigurationStore public class IoCInstaller: IWindsorInstaller { namespace DITest{ Castle Windsor, http://www.castleproject.org
53 / 115 3. Resolution // adds and configures all components using WindsorInstallers from executing assembly container.Install(FromAssembly.This()); // instantiate and configure root component and all its dependencies and their dependencies and... var p = container.Resolve <ICheesePizza >(); Console.WriteLine(p.Describe()); var container = new WindsorContainer();
54 / 115 Part XI Singleton
55 / 115 What about static methods? } } } e.printStackTrace(); Thread.sleep(100); // Very expensive job indeed try { private Singleton() { } System.out.println("Hi there!"); public static void someOtherMethod(){ } return name; public String getName() { private String name; private static Singleton instance = new Singleton(); public class Singleton { Our app takes forever to load if the Singleton class is part of it. } catch (InterruptedException e) { name = Math.random() > 0.5 ? "Jonas" : "Anders";
56 / 115 // Thread that does not use the Singleton object Singleton name: Anders someOtherMethod invoked } e.printStackTrace(); // TODO Auto-generated catch block t2.join(); t1.join(); try { t2.start(); t1.start(); t0 = System.nanoTime(); Thread t2 = new Thread( new SingletonLookup()); // Thread that uses the Singleton object Thread t1 = new Thread( new StaticMethodInvocation()); Static method invocation took 1 002 463 000 ns } catch (InterruptedException e) { Singleton lookup took 1 003 348 000 ns
57 / 115 How about now? private static Singleton instance; public static Singleton getInstance() { if (instance == null ) { } return instance; } someOtherMethod invoked Singleton name: Anders Static method invocation took 899 000 ns Singleton lookup took 1 003 348 000 ns instance = new Singleton(); ◮ How about now?
58 / 115 What about threads?
59 / 115 private static final class SingletonLookup implements Runnable { } Singleton.getInstance().getName())); ", System.out.println(MessageFormat.format("Singleton name: {0} public void run() { @Override } private Singleton() { } e.printStackTrace(); Thread.sleep(100); // Very expensive job indeed try { } } catch (InterruptedException e) { name = Math.random() > 0.5 ? "Jonas" : "Anders";
60 / 115 Singleton name: Jonas t0 = System.nanoTime(); t1.start(); t2.start(); try { t1.join(); t2.join(); public static void main(String[] args) { // TODO Auto-generated catch block e.printStackTrace(); } System.out.println("Singleton name after our threads have run: "+Singleton.getInstance().getName()); } Thread t1 = new Thread( new SingletonLookup()); Thread t2 = new Thread( new SingletonLookup()); } catch (InterruptedException e) { Singleton name after our threads have run: Anders Oops!
61 / 115 public static synchronized Singleton getInstance() { if (instance == null) { instance = new Singleton(); } return instance; } Singleton name: Anders Singleton name: Anders Singleton lookup took 1 003 340 000 ns Singleton lookup took 1 003 286 000 ns Singleton name after our threads have run: Anders Woohoo!
62 / 115 this .name = name; } this .age = age; public void setAge( int age) { } return age; public int getAge() { } public void setName(String name) { Singleton as Enum } return name; public String getName() { private int age; private String name; INSTANCE; public enum EnumSingleton { }
63 / 115 Singletons in Ruby
64 / 115 #<A:0x007f8d6b92bcb0 > irb:13:in `<main>' from ruby-2.0.0-p247/bin/ from (irb):16 from (irb):10: in `new' RuntimeError: Illegal! irb(main):016:0> A.new irb(main):014:0> a class A end end raise "Illegal!" def new class << A a = A.new end Now we have one object, but we cannot produce another of the same class
65 / 115 Singleton: consequences - Violates several design principles! + Ensures single objects per class ◮ Saves memory ◮ Ensures consistency
66 / 115 Singleton considered dangerous ◮ Encapsulate what varies ◮ Program to an interface, not to an implementation ◮ Favor composition over inheritance ◮ Classes should be open for extension but closed for modifjcation ◮ Don’t call us, we’ll call you ◮ Depend on abstractions, do not depend on concrete classes ◮ Classes should only have one reason to change ◮ Strive for loosely-coupled design
67 / 115 Part XII Builder
68 / 115
69 / 115
70 / 115
71 / 115 Director Builder Client
72 / 115 Abstract Factory Client receives a Factory Builder Client initializes Director with Builder Client asks Director to build Client requests a product from Factory ⇒ Client receives an abstract product Client requests product from Builder ⇒ Client receives a builder-specifjc product
73 / 115 Builder: consequences + Can control the way objects are created + Can produce difgerent products using the same Director - Not necessarily a common interface for products - Clients must know how to initialize builders and retrieve products
74 / 115 Adapter
75 / 115 Class Adapter Object Adapter
76 / 115 Multiple back-end objects
77 / 115 Multiple back-end methods
78 / 115 } } public class DuckAdapter implements Turkey { Duck duck; Random rand; public DuckAdapter(Duck duck) { this .duck = duck; public void gobble() { public void gobble(); duck.quack(); } public void fly() { if (rand.nextInt(5) == 0) { duck.fly(); } } public void fly(); public interface Turkey { public interface Duck { } public void quack(); public void fly(); } public class TurkeyAdapter implements Duck { Turkey turkey; public TurkeyAdapter(Turkey turkey) { this .turkey = turkey; } } public void quack() { turkey.gobble(); } public void fly() { for ( int i=0; i < 5; i++) { turkey.fly(); } } rand = new Random();
79 / 115 Adapter: consequences + Isolates interface changes to the adapter class - Class adapters require target interfaces or multiple inheritance in the language
80 / 115 Part XIII Bridge
81 / 115 Abstraction == That which we (should) care about
82 / 115 Remote / TV Samsung LG Logitech Harmony On() Ofg() On() Ofg() One For All On() Ofg() On() Ofg()
83 / 115 Transmission type / Message type Password recovery Signup E-mail Send() Send() SMS Send() Send()
84 / 115 Bridge Strategy Intent Decouple two class hierarchies (ab- straction/implementation) Allow for exchangeable algorithms Collaborations The Bridge forwards requests to the Implementor The Context and Strategy collabo- rate, passing data between them
85 / 115 Bridge Adapter Intent Decouple two class hierarchies (ab- straction/implementation) Convert an existing class to fjt a new interface Applicability In a new system In an existing system
86 / 115 Design principles ◮ Encapsulate what varies ◮ Program to an interface, not to an implementation ◮ Favor composition over inheritance ◮ Classes should be open for extension but closed for modifjcation ◮ Don’t call us, we’ll call you ◮ Depend on abstractions, do not depend on concrete classes ◮ Classes should only have one reason to change
87 / 115 Bridge: consequences + Lets two class hierarchies with common superclasses vary independently - If some implementation classes do not support an abstract concept, the abstraction breaks
88 / 115 Part XIV Observer
89 / 115
90 / 115
91 / 115
92 / 115 Subject Concrete Observers
93 / 115 Mediator vs Observer An Observer lets one object (or event) talk to a set of objects. A Mediator lets objects talk to each other through the Mediator.
94 / 115 Design principles ◮ Encapsulate what varies ◮ Program to an interface, not to an implementation ◮ Favor composition over inheritance ◮ Classes should be open for extension but closed for modifjcation ◮ Don’t call us, we’ll call you ◮ Depend on abstractions, do not depend on concrete classes ◮ Classes should only have one reason to change ◮ Strive for loosely-coupled design
95 / 115 Part XV Chain of Responsibility
96 / 115
97 / 115
98 / 115 Examples ◮ Logging ◮ Input management in GUI:s
99 / 115 CoR: consequences + Provides the Observer with more control over invocation of targets - A handler does not know if it will receive a message, depending on the behavior of other handlers in the chain
100 / 115 Memento
Recommend
More recommend