• HeadFirst设计模式学习笔记(C#版):鸭子与策略(Strategy)模式


     策略模式的设计原则如下:

        1.  将应用中需要经常变化的代码独立出来,应和那些不需要经常变化的代码分开。

        2.  应针对接口,而不是类进行编程。

        3.  在类中应多用组合,少用继承。

        例子:

        我们要实现一个鸭子模拟器,这个鸭子模拟器由Duck类描述,而Duck类有如下4个行为:

        1.  display

        2.  swim

        3.  fly(飞)

        4.  quack(叫)

        其中swim是所有鸭子都具有的特性,而且所有鸭子的这些特性都相同,因此,这个方法可以直接在Duck类中实现。display方法也是所有鸭子具有的特性,但随着鸭子的种类不同,display也有所不同,因此,display方法应为Duck类的抽象方法。fly和quack并不是所有鸭子的特性,如橡皮鸭子即不会飞,也不会叫。因此,可以将这两个方法看作是两个行为,可将每一个行为设计成一个接口。这样可以和Duck类完全脱离。因为,fly和quack与Duck一点关系都没有(别的东西也可能fly和quack),然后不同的fly和quack分别用实现相应接口的类表示。

        下面是关于Duck的完整代码:

    fly行为

        //  飞行接口
        public interface FlyBehavior
        {
            String fly();
        }

        
    //  飞
        public class FlyWithWing : FlyBehavior
        {
            
    public String fly()
            {
                
    return "正在用翅膀飞行";
            }
        }

        
    //  不飞
        public class FlyNoWay : FlyBehavior
        {
            
    public String fly()
            {
                
    return "不会飞";
            }
        }


     quack行为

        //  叫
        public interface QuackBehavior
        {
            String quack();
        }
        
    // 嘎嘎叫
        public class Quack : QuackBehavior
        {
            
    public String quack()
            {
                
    return "嘎嘎叫";
            }
        }

        
    //  吱吱叫
        public class Squeak : QuackBehavior
        {
            
    public String quack()
            {
                
    return "吱吱叫";
            }
        }

        
    //  不叫
        public class MuteQuack : QuackBehavior
        {
            
    public String quack()
            {
                
    return "不会叫";
            }
        }


    实现Duck类

        //  鸭子超类
        public abstract class Duck
        {
            
    protected FlyBehavior flyBehavior;
            
    protected QuackBehavior quackBehavior;

            
    public Duck()
            {
                
    //  默认的行为
                flyBehavior = new FlyWithWing();
                quackBehavior 
    = new Quack();
            }
            
    public String swim()
            {
                
    return "正在游泳";
            }
            
    public String performFly()
            {
                
    return flyBehavior.fly();
            }
            
    public String performQuack()
            {
                
    return quackBehavior.quack();
            }
            
    public void setFlyBehavior(FlyBehavior flyBehavior)
            {
                
    this.flyBehavior = flyBehavior;
            }
            
    public void setQuackBehavior(QuackBehavior quackBehavior)
            {
                
    this.quackBehavior = quackBehavior;
            }
            
    public abstract String display();
        }


    建立不同的鸭子类

        //  野鸭
        public class MallardDuck : Duck
        {
            
    public override String display()
            {
                
    return "绿头鸭";
            }
        }

        
    //  红头鸭
        public class RedHeadDuck : Duck
        {
            
    public override String display()
            {
                
    return "红头鸭";
            }
        }

        
    //  橡皮鸭
        public class RubberDuck : Duck
        {
            
    public override String display()
            {
                
    return "橡皮鸭";
            }
        }


    接口与类的关系如下图

     

    调用代码如下:

    private void printMsg(Duck duck)
    {
        txtMsg.AppendText(duck.display());
        txtMsg.AppendText(duck.performFly());            
        txtMsg.AppendText(duck.performQuack());
    }
    private void btnStrategy_Click(object sender, EventArgs e)
    {
        txtMsg.Clear();

        Duck duck 
    = new MallardDuck();
        printMsg(duck);
        txtMsg.AppendText(
    "\r\n");

        duck 
    = new RedHeadDuck();
        duck.setQuackBehavior(
    new Squeak());
        printMsg(duck);
        txtMsg.AppendText(
    "\r\n");

        duck 
    = new RubberDuck();
        duck.setFlyBehavior(
    new FlyNoWay());
        duck.setQuackBehavior(
    new MuteQuack());
        printMsg(duck);
        txtMsg.AppendText(duck.swim());
        txtMsg.AppendText(
    "\r\n");
    }


    输出结果如下:

    绿头鸭正在用翅膀飞行嘎嘎叫
    红头鸭正在用翅膀飞行吱吱叫
    橡皮鸭不会飞不会叫正在游泳
    http://www.cnblogs.com/nokiaguy/archive/2009/02/11/1388168.html
  • 相关阅读:
    SqQueue(环状队列(顺序表结构))
    LinkQueue(链队列)
    CharMatch(括号匹配)
    LinkStack
    x-boot
    安装npm及cnpm(Windows)
    sourcetree跳过注册的方法
    Mysql 5.7 CentOS 7 安装MHA
    ORA-12519 ORA-12516
    lisp : set 与setq 函数
  • 原文地址:https://www.cnblogs.com/binlyzhuo/p/1419722.html
Copyright © 2020-2023  润新知