bim492 design atterns - eskisehir.edu.trceng.eskisehir.edu.tr/abilge/bim492/icerik/01 - strategy...

30
01. S TRATEGY PATTERN Someone has already solved your problems. DESIGN PATTERNS BIM492

Upload: others

Post on 05-Sep-2020

0 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: BIM492 DESIGN ATTERNS - eskisehir.edu.trceng.eskisehir.edu.tr/abilge/BIM492/icerik/01 - Strategy Pattern.pdf · You are the designer of a highly successful duck pond simulation game,

01. STRATEGY PATTERN

Someone has already solved your problems.

DESIGN PATTERNSBIM492

Page 2: BIM492 DESIGN ATTERNS - eskisehir.edu.trceng.eskisehir.edu.tr/abilge/BIM492/icerik/01 - Strategy Pattern.pdf · You are the designer of a highly successful duck pond simulation game,

2

▪ You are the designer of a highly successful duck pond simulation game, SimUDuck.

▪ Initial designers of the simulator used standard OO techniques and created one Ducksuperclass from which all other duck types inherit.

It started with a simple SimUDuck app

Company executives think it’s time for a big innovation to show at the upcoming fair.

Page 3: BIM492 DESIGN ATTERNS - eskisehir.edu.trceng.eskisehir.edu.tr/abilge/BIM492/icerik/01 - Strategy Pattern.pdf · You are the designer of a highly successful duck pond simulation game,

3

But now we need the ducks to FLYThe executives decided that flying ducks is just what thesimulator needs to blow away other duck sim competitors. And your manager told it’ll be no problem.

▪ After all you are an OO programmer, how hard it can be?

Page 4: BIM492 DESIGN ATTERNS - eskisehir.edu.trceng.eskisehir.edu.tr/abilge/BIM492/icerik/01 - Strategy Pattern.pdf · You are the designer of a highly successful duck pond simulation game,

4

But something went horribly wrong…What happened?- Failed to notice that not all subclasses of Duck fly- Behavior is added to Duck superclass which is not appropriate forsome Duck subclasses- A localized update to the code caused a non-local side effect(flying rubber ducks)!

Page 5: BIM492 DESIGN ATTERNS - eskisehir.edu.trceng.eskisehir.edu.tr/abilge/BIM492/icerik/01 - Strategy Pattern.pdf · You are the designer of a highly successful duck pond simulation game,

5

Let’s think about inheritance…

Sharpen your pencilWhich of the following are disadvantages of using inheritance to provide Duck behavior? (choose all that apply)A. Code is duplicated across subclasses.B. Runtime behavior changes are difficultC. We can’t make ducks dance.D. Hard to gain knowledge of all duck

behaviors.E. Ducks can’t fly and quack at the same

time.F. Changes can unintentionally affect other

ducks.

Page 6: BIM492 DESIGN ATTERNS - eskisehir.edu.trceng.eskisehir.edu.tr/abilge/BIM492/icerik/01 - Strategy Pattern.pdf · You are the designer of a highly successful duck pond simulation game,

6

How about an interface?▪ Inheritance probably wasn’t the answer

▪ Because execs now want to update the product every six months (in ways that haven’t decided yet).

▪Will need to override fly() and quack() for every new Duck subclass

▪ Need a cleaner way to have only some (but not all) of the duck types fly or quack

What do YOU think of thisdesign?

Page 7: BIM492 DESIGN ATTERNS - eskisehir.edu.trceng.eskisehir.edu.tr/abilge/BIM492/icerik/01 - Strategy Pattern.pdf · You are the designer of a highly successful duck pond simulation game,

7

What would you do instead?

▪ Not all subclasses should have flying or quacking behavior, so inheritance isn’t the right answer

▪ Having subclasses implement Flyableand/or Quackable partly solves the problem, but it destroys code reuse▪ A different maintenance nightmare!▪ Also there might be more than one kind of flying

behavior among ducks that do fly

▪ Let’s figure out a solution the old-fashioned-way▪ by applying good OO software design principles

Page 8: BIM492 DESIGN ATTERNS - eskisehir.edu.trceng.eskisehir.edu.tr/abilge/BIM492/icerik/01 - Strategy Pattern.pdf · You are the designer of a highly successful duck pond simulation game,

8

The one constant in software development

Okay, what’s the one thing you can always count on in software development?▪ No matter where you work, what you’re building, or what language you programming in, what’s

one true constant that will be always with you?

▪ No matter how well you design an application, over time an application must grow and change or it will die.

Page 9: BIM492 DESIGN ATTERNS - eskisehir.edu.trceng.eskisehir.edu.tr/abilge/BIM492/icerik/01 - Strategy Pattern.pdf · You are the designer of a highly successful duck pond simulation game,

9

Zeroing in on the problem…• Using inheritance hasn’t worked out well

• Duck behavior keeps changing across subclasses

• Flyable and Quackable interface sounded promising at first• Except Java interfaces have no implementation code, no code reuse!• Whenever you need a modification, you need to track down in all

different subclasses

• As simple as it is, • It forms the basis for almost every design pattern• All patterns provide a way to let some part of a system vary

independently of all other parts

Page 10: BIM492 DESIGN ATTERNS - eskisehir.edu.trceng.eskisehir.edu.tr/abilge/BIM492/icerik/01 - Strategy Pattern.pdf · You are the designer of a highly successful duck pond simulation game,

10

Separating what changes from what stays the same

▪ fly() and quack() arethe parts of the Duckclass that vary acrossducks.

▪ To separate thesebehaviors, let’s pull bothmethods out of the Duckclass and create new set of classes to representeach behavior

Page 11: BIM492 DESIGN ATTERNS - eskisehir.edu.trceng.eskisehir.edu.tr/abilge/BIM492/icerik/01 - Strategy Pattern.pdf · You are the designer of a highly successful duck pond simulation game,

11

Designing the Duck behaviors

• We’d like to keep things flexible.• Assign behaviors to instances of Duck

• e.g., instantiate a new MallardDuck instance and initialize with a specific type of flying behavior

• Use an interface to represent each behavior, FlyBehavior and QuackBehavior• Each implementation of a behavior will implement one of those interfaces• Make sets of classes whose entire reason for living is to represent a behavior

(e.g., squeaking), and it is the Behavior class rather than the Duck class, thatwill implement the behavior interface

YOUR TURNNow, explain how we did achieve

programming to an interface ratheran implementation in this example?

Page 12: BIM492 DESIGN ATTERNS - eskisehir.edu.trceng.eskisehir.edu.tr/abilge/BIM492/icerik/01 - Strategy Pattern.pdf · You are the designer of a highly successful duck pond simulation game,

12

<Program to an interface> really means <Program to a supertype>▪ The word interface is overloaded here.

▪ There’s the concept of interface, but there’s also java construct interface

▪ You can program to an interface, without using Java interface▪ using an abstract class or interface – supertype (exploit polymorphism)

Programming to an implementation would be:

But programming to an interface/supertype would be:

Even better, rather than hard-coding the instantiation of the subtype (like new Dog()), assign concrete implementation object at runtime:

Page 13: BIM492 DESIGN ATTERNS - eskisehir.edu.trceng.eskisehir.edu.tr/abilge/BIM492/icerik/01 - Strategy Pattern.pdf · You are the designer of a highly successful duck pond simulation game,

13

Implementing the Duck BehaviorsWith this design, other types of objects can reuse our fly and quack behaviors because they are no longer hidden away in our Duck class!

And we can add new behaviors without modifying any of our existing behavior classes or touching any of Duck classes that use flying behaviors

Page 14: BIM492 DESIGN ATTERNS - eskisehir.edu.trceng.eskisehir.edu.tr/abilge/BIM492/icerik/01 - Strategy Pattern.pdf · You are the designer of a highly successful duck pond simulation game,

14

Q: Do I always have to implement my application first, see where things are changing, and then go back and separate & encapsulate them?

A: Not always; often when you are designing an application you anticipate that might vary. Principles and patterns can be applied at any stage of development cycle.

Q: Should we make Duck an interface too?

A: Not in this case. We’ve got everything hooked together, we do benefit by having Duck be aconcrete class and having specific ducks, like MallardDuck, inherit common properties and methods.

there are noDumb QuestionsQ: It feels weird to have a class that’s just a behavior. Aren’t classes supposed to representthings? Aren’t classes supposed to have bothstate AND behavior?

A: In an OO system, yes, classes represent thingsthat generally have both state (instance variables) and Methods. Here, the thing happens to be a behavior. But even a behavior can still have stateand methods; a flying behavior might have instancevariables representing attributes (beats perminute, max altitude and speed, etc.) for flyingbehavior.

Page 15: BIM492 DESIGN ATTERNS - eskisehir.edu.trceng.eskisehir.edu.tr/abilge/BIM492/icerik/01 - Strategy Pattern.pdf · You are the designer of a highly successful duck pond simulation game,

15

Sharpen your pencil

1. Using our new design, what would you do if you needed to addrocket-powered flying to the SimUDuck app?

2. Can you think of a class that might want to use the Quackbehavior that isn’t a duck?

Create a FlyRocketPowered classthat implements the FlyBehaviorinterface.

One example, a duck call (a device that makes duck sounds).Another example is a charlatan or a mountebank person [check out here].

Page 16: BIM492 DESIGN ATTERNS - eskisehir.edu.trceng.eskisehir.edu.tr/abilge/BIM492/icerik/01 - Strategy Pattern.pdf · You are the designer of a highly successful duck pond simulation game,

16

The key is that a Duck will now delegate its flying and quacking behavior, instead of usingquacking and flying methods defined in the Duck class (or subclass).

Integrating the Duck Behavior

3. Now implement performQuack()

1. Add two instance variables to theDuck class called flyBehaviorand quackBehavior declared as interface type. Each duck object willset these variables polymorphicallyto reference specific type it wouldlike at runtime (FlyWithWings, Squeak, etc.).

2. Also replace fly() and quack() in the Duck classwith performFly() and performQuack().

Page 17: BIM492 DESIGN ATTERNS - eskisehir.edu.trceng.eskisehir.edu.tr/abilge/BIM492/icerik/01 - Strategy Pattern.pdf · You are the designer of a highly successful duck pond simulation game,

17

More integration…4. How the flyBehavior and quackBehavior instance variables are set.

▪ So MallardDuck’s quack is a real live duck quack, not a squeak and not a mute quack.

▪ When a MallardDuck is instantiated, its constructor initializes the MallardDuck’s inherited "quackBehavior" instance variable to a new instance of type Quack (a QuackBehavior concrete implementation class).

▪ And the same with the flying behavior.

public class MallardDuck extends Duck { public MallardDuck() { quackBehavior = new Quack(); flyBehavior = new FlyWithWings();

}

public void display() { System.out.println(“I’m a real Mallard duck”);

} }

Page 18: BIM492 DESIGN ATTERNS - eskisehir.edu.trceng.eskisehir.edu.tr/abilge/BIM492/icerik/01 - Strategy Pattern.pdf · You are the designer of a highly successful duck pond simulation game,

18

▪ Good catch, yes we do, just for now.

▪ We’ll fix it later with other Design Patterns.

▪ Still, we are setting the behaviorsto concrete classes that we couldeasily change at runtime (throughmagic of polymorphism)

Take a moment and think about how youwould implement a duck so that its behaviorcould change at runtime.

?

Page 19: BIM492 DESIGN ATTERNS - eskisehir.edu.trceng.eskisehir.edu.tr/abilge/BIM492/icerik/01 - Strategy Pattern.pdf · You are the designer of a highly successful duck pond simulation game,

19

Testing the Duck codeDuck.java - also consider MallardDuck.java

FlyBehavior.java FlyWithWings.java FlyNoWay.javapublic abstract class Duck { FlyBehavior flyBehavior; QuackBehavior quackBehavior; public Duck() { }

public abstract void display();

public void performFly() { flyBehavior.fly();

}

public void performQuack() { quackBehavior.quack();

}

public void swim() { System.out.println(“All ducks float, even decoys!”);

} }

public interface FlyBehavior { public void fly();

}

public class FlyWithWings implements FlyBehavior { public void fly() { System.out.println(“I’m flying!!”);

} }

public class FlyNoWay implements FlyBehavior { public void fly() { System.out.println(“I can’t fly”);

} }

Page 20: BIM492 DESIGN ATTERNS - eskisehir.edu.trceng.eskisehir.edu.tr/abilge/BIM492/icerik/01 - Strategy Pattern.pdf · You are the designer of a highly successful duck pond simulation game,

20

Testing the Duck code continued…Quack Behavior interface QuackBehavior.java, Quack.java, MuteQuack.java, and Squeak.java

MiniDuckSimulator.java

Run the code

public interface QuackBehavior { public void quack();

}

public class Quack implements QuackBehavior { public void quack() { System.out.println(“Quack”);

} }

public class MuteQuack implements QuackBehavior { public void quack() { System.out.println(“<< Silence >>”);

} }

public class Squeak implements QuackBehavior { public void quack() { System.out.println(“Squeak”);

} }

public class MiniDuckSimulator { public static void main(String[] args) { Duck mallard = new MallardDuck(); mallard.performQuack(); mallard.performFly();

} }

Page 21: BIM492 DESIGN ATTERNS - eskisehir.edu.trceng.eskisehir.edu.tr/abilge/BIM492/icerik/01 - Strategy Pattern.pdf · You are the designer of a highly successful duck pond simulation game,

21

Setting behavior dynamically

1. Add two new methods to the Duck Class

We can call these methods anytime we want to change the behavior of a duck on the fly

2. Make a new Duck type (ModelDuck.java)

3. Make a new FlyBehavior type(FlyRocketPowered.java)

public void setFlyBehavior(FlyBehavior fb) { flyBehavior = fb;

} public void setQuackBehavior(QuackBehavior qb) { quackBehavior = qb;

}

public class ModelDuck extends Duck { public ModelDuck() { flyBehavior = new FlyNoWay(); quackBehavior = new Quack();

} public void display() { System.out.println(“I’m a model duck”);

} }

public class FlyRocketPowered implements FlyBehavior { public void fly() {

System.out.println(“I’m flying with a rocket!”); }

}

Page 22: BIM492 DESIGN ATTERNS - eskisehir.edu.trceng.eskisehir.edu.tr/abilge/BIM492/icerik/01 - Strategy Pattern.pdf · You are the designer of a highly successful duck pond simulation game,

22

4. Change the test class, add ModelDuck and make ModelDuck rocket-enabled, and run it!

Page 23: BIM492 DESIGN ATTERNS - eskisehir.edu.trceng.eskisehir.edu.tr/abilge/BIM492/icerik/01 - Strategy Pattern.pdf · You are the designer of a highly successful duck pond simulation game,

23

The Big Picture on encapsulated behaviors

Pay careful attention tothe relationships.

Now assign rightrelations to theappropriate arrows(IS-A, HAS-A andIMPLEMENTS)

Page 24: BIM492 DESIGN ATTERNS - eskisehir.edu.trceng.eskisehir.edu.tr/abilge/BIM492/icerik/01 - Strategy Pattern.pdf · You are the designer of a highly successful duck pond simulation game,

24

HAS-A can be better than IS-A

▪ The HAS-A relationship is interesting: each duck has a FlyBehavior and a QuackBehavior to which it delegates flying and quacking.

▪When you put two classes together you’re using composition.

▪ Instead of inheriting their behavior, the ducks get their behavior by composed with the right behavior object

▪ Creating systems using composition gives a lot flexibility.

▪ Not only encapsulating a family of algorithms into their own set of classes, but also letting change behavior at runtime

▪ Composition is used in many design patterns and you’ll see a lot more about its advantages and disadvantages

Page 25: BIM492 DESIGN ATTERNS - eskisehir.edu.trceng.eskisehir.edu.tr/abilge/BIM492/icerik/01 - Strategy Pattern.pdf · You are the designer of a highly successful duck pond simulation game,

25

Speaking of Design Patterns

▪ You just applied a pattern – STRATEGY pattern.

▪ You used Strategy Pattern to rework the SimUDuckapp. Thanks to this pattern, the simulator is ready for any changes those execs might cook up on their next business trip.

▪ Here is the formal definition.

Page 26: BIM492 DESIGN ATTERNS - eskisehir.edu.trceng.eskisehir.edu.tr/abilge/BIM492/icerik/01 - Strategy Pattern.pdf · You are the designer of a highly successful duck pond simulation game,

26

Overheards

• What is the difference between these two orders? Not a thing!

• What’s Flo got that Alice doesn’t is a shared vocabulary.

• Easier to communicate with the cook and gives cook less to remember, because he’s got all dinner patterns.

Design patterns give you a shared vocabulary which elevates your thinking about architecture by letting you think at the pattern level, not the nitty gritty objectlevel.

Page 27: BIM492 DESIGN ATTERNS - eskisehir.edu.trceng.eskisehir.edu.tr/abilge/BIM492/icerik/01 - Strategy Pattern.pdf · You are the designer of a highly successful duck pond simulation game,

27

When you communicate using patterns you are doing more than just sharing LINGO.✓ Shared pattern vocabularies are POWERFUL

✓Not just pattern name but a whole set of qualities, characteristics and constraints

✓Patterns allow you to say more with less

✓Talking at the pattern level allows you to stay «in the design» longer✓Discuss at the design level not implementation

✓Shared vocabularies can turbo charge your team✓Move more quickly with less misunderstanding

✓Shared vocabularies encourage junior developers to get up to speed✓Seniors shall motivate juniors

The power of a shared vocabulary

Page 28: BIM492 DESIGN ATTERNS - eskisehir.edu.trceng.eskisehir.edu.tr/abilge/BIM492/icerik/01 - Strategy Pattern.pdf · You are the designer of a highly successful duck pond simulation game,

28

How do I use Design Patterns?▪ Think of off-the-shelf libraries and frameworks.

▪ Java APIs and all the functionality they give you: network, GUI, IO, etc.

THEY DON'T HELP STRUCTURING YOUR CODE

Design patterns don’t go directly into your

code, they first go into your BRAIN.

Page 29: BIM492 DESIGN ATTERNS - eskisehir.edu.trceng.eskisehir.edu.tr/abilge/BIM492/icerik/01 - Strategy Pattern.pdf · You are the designer of a highly successful duck pond simulation game,

29

Q: If design patterns are so great, why can’t someone build a library of them so I don’t have to?

A: Design patterns are higher level than libraries. Design patterns tell us how to structure classes and objects to solve certain problems and it is our job to adapt those designs to fit our particularapplication.

there are noDumb Questions

Q: So, there are no libraries of design patterns?

A: No, but you will learn later aboutpattern catalogs with lists of patterns thatyou can apply to your applications.

Q: Aren’t libraries and frameworks also design patterns?A: Frameworks and libraries are not design patterns; they provide specific implementations that we link into our code. Sometimes, however, libraries andframeworks make use of design patterns in their implementations. That’s great, because once you understand design patterns, you’ll more quicklyunderstand APIs that are structured around design patterns.

Page 30: BIM492 DESIGN ATTERNS - eskisehir.edu.trceng.eskisehir.edu.tr/abilge/BIM492/icerik/01 - Strategy Pattern.pdf · You are the designer of a highly successful duck pond simulation game,

30

Tools for your Design ToolboxLet’s look at the tools you’ve put in your OO toolbox.Bullet Points▪ Knowing the OO basics does not make you a good

OO designer▪ Good OO designs are reusable, extensible and

maintainable▪ Patterns are proven OO experience▪ Patterns don’t give you code, they give you general

solutions to design problems.▪ Patterns aren’t invented, they are discovered▪ Most patterns and principles

▪ address issues of change in software▪ allow some part of a system vary independently