(Head First 设计模式)学习笔记(1)

把书中开篇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 整理于上海

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏跟着阿笨一起玩NET

C#中格式化数据的输出

alignment:可选,是一个带符号的整数,指示首选的格式化字段宽度。如果“对齐”值小于格式化字符串的长度,“对齐”会被忽略,并且使用格式化字符串的长度作为字...

810
来自专栏Jackson0714

01.策略模式-上篇

3498
来自专栏岑玉海

RavenDb学习(五)结果转换

1)Result Transformers public class Order { public DateTime OrderedAt { get;...

2739
来自专栏王磊的博客

HttpWebRequest采集读取网站挂载Cookie的通用方法

Asp.net 版本 HttpWebRequest采集时添加:httpWebRequest.CookieContainer = new CookieContai...

3015
来自专栏hbbliyong

LINQ分页和排序,skip和Take 用法

LINQ分页和排序,skip和Take 用法 dbconn.BidRecord.OrderBy(p=>p.bid_id).ToList<BidRecord>()...

3869
来自专栏我是攻城师

Joda-Time几个用法小记

3057
来自专栏菩提树下的杨过

几种常见复合sql查询语句的linq写法[继续补充中]

1.IN 语句 尝试了很多次,好象linq死活不生成in语句,无奈只能做了下变换 例,要找出"手机大类"以及"手机下属所有子类"的产品 (手机大类的ID为D0...

2436
来自专栏菩提树下的杨过

泛型List<T>使用示例

代码来源于"c#高级编程(第4版)",略作修改 using System; using System.Collections; using System.C...

1917
来自专栏lgp20151222

JSONObject和JSONArray区别及基本用法

        例如:   { "id" : "123", "courseID" : "huangt-test", "title" : "提交作业", "con...

841
来自专栏cs

c#练手code

3106

扫码关注云+社区

领取腾讯云代金券