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


以下内容转载请注明来自"菩提树下的杨过(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 整理于上海
posted @ 2008-05-08 22:43  菩提树下的杨过  阅读(563)  评论(0编辑  收藏  举报