以下内容转载请注明来自"菩提树下的杨过(http://blog.sqlsky.com)"
 
把书中开篇duck问题的代码翻译成了c#版:

概述:
某游戏公司要设计一款鸭子的游戏,里面有各种各样的鸭子,有些会飞,有些会叫,但都会游泳。而且不同种类的鸭子,飞行方式和叫唤的方式各不相同

以下代码体现了二个oo原则:
1.找出应用中可能需要变化之外,把它们独立出来,不要和那些不需要变化的代码混在一起
2.针对接口编程,而不是针对实现编程

Duck抽象类:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace duck
{
    /**//// <summary>
    /// 鸭子的抽象类
    /// </summary>
    public abstract class Duck
    {
        //注:以下二个变量,当然可以做成属性,但是从oo的角度考虑,这二个是代表duck的具体行为的,还是用实例变量比较恰当
        protected FlyBehavior flyBehavior = null;
        protected QuackBehavior quackBehavior = null;

        /**//// <summary>
        /// 开始叫唤
        /// </summary>
        public void StartQuack() 
        {
            quackBehavior.Quack();
        }

        /**//// <summary>
        /// 开始飞行 
        /// </summary>
        public void StartFly()
        {
            flyBehavior.Fly();
        }

        /**//// <summary>
        /// 游泳(所有的鸭子都会swim)
        /// </summary>
        public void Swim() 
        {
            Console.WriteLine("All the ducks can swim.");
        }

        /**//// <summary>
        /// 抽象方法(返回具体鸭子的描述)
        /// </summary>
        public abstract void Display();
    }
}

飞行行为接口:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace duck
{
    /**//// <summary>
    /// 飞行行为接口
    /// </summary>
    public interface FlyBehavior
    {
        /**//// <summary>
        /// Fly方法,必须由实现该接口的类实现
        /// </summary>
        void Fly(); 
        
    }
}

叫唤行为接口:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace duck
{
    /**//// <summary>
    /// "叫"行为接口
    /// </summary>
    public interface QuackBehavior
    {
        void Quack();
       
    }
}

几种不同飞行方式类:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace duck
{
    /**//// <summary>
    /// "用翅膀飞"类(普通鸭子的飞行行为)
    /// </summary>
    public class FlyWithWings:FlyBehavior
    {
        public void Fly() 
        {
            Console.WriteLine("I can fly with wing.");
        }
    }
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace duck
{
    /**//// <summary>
    /// "不会飞"类(橡皮鸭,模型鸭的飞行行为)
    /// </summary>
    public class FlyNoWay:FlyBehavior
    {
        public void Fly() 
        {
            Console.WriteLine("Don't be fool! I can't fly.");
        }
    }
}

几种不同方式的叫唤类:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace duck
{
    /**//// <summary>
    /// "呱呱叫"类(普通鸭子的quack行为)
    /// </summary>
    public class NormalQuack:QuackBehavior
    {
        public void Quack() 
        {
            Console.WriteLine("ga ga ga ");
        }
    }
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace duck
{
    /**//// <summary>
    /// "吱吱叫"类(橡皮鸭子的quack行为)
    /// </summary>
    public class Squeak:QuackBehavior
    {
        public void Quack() 
        {
            Console.WriteLine("zhi zhi zhi ");
        }
    }
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace duck
{
    /**//// <summary>
    /// "不会叫"类(模型鸭专用)
    /// </summary>
    public class Mute:QuackBehavior
    {
        public void Quack() 
        {
            Console.WriteLine("I can't make sound");
        }
    }
}

几种不同类型的鸭子类

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace duck
{
    /**//// <summary>
    /// 红头鸭,会用翅膀飞,会呱呱叫
    /// </summary>
    public class RedHeadDuck:Duck
    {
        public RedHeadDuck() 
        {
            this.flyBehavior = new FlyWithWings();
            this.quackBehavior = new NormalQuack();           
            
        }

        public override void Display()
        {
            Console.WriteLine("I am a real red-head-duck.");
        }
    }
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace duck
{
    /**//// <summary>
    /// 模型鸭子,不会飞,不会叫
    /// </summary>
    public class ModelDuck:Duck
    {
        public ModelDuck() 
        {
            this.flyBehavior = new FlyNoWay();
            this.quackBehavior = new Mute();
        }

        public override void Display()
        {
            Console.WriteLine("I am a mute duck.I cannot fly and quack.");
        }

        /**//// <summary>
        /// 允许模型鸭在运行时动态改变飞行行为(这里本人修改了下,原文中把这个方法放到了Duck抽象类中,即允许所有鸭子都可以动态修改飞行方式,但有可能出现橡皮鸭改变为能用翅膀飞的尴尬,呵呵)
        /// </summary>
        /// <param name="fb"></param>
        public void SetFlyBehavior(FlyBehavior fb)
        {
            this.flyBehavior = fb;
        }

    }
}

最终测试:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace duck
{
    class Program
    {
        static void Main(string[] args)
        {
            RedHeadDuck _redDuck = new RedHeadDuck();
            _redDuck.Display();//I am a real red-head-duck.
            _redDuck.StartFly();//I can fly with wing.
            _redDuck.StartQuack();//ga ga ga 

            Console.WriteLine();

            ModelDuck _modelDuck = new ModelDuck();
            _modelDuck.Display();//I am a mute duck.I cannot fly and quack.
            _modelDuck.StartFly();//Don't be fool! I can't fly.
            _modelDuck.StartQuack();//I can't make sound


            Console.WriteLine();
            _modelDuck.SetFlyBehavior(new FlyWithWings());//动态改变模型鸭子的飞行行为特性
            _modelDuck.StartFly();//I can fly with wing.

            Console.ReadLine();

        }
    }
}

菩提树下的杨过 2008-05-08 22:37:24 整理于上海

转载于:https://www.cnblogs.com/yjmyzz/archive/2008/05/08/1189044.html

(Head First 设计模式)学习笔记(1)相关推荐

  1. 7 种 Javascript 常用设计模式学习笔记

    7 种 Javascript 常用设计模式学习笔记 由于 JS 或者前端的场景限制,并不是 23 种设计模式都常用. 有的是没有使用场景,有的模式使用场景非常少,所以只是列举 7 个常见的模式 本文的 ...

  2. java/android 设计模式学习笔记(1)--- 单例模式

    前段时间公司一些同事在讨论单例模式(我是最渣的一个,都插不上嘴 T__T ),这个模式使用的频率很高,也可能是很多人最熟悉的设计模式,当然单例模式也算是最简单的设计模式之一吧,简单归简单,但是在实际使 ...

  3. 设计模式学习笔记清单

    设计模式学习笔记清单 关于设计模式许多人已经耳熟能详,这段时间结合李建忠的教学视频以及大量网络资料,把这部分过了一遍,整理出学习笔记,而真正的深入学习和理解只能在具体的开发环境中日积月累.      ...

  4. 步步为营 .NET 设计模式学习笔记系列总结

    设计模式我从开篇到23种设计模式的讲解总共花了进两个月的时间,其间有很多读者给我提出了很好的建议,同时也指出了我的不足,对此我表示感谢,正是由于很多读者的支持我才能坚持的写到最后.在此表示我真诚的谢意 ...

  5. 设计模式学习笔记--Strategy 策略模式

    所谓策略模式(Strategy Pattern),就是将策略 (算法) 封装为一个对象,易于相互替换,如同 USB 设备一样可即插即用:如果将策略.具体的算法和行为,编码在某个类或客户程序内部,将导至 ...

  6. 设计模式学习笔记--Mediator 中介者模式

    我们知道面向对象应用程序是由一组为了提供某种服务而彼此交互的对象组成.当彼此引用的对象数量比较少时,此时对象之间就为直接交互(点对点).而当对象的数量增加时,这种直接交互会导致对象之间复杂的.混乱的引 ...

  7. 设计模式学习笔记(十七)——Command命令模式

    设计模式学习笔记(十七)--Command命令模式 Command命令模式介绍: Command命令模式是一种对象行为型模式,它主要解决的问题是:在软件构建过程中,"行为请求者"与 ...

  8. 设计模式学习笔记——解释器(Interpreter)模式

    设计模式学习笔记--解释器(Interpreter)模式 @(设计模式)[设计模式, 解释器模式, Interpreter] 设计模式学习笔记解释器Interpreter模式 基本介绍 解释器案例 类 ...

  9. 设计模式学习笔记——命令(Command)模式

    设计模式学习笔记--命令(Command)模式 @(设计模式)[设计模式, 命令模式, command] 设计模式学习笔记命令Command模式 基本介绍 命令案例 类图 实现代码 Command接口 ...

  10. 设计模式学习笔记——代理(Proxy)模式

    设计模式学习笔记--代理(Proxy)模式 @(设计模式)[设计模式, 代理模式, proxy] 设计模式学习笔记代理Proxy模式 基本介绍 代理案例 类图 实现代码 Printable接口 Pri ...

最新文章

  1. Dynamic AX ERP 4.0 数据导出(上)
  2. Scala方法定义及调用
  3. Python——制作深度学习数据集批量重命名图片文件名解决方案
  4. Android_安卓为按钮控件绑定事件的五种方式
  5. NET主流ORM框架分析
  6. php中的css类怎么查找,CSS 样式表中的类和伪类
  7. Android动画效果
  8. redis存储对象_redis内存优化总结
  9. 5. 学习集合与常用类
  10. 部署http+svn,yum安装svn 1.9版本
  11. android怎么改名字,手把手教你如何修改安卓软件的图标和名字
  12. linux 有道 离线词典,有道词典离线版
  13. fiddler+xpose_JustTrustMe: 解决app应用在开启抓包工具后无法联网问题
  14. RPM命令详解(安装、升级、卸载)
  15. 出生年分数 15作者 陈越单位 浙江大学
  16. 优雅地使用ffmpeg转换音频格式
  17. 【每日一读】Efficient Personalized PageRank Computation: A Spanning Forests Sampling Based Approach
  18. 智能电脑监控器,完美解决想监控别人在自己电脑上的一切操作。
  19. 微信公众号打开的h5网页点击按钮返回公众号
  20. C语言768kb未压缩图片,若一幅图像的量化字长为16位,分辨率为800*600,它不经压缩占用的存储容量是()字节。A.690000B.1 - 试题答案网问答...

热门文章

  1. 一天学完spark的Scala基础语法教程二、运算符与分支语句(idea版本)
  2. PHP面试题:请以空格作为间隔,拆分字符串’Apple Orange Banana Strawberry’,组成数组$fruit,
  3. 用pip命令把python包安装到指定目录
  4. Message 消息提示
  5. ckeidtor编辑器添加图片上传功能
  6. Chapter 7 Windows下pycaffe的使用之draw_net.py
  7. Gradient Boost Decision Tree(GBDT)中损失函数为什么是对数形式
  8. struts 权限控制
  9. ASP.NET MVC3 权限验证
  10. JavaScript高级程序设计学习笔记6:正则表达式