Strategy (THIẾT kế đối TƯỢNG SLIDE)

28 48 0
Strategy (THIẾT kế đối TƯỢNG SLIDE)

Đang tải... (xem toàn văn)

Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống

Thông tin tài liệu

The Strategy Pattern The Specifications • Joe works at a company that produces a simulation game called SimUDuck He is an OO Programmer and his duty is to implement the necessary functionality for the game • The game should have the following specifications: – – – A variety of different ducks should be integrated into the game The ducks should swim The ducks should quack A First Design for the Duck Simulator Game Duck All ducks quack() and swim() The superclass takes care of the implementation quack() swim() The display() method is abstract since all the duck subtypes look display() //other duck like methods different Each duck subtype is responsible for MallardDuck implementing its own display() behavior for how it looks on the RedHeadDuck screen display() display() Lots of other types of ducks inherit from the Duck type But now we need the ducks to fly… Joe, at the shareholders meeting we decided that we need to crush the competition From now on our ducks need to fly Duck quack() swim() display() fly() MallardDuck display() All subclasses inherit fly() RedHeadDuck display() But something went horribly wrong • At a demo the program failed to impress anyone – There were rubber ducks flying across the screen! Duck What happened? A localized update to the code caused a non-local side effect (flying rubber ducks) quack() swim() display() fly() MallardDuck display() RedHeadDuck display() By putting fly() in the superclass, Joe gave flying ability to all ducks including those that shouldn’t RubberDuck quack() display() Inheritance at Work public class Duck { Duck public void fly() { + quack () // fly implementation + swim () + } display () public void quack() { + fly () System.out.println("quack, quack"); } } MallardDuck + display () RubberDuck RedHeadDuck + display () we override the quack() method + quack () + fly () + quack quack We can override the fly() method in the rubber duck in a similar way that display () public class RubberDuck extends Duck { squick public void fly() { } public void quack() { System.out.println( "squick, squick"); } } Yet Another Duck is Added to the Application What would happen if we added a DecoyDuck to the class Duck hierarchy? + quack () + swim + display It doesn’t quack() or fly() () () + fly () public class DecoyDuck extends Duck { public void fly() { MallardDuck RubberDuck RedHeadDuck DecoyDuck // nothing } + display () + display () + quack () + + fly () + display quack () + fly () () + display public void quack() { () // nothing } } How about an interface? • Need a cleaner way to make some ducks fly or quack – Could take the fly() out of the superclass and make an Flyable interface with a fly() method Each duck that is supposed to fly will implement that interface – and maybe a Quackable interface as well Flyable Quackable Duck + swim() + fly() + quack() + display() // other duck like methods What you think about this design? MallardDuck + fly() RedHeadDuck + fly() + quack() + quack() + display() + display() RubberDuck DecoyDuck + display() + quack() + display() What you think? • Dumb!!!! • “Duplicate code” all over the place – – Interface not reuse code A small change to the flying behavior will require changing all 48 of the Duck subclasses! Embracing Change • In SOFTWARE projects you can count on one thing that is constant: CHANGE • Solution – Deal with it • • Make CHANGE part of your design Identify what vary and separate from the rest Let’s shoot some ducks! 10 Embracing Change in Ducks • fly() and quack() are the parts that vary • We create a new set of classes to represent each behavior QuackBehavior FlyBehavior + quack() + fly() FlyWithWings + fly() print("I'm flying!") print("I can't fly.") FlyNoWay + fly() Quack Squick + quack() + quack() print("Quack") MuteQuack + quack() print(" ") print("Squeak") 14 Design Principle Program to an interface not to an implementation 15 The Constitution of Software Architects • • Encapsulate what varies Program through an interface not to an implementation • • • • • • • ????????? ????????? ????????? ????????? ????????? ????????? ????????? 16 Design Principle Example Animal Program through an implementation + makeSound() Dog dog = createDog(); dog.bark(); Dog + makeSound() { Cat + makeSound() { bark(); } meow(); Program through an interface Animal dog = createDog(); dog.makeSound(); } + bark() + moew() 17 Integrating the Duck Behavior Instance variables hold a The behavior variables are declared as reference to a specific behavior Duck the behavior interface type at runtime # flyBehavior : FlyBehavior # quackBehavior : QuackBehavior quackBehavior.quack(); + performQuack() These replace the fly() and quack() methods + performFly() + swim() flyBehavior.fly(); + display() MallardDuck + display() class MallardDuck extends Duck RedHeadDuck + display() RubberDuck + display() + display() class DecoyDuck extends Duck public MallardDuck(){ public DecoyDuck(){ flyBehavior = new FlyWithWings(); flyBehavior = new FlyNoway(); quackBehavior = new Quack(); quackBehavior = new MuteQuack(); } } DecoyDuck } } 18 Design Principle Ahead Duck # flyBehavior : FlyBehavior Each Duck HAS A FlyingBehavior and a QuackBehavior to which it delegates flying and quacking behaviors # quackBehavior : QuackBehavior + performQuack() + performFly() Composition + swim() + display() Instead of inheriting behavior, the duck get their behavior by being composed with the right behavior object 19 Design Principle Favor Composition over Inheritance 20 The Constitution of Software Architects • • Encapsulate what varies Program through an interface not to an implementation • • • • • • • Favor Composition over Inheritance ????????? ????????? ????????? ????????? ????????? ????????? 21 Putting it together… public interface QuackBehavior { void quack(); } public interface FlyBehavior { void fly(); } public abstract class Duck { protected FlyBehavior flyBehavior; protected QuackBehavior quackBehavior; public performQuack() { quackBehavior.quack(); } public performFly() { flyBehavior.fly(); } } 22 Putting it together… public class MallardDuck extends Duck { public MallardDuck() { quackBehavior = new Quack(); flyBehavior = new FlyWithWings(); } } public class Quack implements QuackBehavior { public void quack() { System.out.println("Quack"); } } public class FlyWithWings implements FlyBehavior { public void fly() { System.out.println("I'm flying!!"); } } public class MiniDuckSimulator { public static void main(String[] args) { Duck mallard = new MallardDuck(); } mallard.performQuack(); I'm a real Mallard duck mallard.performFly(); Quack I'm flying!! } 23 Setting Behavior Dynamically! public void setFlyBehavior(FlyBehavior fb) { Duck flyBehavior = fb; - flyBehavior : FlyBehavior } - quackBehavior : QuackBehavior public void setQuackBehavior(QuackBehavior qb) { quackBehavior = qb; + performFly() } + performQuack() + swim() + display() // Test it out in main + setFlyBehavior(f : FlyBehavior) + setQuackBehavior(q : QuackBehavior) Duck model = new ModelDuck(); model.performFly(); model.setFlyBehavior( // Create a new type of Duck new FlyRocketPowered()); public class ModelDuck extends Duck { model.performFly(); public ModelDuck() { setFlyBehavior(new FlyNoWay()); setQuackBehavior(new Quack()); } public void display() { System.out.println("I'm a model duck"); } } // Make a new FlyBehavior type public class FlyRocketPowered implements FlyBehavior { public void fly() { System.out.println("I'm flying with a rocket"); } } 24 The Big Picture FlyBehavior Duck + fly() # flyBehavior : FlyBehavior # quackBehavior : QuackBehavior + performFly() + performQuack() FlyWithWings + swim() + display() FlyRocketPower FlyNoWay + fly() + fly() + fly() + setFlyBehavior(f : FlyBehavior) + setQuackBehavior(q : QuackBehavior) QuackBehavior MallardDuck + display() RedHeadDuck + display() RubberDuck + display() DecoyDuck + display() Quack Squick + quack() + quack() 25 MuteQuack + quack() Behavior Reuse FlyBehavior Duck + fly() - flyBehavior : FlyBehavior - quackBehavior : QuackBehavior + performFly() + performQuack() FlyWithWings + swim() FlyNoWay + display() + fly() + setFlyBehavior(f : FlyBehavior) + fly() + setQuackBehavior(q : QuackBehavior) QuackBehavior MallardDuck + display() DecoyDuck RubberDuck RedHeadDuck + display() + display() + display() Squick Quack + quack() + quack() Plane - flyBehavior : FlyBehavior + performFly() AirForceOne Airbus Boeing Apache 26 MuteQuack + quack() The Strategy Design Pattern The Strategy Design Pattern defines a family of algorithms, encapsulates each one, and makes them interchangeable Strategy lets the algorithms vary independently from the clients that use it Context manages the data structures that a concrete strategy operates on Defines the generic interface Context - strategy : Strategy Strategy + Context(s : Strategy) + runAlgorithm() + setStrategy(s : Strategy) + runAlgorithm() strategy.runAlgorithm(); ConcreteStrategyA + runAlgorithm() ConcreteStrategyB ConcreteStrategyC + runAlgorithm() + runAlgorithm() ConcreteStrategy classes provide the implementations of the different strategies These operate on the data structures in the the Context, and can be set dynamically 27 Summary • Strategy pattern allows selection of one of several algorithms dynamically • Algorithms may be related via an inheritance hierarchy or unrelated [must implement the same interface] • Strategies don’t hide everything client code is typically aware that there are a number of strategies and has some criteria to choose among them shifts the algorithm decision to the client 28 ... strategy operates on Defines the generic interface Context - strategy : Strategy Strategy + Context(s : Strategy) + runAlgorithm() + setStrategy(s : Strategy) + runAlgorithm() strategy. runAlgorithm();... runAlgorithm() strategy. runAlgorithm(); ConcreteStrategyA + runAlgorithm() ConcreteStrategyB ConcreteStrategyC + runAlgorithm() + runAlgorithm() ConcreteStrategy classes provide the implementations... 26 MuteQuack + quack() The Strategy Design Pattern The Strategy Design Pattern defines a family of algorithms, encapsulates each one, and makes them interchangeable Strategy lets the algorithms

Ngày đăng: 29/03/2021, 14:51

Mục lục

    A First Design for the Duck Simulator Game

    But now we need the ducks to fly…

    Yet Another Duck is Added to the Application

    How about an interface?

    What do you think?

    Change is a taste of life

    The Constitution of Software Architects

    Embracing Change in Ducks

    The Constitution of Software Architects

    Integrating the Duck Behavior