from Head first Design Patterns.
Design Principle:
Idnetify the aspects of your application that vary and separate them from what stays the same.
Here's another-to-think about it:
Take the parts. Vary and encapsulate them, so then later you can alter or extend the parts that vary without affecting Those that don ' t.
Simuduck App
We need to separate behaviors from Duck class. So, let's define-behavior interfaces: quackbehavior and flybehavior with additonal instantial classe S.
Design Principle
Program to a interface, not an implementation.
Quackbehavior interface and Instantial classes:
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");}}
Flybehavior interface and Instantial classes:
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");}}
And then, we can define the abstract class Duck, which are the base class of our Duck Project:
Public abstract class Duck {Quackbehavior quackbehavior; Flybehavior flybehavior;public Duck () {}public abstract void display ();p ublic void Performquack () {Quackbehavior.quack ( );} public void Performfly () {flybehavior.fly ();} public void Swim () {System.out.println ("All ducks float, even decoys!");}}
Now, we can make a concrete duck, mallard!
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");}}
Finally,let ' s write a simulator to test our codes:
public class Miniducksimulator {public static void main (string[] args) {Duck mallard = new Mallardduck (); mallard.performqu ACK (); Mallard.performfly (); Mallard.display ();}} /* output:quacki ' m flying!! I ' m a real mallard duck*/
Pay attention, the duck Mallard is offer for both apis:performquack (), Performfly (). We can ' t call Quack () or fly (), which also make the process of calling behaviors simple.
It's a shame to has all the dynamic talent built into we ducks and not being using it!
If you want to set duck ' s behavior now, you should make it through instantiating it in the Duck ' s constructor rat She than adding a setter method on the duck subclass.
Add new methods to the Duck class:
public void Setflybehavior (Flybehavior fb) {flybehavior = fb;} public void Setquackbehavior (Quackbehavior qb) {quackbehavior = QB;}
Let's make a new Duck type:
public class Modelduck extends Duck {public Modelduck () { quackbehavior = new Quack (); Flybehavior = new Flynoway (); } public void display () { System.out.println ("I ' m A model Duck");}}
Adding new Flybehavior Type:
public class Flyrocketpowered implements Flybehavior {public void Fly () { System.out.println ("I ' m flying with a Rocke T! ");}}
Now, we can add some codes in simulator to test our set methods:
Duck model = new Modelduck (); Model.performfly (); Model.setflybehavior (new flyrocketpowered ()); Model.performfly ();
Here, the model duck dynamically changed its flying behavior!
You can ' t does that if the implementation lives inside the duck class!
Design Principle
Favor composition over inheritance.
In this project, we use the stragegy pattern, the formal definition is:
The strategy Pattern defines a family of algorithms, encapsulates each one, and makes them interchangeable. Strategy lets the algorithm vary independently from clients.
Head First Design Patterns