zoukankan      html  css  js  c++  java
  • 设计模式策略模式

    策略模式

      定义算法族,分别封装起来,让它们之间可以互相替换,此模式让算法的变化独立于使用算法的客户。(虽然能理解意思,但真心记不住= =)

      策略模式其实不难,顾名思义就是更改策略(策略接口下的子类)。首先是需要一个策略接口:Strategy,可以有n个子类实现此接口;其次是

    拥有此接口对象(注意是接口对象,而不是任意的子类)的客户端,那么客户端可以在运行时根据需要选择策略(子类)。

      这样做的好处:

        1. 维护方便:若策略经常改变,则更换策略便是;若出现新策略,那么实现一个继承策略接口的子类便可。其实这都可以归结为针对接口编程带来的好处。

        2. 强大的组合:想象一下,若有n个策略接口,每个策略接口都有m个子类。客户端只要维护n个策略接口对象,在运行时更改具体子类,那么其组合效应             是非常惊人的,可以很方便的根据实际需要组装出各种接口组合。

      

      说了这么多,写一个例子:

      有这样一个场景:有3种鸭子(为毛是鸭子呢- -):小鸭、会飞的老鸭(这个更囧吧)、玩具鸭。它们具有两类行为:叫和飞。具体行为分配如下列表:

          quack   fly
       小鸭:  不会叫    不会飞
       老鸭:    嘎嘎叫      会飞
       橡皮鸭: 吱吱叫    不会飞

      一种常见的做法是:写一个Duck的抽象类,包括quack()和fly()方法(应当是抽象的,因为每种鸭子的行为不同),然后这三种鸭子继承Duck抽象类。这样做的问题:1. 代码无法复用。当两种鸭子的某一行为相同时,你只能去copy代码;当增加一种新鸭子时,也只能重写其行为。 2. 当鸭子的行为改变时,很显然只能修改源代码!这样不好嘛?好是好,可有没有想过运行时修改,而不用修改源代码呢!

      现在就用策略模式来改变这一现状吧:)

      1. FlyBehaviour接口及其两个子类CanFly和CantFly,分别代表“会飞”和“不会飞”。

    View Code
     1 package StrategyPattern;
     2 /*
     3  * 飞行接口
     4  */
     5 public interface FlyBehaviour {
     6     public void fly();
     7 }
     8 
     9 
    10 
    11 package StrategyPattern;
    12 
    13 public class CanFly implements FlyBehaviour {
    14 
    15     @Override
    16     public void fly() {
    17         // TODO Auto-generated method stub
    18         System.out.print("会飞");
    19     }
    20 
    21 }
    22 
    23 
    24 
    25 package StrategyPattern;
    26 
    27 public class CantFly implements FlyBehaviour {
    28 
    29     @Override
    30     public void fly() {
    31         // TODO Auto-generated method stub
    32         System.out.print("不会飞");
    33     }
    34 
    35 }

      2. QuackBehaviour接口及其三个子类NoQuack,GagaQuack和ZhizhiQuack,分别代表“不会叫”、“嘎嘎叫”、“吱吱叫”。

    View Code
     1 package StrategyPattern;
     2 /**
     3  * 叫行为。
     4  * @author Administrator
     5  *
     6  */
     7 public interface QuackBehaviour {
     8     public void quack();
     9 }
    10 
    11 
    12 package StrategyPattern;
    13 
    14 public class NoQuack implements QuackBehaviour {
    15 
    16     @Override
    17     public void quack() {
    18         // TODO Auto-generated method stub
    19         System.out.print("不会叫");
    20     }
    21 
    22 }
    23 
    24 package StrategyPattern;
    25 
    26 public class GagaQuack implements QuackBehaviour {
    27 
    28     @Override
    29     public void quack() {
    30         // TODO Auto-generated method stub
    31         System.out.print("嘎嘎叫");
    32     }
    33 
    34 }
    35 
    36 
    37 package StrategyPattern;
    38 
    39 public class ZhizhiQuack implements QuackBehaviour {
    40 
    41     @Override
    42     public void quack() {
    43         // TODO Auto-generated method stub
    44         System.out.print("吱吱叫");
    45     }
    46 
    47 }

      3. Duck抽象类,含有FlyBehaviour和QuackBehaviour的两个接口对象。及其三个子类,LittleDuck、OldDuck和RubbDuck。

    View Code
      1 package StrategyPattern;
      2 
      3 import java.awt.DisplayMode;
      4 
      5 /**
      6  * duck的抽象父类。
      7  * @author Administrator
      8  *
      9  */
     10 public abstract class Duck {
     11     
     12     FlyBehaviour flyBh;
     13     QuackBehaviour quackBh;
     14     
     15     public Duck(FlyBehaviour fly, QuackBehaviour quack) {
     16         this.flyBh = fly;
     17         this.quackBh = quack;
     18     }
     19     
     20     public void setFlyBehaviour(FlyBehaviour fly) {
     21         this.flyBh = fly;
     22     }
     23     
     24     public void setQuackBehaviour(QuackBehaviour quack) {
     25         this.quackBh = quack;
     26     }
     27     
     28     public void performFly() {
     29         flyBh.fly();
     30     }
     31     
     32     public void peformQuack() {
     33         quackBh.quack();
     34     }
     35     
     36     public abstract void display();
     37     
     38 }
     39 
     40 
     41 
     42 package StrategyPattern;
     43 
     44 public class LittleDuck extends Duck {
     45 
     46     public LittleDuck(FlyBehaviour fly, QuackBehaviour quack) {
     47         super(fly, quack);
     48         // TODO Auto-generated constructor stub
     49     }
     50 
     51     @Override
     52     public void display() {
     53         // TODO Auto-generated method stub
     54         System.out.println();
     55         System.out.print("小鸭");
     56         peformQuack();
     57         performFly();
     58     }
     59 
     60 }
     61 
     62 
     63 
     64 package StrategyPattern;
     65 
     66 public class OldDuck extends Duck {
     67 
     68     public OldDuck(FlyBehaviour fly, QuackBehaviour quack) {
     69         super(fly, quack);
     70         // TODO Auto-generated constructor stub
     71     }
     72 
     73     @Override
     74     public void display() {
     75         // TODO Auto-generated method stub
     76         System.out.println();
     77         System.out.print("老鸭");
     78         peformQuack();
     79         performFly();
     80     }
     81 
     82 }
     83 
     84 
     85 
     86 
     87 package StrategyPattern;
     88 
     89 public class RubbDuck extends Duck {
     90 
     91     public RubbDuck(FlyBehaviour fly, QuackBehaviour quack) {
     92         super(fly, quack);
     93         // TODO Auto-generated constructor stub
     94     }
     95 
     96     @Override
     97     public void display() {
     98         // TODO Auto-generated method stub
     99         System.out.println();
    100         System.out.print("橡皮鸭");
    101         peformQuack();
    102         performFly();
    103     }
    104 
    105 }

      最后,看看效果吧:

    View Code
    1     public static void main(String[] args) {
    2         // TODO Auto-generated method stub
    3         Duck littleDuck = new LittleDuck(new CantFly(), new NoQuack());
    4         Duck oldDuck = new OldDuck(new CanFly(), new GagaQuack());
    5         Duck rubbDuck = new RubbDuck(new CantFly(), new ZhizhiQuack());
    6         littleDuck.display();
    7         oldDuck.display();
    8         rubbDuck.display();
    9     }

    运行结果:

    小鸭不会叫不会飞
    老鸭嘎嘎叫会飞
    橡皮鸭吱吱叫不会飞

      

  • 相关阅读:
    redis 笔记04 服务器、复制
    redis 笔记03 RDB 持久化、AOF持久化、事件、客户端
    redis 笔记02 对象、数据库
    反射复习笔记02
    攻防世界 — Web进阶题(第11
    机器学习-极大似然和对数几率回归(浅入)
    redis的过期策略和内存淘汰
    Backbone.Router实践
    Spring Boot 数据访问
    Archives: 2018/12
  • 原文地址:https://www.cnblogs.com/forstudy/p/2735460.html
Copyright © 2011-2022 走看看