Head First_设计模式_学习笔记_第01章_策略模式
第一次用这书来学习设计模式,还真是超正点,无意中学会了第一个设计模式——策略模式。本次学习,我决定用最笨的方法,上机实践,逐个代码敲,用C++,C#,java三种语言来将它书上的UML图用代码实现。具体也不多说啦。这次的笔记就以笔记的形式记录吧,也不用过多的说明啦,书本上写得太好啦。
首先呢,是从简单的模拟鸭子应用做起:
P002_C++代码实现:
/** * 项目名称:P002Duck.cpp * 文件说明: 实现《Head Frist 设计模式》P2书本UML图的代码。 * 完成简单的模拟Duck应用。 * 程序说明:本程序共含三个类: * Duck作为基类,定义quack(), swim(), display() 基本方法。 * MallardDuck派生Duck,重写display()方法。 * RedheadDuck派生Duck,重写display()方法。 * 开发环境:Microsoft Visual Studio 2010 * 开发语言:C++ * 文件作者:Neicole * 联系方式:http://blog.csdn.net/neicole * 联系方式:http://neicole.blog.51cto.com/ * 制作日期:2012.09.17 **/ #include <iostream> using std::cout; #include "Duck.h" #include "MallardDuck.h" #include "RedheadDuck.h" /************************** 主函数 ****************************/ int main() { // Duck, MallardDuck, RedheadDuck // construct Duck * duck[3] = {0, 0, 0}; duck[0] = new Duck(); duck[1] = new MallardDuck(); duck[2] = new RedheadDuck(); // show for(int i = 0; i < 3; ++i){ if(0 == i){ cout << "Hello, I'm class Duck:\n"; } else if(1 == i){ cout << "\nHello, I'm class MallardDuck:\n";} else if(2 == i){ cout << "\nHello, I'm class RedHeadDuck:\n";} duck[i] -> quack(); duck[i] -> swim(); duck[i] -> display(); } // destroy for(int i = 0; i < 3; ++i){ delete duck[i]; } cout << "\n测试已完成,"; system("pause"); return 0; } /************** 运行结果 ************* Hello, I'm class Duck: Duck: 我是一只会呱呱叫的鸭 Duck: 我是一只会游泳的鸭 Duck: 我是一只普通样子的鸭 Hello, I'm class MallardDuck: Duck: 我是一只会呱呱叫的鸭 Duck: 我是一只会游泳的鸭 MallardDuck: 我是一只绿色头的鸭 Hello, I'm class RedHeadDuck: Duck: 我是一只会呱呱叫的鸭 Duck: 我是一只会游泳的鸭 RedheadDuck: 我是一只红头鸭 测试已完成,请按任意键继续. . . ************** 以上 *************/
// Duck.h /************************* Duck类 ******************************/ #ifndef __DUCK__ #define __DUCK__ class Duck { public: Duck(){} virtual ~Duck(){} void quack(){ // 呱呱叫 cout << "Duck: 我是一只会呱呱叫的鸭\n"; } void swim(){ // 游泳 cout << "Duck: 我是一只会游泳的鸭\n"; } virtual void display(){ // 鸭子的样子 cout << "Duck: 我是一只普通样子的鸭\n"; } }; #endif // __DUCK__
// MallardDuck.h /******************** MallardDuck类 ****************************/ #ifndef __MALLARDDUCK__ #define __MALLARDDUCK__ class Duck; class MallardDuck: public Duck { public: MallardDuck():Duck(){} // 外观是绿头的一种鸭 virtual ~MallardDuck(){} virtual void display(){ cout << "MallardDuck: 我是一只绿色头的鸭\n"; } }; #endif // __MALLARDDUCK__
// RedheadDuck.h /******************** RedheadDuck类 ****************************/ #ifndef __REDHEADDUCK__ #define __REDHEADDUCK__ class Duck; class RedheadDuck: public Duck { public: RedheadDuck():Duck(){} // 外观是红头的一种鸭 virtual ~RedheadDuck(){} virtual void display(){ cout << "RedheadDuck: 我是一只红头鸭\n"; } }; #endif // __REDHEADDUCK__
P002_C#代码实现:
/** * 项目名称:P002Duck * 文件说明: 实现《Head Frist 设计模式》P2书本UML图的代码。 * 完成简单的模拟Duck应用。 * 程序说明:本程序共含三个类: * Duck作为基类,定义quack(), swim(), display() 基本方法。 * MallardDuck派生Duck,重写display()方法。 * RedheadDuck派生Duck,重写display()方法。 * 开发环境:Microsoft Visual Studio 2010 * 开发语言:C# * 文件作者:Neicole * 联系方式:http://blog.csdn.net/neicole * 联系方式:http://neicole.blog.51cto.com/ * 制作日期:2012.09.17 **/ using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace P002Duck { class Program { static void Main(string[] args) { // Duck, MallardDuck, RedheadDuck // construct Duck [] duck = {new Duck(), new MallardDuck(), new RedheadDuck()}; // show for(int i = 0; i < 3; ++i){ if(0 == i){ Console.WriteLine("Hello, I'm class Duck:"); } else if(1 == i){ Console.WriteLine("\nHello, I'm class MallardDuck:");} else if(2 == i){ Console.WriteLine("\nHello, I'm class RedHeadDuck:");} duck[i].quack(); duck[i].swim(); duck[i].display(); } Console.WriteLine("\n测试已完成,请按任意键继续"); Console.ReadKey(); } } } /************** 运行结果 ************* Hello, I'm class Duck: Duck: 我是一只会呱呱叫的鸭 Duck: 我是一只会游泳的鸭 Duck: 我是一只普通样子的鸭 Hello, I'm class MallardDuck: Duck: 我是一只会呱呱叫的鸭 Duck: 我是一只会游泳的鸭 MallardDuck: 我是一只绿色头的鸭 Hello, I'm class RedHeadDuck: Duck: 我是一只会呱呱叫的鸭 Duck: 我是一只会游泳的鸭 RedheadDuck: 我是一只红头鸭 测试已完成,请按任意键继续. . . ************** 以上 *************/
// Duck.cs using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace P002Duck { /************************* Duck类 ******************************/ public class Duck { public Duck() { } public void quack() { // 呱呱叫 Console.WriteLine("Duck: 我是一只会呱呱叫的鸭"); } public void swim() { // 游泳 Console.WriteLine("Duck: 我是一只会游泳的鸭"); } public virtual void display() { // 鸭子的样子 Console.WriteLine("Duck: 我是一只普通样子的鸭"); } }; }
// MallardDuck.cs using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace P002Duck { /******************** MallardDuck类 ****************************/ public class MallardDuck : Duck { public MallardDuck() : base() { } // 外观是绿头的一种鸭 public override void display() { Console.WriteLine("MallardDuck: 我是一只绿色头的鸭"); } }; }
// RedheadDuck.cs using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace P002Duck { /******************** RedheadDuck类 ****************************/ public class RedheadDuck : Duck { public RedheadDuck() : base() { } // 外观是红头的一种鸭 public override void display() { Console.WriteLine("RedheadDuck: 我是一只红头鸭"); } }; }
P002_Java代码实现
/** * 文件名称:P2Duck.java * 文件说明: 实现《Head Frist 设计模式》P2书本UML图的代码。 * 完成简单的模拟Duck应用。 * 程序说明:本程序共含三个类: * Duck作为基类,定义quack(), swim(), display() 基本方法。 * MallardDuck派生Duck,重写display()方法。 * RedheadDuck派生Duck,重写display()方法。 * 开发环境:Eclipse-SDK-3.4.2-win32 * 开发语言:Java * 文件作者:Neicole * 联系方式:http://blog.csdn.net/neicole * 联系方式:http://neicole.blog.51cto.com/ * 制作日期:2012.09.17 **/ import Duck.*; public class Main { public static void main(String[] args) { // Duck, MallardDuck, RedheadDuck // construct Duck[] duck = { new Duck(), new MallardDuck(), new RedheadDuck() }; // show for (int i = 0; i < 3; ++i) { if (0 == i) { System.out.println("Hello, I'm class Duck:"); } else if (1 == i) { System.out.println("\nHello, I'm class MallardDuck:"); } else if (2 == i) { System.out.println("\nHello, I'm class RedHeadDuck:"); } duck[i].quack(); duck[i].swim(); duck[i].display(); } System.out.println("\n测试已完成。"); } } /************** 运行结果 ************* Hello, I'm class Duck: Duck: 我是一只会呱呱叫的鸭 Duck: 我是一只会游泳的鸭 Duck: 我是一只普通样子的鸭 Hello, I'm class MallardDuck: Duck: 我是一只会呱呱叫的鸭 Duck: 我是一只会游泳的鸭 MallardDuck: 我是一只绿色头的鸭 Hello, I'm class RedHeadDuck: Duck: 我是一只会呱呱叫的鸭 Duck: 我是一只会游泳的鸭 RedheadDuck: 我是一只红头鸭 测试已完成。 ************** 以上 *************/
package Duck; /************************* Duck类 ******************************/ public class Duck { public Duck() { } public void quack() { // 呱呱叫 System.out.println("Duck: 我是一只会呱呱叫的鸭"); } public void swim() { // 游泳 System.out.println("Duck: 我是一只会游泳的鸭"); } public void display() { // 鸭子的样子 System.out.println("Duck: 我是一只普通样子的鸭"); } }
package Duck; /******************** MallardDuck类 ****************************/ public class MallardDuck extends Duck { public MallardDuck() { super(); } // 外观是绿头的一种鸭 public void display() { System.out.println("MallardDuck: 我是一只绿色头的鸭"); } }
package Duck; /******************** RedheadDuck类 ****************************/ public class RedheadDuck extends Duck { public RedheadDuck() { super(); } // 外观是红头的一种鸭 public void display() { System.out.println("RedheadDuck: 我是一只红头鸭"); } }
之后,需要增加一个特殊的不会飞也不会叫的RubberDuck类,项目代码变得有点冗余
P005_C++代码实现:
/** * 项目名称:P005RubberDuck * 文件说明: 实现《Head Frist 设计模式》P5书本UML图的代码。 * 完成简单的模拟Duck应用。 * 在P02的基础上另外再给Duck加上会飞的方法,再加一个RubberDuck类。 * 程序说明:本程序共含四个类: * Duck作为基类,定义quack(), swim(), display() 基本方法。 * MallardDuck派生Duck,重写display()方法。 * RedheadDuck派生Duck,重写display()方法。 * RubberDuck派生Duck,重写display()方法,fly()方法,quack()方法。 * 开发环境:Microsoft Visual Studio 2010 * 开发语言:C++ * 文件作者:Neicole * 联系方式:http://blog.csdn.net/neicole * 联系方式:http://neicole.blog.51cto.com/ * 制作日期:2012.09.17 **/ #include <iostream> using std::cout; #include "Duck.h" #include "MallardDuck.h" #include "RedheadDuck.h" #include "RubberDuck.h" /************************** 主函数 ****************************/ int main() { // construct Duck * duck[4] = {0, 0, 0, 0}; duck[0] = new Duck(); duck[1] = new MallardDuck(); duck[2] = new RedheadDuck(); duck[3] = new RubberDuck(); // show for(int i = 0; i < 4; ++i){ if(0 == i){ cout << "Hello, I'm class Duck:\n"; } else if(1 == i){ cout << "\nHello, I'm class MallardDuck:\n";} else if(2 == i){ cout << "\nHello, I'm class RedHeadDuck:\n";} else if(3 == i){ cout << "\nHello, I'm class RubberDuck:\n";} duck[i] -> swim(); duck[i] -> display(); duck[i] -> quack(); duck[i] -> fly(); } // destroy for(int i = 0; i < 4; ++i){ delete duck[i]; } cout << "\n测试已完成,"; system("pause"); return 0; } /************** 运行结果 ************* Hello, I'm class Duck: Duck: 我是一只会游泳的鸭 Duck: 我是一只普通样子的鸭 Duck: 我是一只会呱呱叫的鸭 Duck: 我是一只会飞的鸭 Hello, I'm class MallardDuck: Duck: 我是一只会游泳的鸭 MallardDuck: 我是一只绿色头的鸭 Duck: 我是一只会呱呱叫的鸭 Duck: 我是一只会飞的鸭 Hello, I'm class RedHeadDuck: Duck: 我是一只会游泳的鸭 RedheadDuck: 我是一只红头鸭 Duck: 我是一只会呱呱叫的鸭 Duck: 我是一只会飞的鸭 Hello, I'm class RubberDuck: Duck: 我是一只会游泳的鸭 RubberDuck: 我是一只橡皮鸭 RubberDuck: 我这鸭不会叫 RubberDuck: 我这鸭不会飞 测试已完成,请按任意键继续. . . ************** 以上 *************/
// Duck.h /************************* Duck类 ******************************/ #ifndef __DUCK__ #define __DUCK__ class Duck { public: Duck(){} virtual ~Duck(){} virtual void quack(){ // 呱呱叫 cout << "Duck: 我是一只会呱呱叫的鸭\n"; } void swim(){ // 游泳 cout << "Duck: 我是一只会游泳的鸭\n"; } virtual void display(){ // 鸭子的样子 cout << "Duck: 我是一只普通样子的鸭\n"; } virtual void fly(){ // 还会飞 cout << "Duck: 我是一只会飞的鸭\n"; } }; #endif // __DUCK__
// MallardDuck.h /******************** MallardDuck类 ****************************/ #ifndef __MALLARDDUCK__ #define __MALLARDDUCK__ class Duck; class MallardDuck: public Duck { public: MallardDuck():Duck(){} // 外观是绿头的一种鸭 virtual ~MallardDuck(){} virtual void display(){ cout << "MallardDuck: 我是一只绿色头的鸭\n"; } }; #endif // __MALLARDDUCK__
// RedheadDuck.h /******************** RedheadDuck类 ****************************/ #ifndef __REDHEADDUCK__ #define __REDHEADDUCK__ class Duck; class RedheadDuck: public Duck { public: RedheadDuck():Duck(){} // 外观是红头的一种鸭 virtual ~RedheadDuck(){} virtual void display(){ cout << "RedheadDuck: 我是一只红头鸭\n"; } }; #endif // __REDHEADDUCK__
// RubberDuck.h /******************** RubberdDuck类 ****************************/ #ifndef __RUBBERDUCK__ #define __RUBBERDUCK__ class Duck; class RubberDuck: public Duck { public: RubberDuck():Duck(){} // 不会飞也不会叫的橡皮鸭,实质是一只诱饵鸭 virtual ~RubberDuck(){} virtual void display(){ cout << "RubberDuck: 我是一只橡皮鸭\n"; } virtual void fly(){ cout << "RubberDuck: 我这鸭不会飞\n"; } virtual void quack(){ cout << "RubberDuck: 我这鸭不会叫\n"; } }; #endif // __RUBBERDUCK__
P005_C#代码实现:
/** * 项目名称:P005RubberDuck * 文件说明: 实现《Head Frist 设计模式》P5书本UML图的代码。 * 完成简单的模拟Duck应用。 * 在P02的基础上另外再给Duck加上会飞的方法,再加一个RubberDuck类。 * 程序说明:本程序共含四个类: * Duck作为基类,定义quack(), swim(), display() 基本方法。 * MallardDuck派生Duck,重写display()方法。 * RedheadDuck派生Duck,重写display()方法。 * RubberDuck派生Duck,重写display()方法,fly()方法,quack()方法。 * 开发环境:Microsoft Visual Studio 2010 * 开发语言:C# * 文件作者:Neicole * 联系方式:http://blog.csdn.net/neicole * 联系方式:http://neicole.blog.51cto.com/ * 制作日期:2012.09.17 **/ using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace P005RubberDuck { class Program { static void Main(string[] args) { // construct Duck [] duck = { new Duck(), new MallardDuck(), new RedheadDuck(), new RubberDuck() }; // show for(int i = 0; i < 4; ++i){ if(0 == i){ Console.WriteLine("Hello, I'm class Duck:"); } else if(1 == i){ Console.WriteLine("\nHello, I'm class MallardDuck:");} else if(2 == i){ Console.WriteLine("\nHello, I'm class RedHeadDuck:");} else if (3 == i) { Console.WriteLine("\nHello, I'm class RubberDuck:"); } duck[i].swim(); duck[i].display(); duck[i].quack(); duck[i].fly(); } Console.WriteLine("\n测试已完成,请按任意键继续"); Console.ReadKey(); } } } /************** 运行结果 ************* Hello, I'm class Duck: Duck: 我是一只会游泳的鸭 Duck: 我是一只普通样子的鸭 Duck: 我是一只会呱呱叫的鸭 Duck: 我是一只会飞的鸭 Hello, I'm class MallardDuck: Duck: 我是一只会游泳的鸭 MallardDuck: 我是一只绿色头的鸭 Duck: 我是一只会呱呱叫的鸭 Duck: 我是一只会飞的鸭 Hello, I'm class RedHeadDuck: Duck: 我是一只会游泳的鸭 RedheadDuck: 我是一只红头鸭 Duck: 我是一只会呱呱叫的鸭 Duck: 我是一只会飞的鸭 Hello, I'm class RubberDuck: Duck: 我是一只会游泳的鸭 RubberDuck: 我是一只橡皮鸭 RubberDuck: 我是不会叫的 RubberDuck:我也不会飞 测试已完成,请按任意键继续 ************** 以上 *************/
// Duck.cs using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace P005RubberDuck { /************************* Duck类 ******************************/ public class Duck { public Duck() { } public virtual void quack() { // 呱呱叫 Console.WriteLine("Duck: 我是一只会呱呱叫的鸭"); } public void swim() { // 游泳 Console.WriteLine("Duck: 我是一只会游泳的鸭"); } public virtual void display() { // 鸭子的样子 Console.WriteLine("Duck: 我是一只普通样子的鸭"); } public virtual void fly() { // 飞 Console.WriteLine("Duck: 我是一只会飞的鸭"); } }; }
// MallardDuck.cs using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace P005RubberDuck { /******************** MallardDuck类 ****************************/ public class MallardDuck : Duck { public MallardDuck() : base() { } // 外观是绿头的一种鸭 public override void display() { Console.WriteLine("MallardDuck: 我是一只绿色头的鸭"); } }; }
// RedheadDuck.cs using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace P005RubberDuck { /******************** RedheadDuck类 ****************************/ public class RedheadDuck : Duck { public RedheadDuck() : base() { } // 外观是红头的一种鸭 public override void display() { Console.WriteLine("RedheadDuck: 我是一只红头鸭"); } }; }
using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace P005RubberDuck { /******************** RubberDuck类 ****************************/ public class RubberDuck: Duck { public RubberDuck() : base() { } // 橡皮鸭,用作诱饵 public override void display() { Console.WriteLine("RubberDuck: 我是一只橡皮鸭"); } public override void quack() { // 呱呱叫 Console.WriteLine("RubberDuck: 我是不会叫的"); } public override void fly() { // 飞 Console.WriteLine("RubberDuck:我也不会飞"); } } }
P005_Java代码实现:
/** * 项目名称:P005RubberDuck * 文件说明: 实现《Head Frist 设计模式》P5书本UML图的代码。 * 完成简单的模拟Duck应用。 * 在P02的基础上另外再给Duck加上会飞的方法,再加一个RubberDuck类。 * 程序说明:本程序共含四个类: * Duck作为基类,定义quack(), swim(), display() 基本方法。 * MallardDuck派生Duck,重写display()方法。 * RedheadDuck派生Duck,重写display()方法。 * RubberDuck派生Duck,重写display()方法,fly()方法,quack()方法。 * 开发环境:Eclipse-SDK-3.4.2-win32 * 开发语言:Java * 文件作者:Neicole * 联系方式:http://blog.csdn.net/neicole * 联系方式:http://neicole.blog.51cto.com/ * 制作日期:2012.09.17 **/ import Duck.*; public class Main { public static void main(String[] args) { // Duck, MallardDuck, RedheadDuck // construct Duck[] duck = { new Duck(), new MallardDuck(), new RedheadDuck(), new RubberDuck()}; // show for (int i = 0; i < 4; ++i) { if (0 == i) { System.out.println("Hello, I'm class Duck:"); } else if (1 == i) { System.out.println("\nHello, I'm class MallardDuck:"); } else if (2 == i) { System.out.println("\nHello, I'm class RedHeadDuck:"); } duck[i].swim(); duck[i].display(); duck[i].quack(); duck[i].fly(); } System.out.println("\n测试已完成。"); } } /************** 运行结果 ************* Hello, I'm class Duck: Duck: 我是一只会游泳的鸭 Duck: 我是一只普通样子的鸭 Duck: 我是一只会呱呱叫的鸭 Duck: 我是一只会飞的鸭 Hello, I'm class MallardDuck: Duck: 我是一只会游泳的鸭 MallardDuck: 我是一只绿色头的鸭 Duck: 我是一只会呱呱叫的鸭 Duck: 我是一只会飞的鸭 Hello, I'm class RedHeadDuck: Duck: 我是一只会游泳的鸭 RedheadDuck: 我是一只红头鸭 Duck: 我是一只会呱呱叫的鸭 Duck: 我是一只会飞的鸭 Duck: 我是一只会游泳的鸭 RedheadDuck: 我是一只红头鸭 RubberDuck: 我这鸭不会叫 RubberDuck: 我这鸭不会飞 测试已完成。 ************** 以上 *************/
package Duck; /************************* Duck类 ******************************/ public class Duck { public Duck() { } public void quack() { // 呱呱叫 System.out.println("Duck: 我是一只会呱呱叫的鸭"); } public void swim() { // 游泳 System.out.println("Duck: 我是一只会游泳的鸭"); } public void display() { // 鸭子的样子 System.out.println("Duck: 我是一只普通样子的鸭"); } public void fly() { // 会飞的鸭 System.out.println("Duck: 我是一只会飞的鸭"); } }
package Duck; /******************** MallardDuck类 ****************************/ public class MallardDuck extends Duck { public MallardDuck() { super(); } // 外观是绿头的一种鸭 public void display() { System.out.println("MallardDuck: 我是一只绿色头的鸭"); } }
package Duck; /******************** RedheadDuck类 ****************************/ public class RedheadDuck extends Duck { public RedheadDuck() { super(); } // 外观是红头的一种鸭 public void display() { System.out.println("RedheadDuck: 我是一只红头鸭"); } }
package Duck; /******************** RedheadDuck类 ****************************/ public class RubberDuck extends Duck { public RubberDuck() { super(); } // 不会飞也不会叫的橡皮鸭,实质是一只诱饵鸭 public void display() { System.out.println("RedheadDuck: 我是一只红头鸭"); } public void fly(){ System.out.println("RubberDuck: 我这鸭不会飞\n"); } public void quack(){ System.out.println("RubberDuck: 我这鸭不会叫\n"); } }
最后,使用策略者模式(Strategy Pattern)解决这个问题:
P022_C++代码实现:
/** * 项目名称:P022StrategyPerfectDuck * 文件说明: 实现《Head Frist 设计模式》P22书本UML图的代码。 * 以书上的UML图为例,以策略模式(Strategy)设计本程序。 * 程序说明:本程序共含三个包: * Duck包,含一个Duck抽象基类,基类中包含两个接口数据成员, * 其它派生类通过定义这两数据成员实现动作委托。 * Fly包,含一个FlyBehavior接口,其它类为实现该接口,定义出含该接口的类的特征。 * Quack包,含一个QuackBehavior接口,其它类为实现该接口,定义出含该接口的类的特征。 * 开发环境:Microsoft Visual Studio 2010 * 开发语言:C++ * 文件作者:Neicole * 联系方式:http://blog.csdn.net/neicole * 联系方式:http://neicole.blog.51cto.com/ * 制作日期:2012.09.18 * 附:策略模式——定义了算法族,分别封装起来,让它们之间可以互相替换, * 此模式让算法的变化独立于使用算法的客户。 **/ #include <iostream> #include "FlyBehavior.h" #include "FlyNoWay.h" #include "FlyRocketPowered.h" #include "FlyWithWings.h" #include "QuackBehavior.h" #include "Squeak.h" #include "Quack.h" #include "MuteQuack.h" #include "Duck.h" #include "DecoyDuck.h" #include "MallardDuck.h" #include "MiniDuckSimulator.h" #include "RedheadDuck.h" #include "RubberDuck.h" int main() { Duck * duck[] = { new DecoyDuck(), new MallardDuck(), new RedheadDuck(), new RubberDuck(), new MiniDuckSimulator() }; for(int i = 0; i < sizeof(duck)/sizeof(duck[0]); ++i){ switch(i){ case 0: std::cout << "\nNow,DocoyDuck Testing Start...\n";break; case 1: std::cout << "\nNow,MallardDuck Testing Start...\n";break; case 2: std::cout << "\nNow,RedheadDuck Testing Start...\n";break; case 3: std::cout << "\nNow,RubberDuck Testing Start...\n";break; case 4: std::cout << "\nNow,MiniDuckSimulator Testing Start...\n";break; } duck[i] -> swim(); duck[i] -> display(); duck[i] -> performFly(); duck[i] -> performQuack(); } std::cout << "\nNow, Trying to change MiniDuckSimulator\n"; duck[4] -> setFlyBehavior(new FlyRocketPowered()); duck[4] -> setQuackBehavior(new Quack()); duck[4] -> display(); duck[4] -> performFly(); duck[4] -> performQuack(); std::cout << "\n"; system("pause"); for (int i = 0; i < 5; ++i){ delete duck[i]; } return 0; } /**************** 运算结果 ****************** Now,DocoyDuck Testing Start... All ducks can Swim. I'm a duck Decoy I can fly in no way I am MuteQuack, I can't Quack. Now,MallardDuck Testing Start... All ducks can Swim. I'm Mallard duck! I can Fly With Wings I can Quack, gua gua ... Now,RedheadDuck Testing Start... All ducks can Swim. I'm Red Headed duck I can Fly With Wings I can Quack, gua gua ... Now,RubberDuck Testing Start... All ducks can Swim. I'm Red Headed duck I can fly in no way I am MuteQuack, I can't Quack. Now,MiniDuckSimulator Testing Start... All ducks can Swim. I'm MiniDuckSimulator! I can fly in no way I am MuteQuack, I can't Quack. Now, Trying to change MiniDuckSimulator I'm MiniDuckSimulator! I'm flying with a rocket I can Quack, gua gua ... 请按任意键继续. . . ************************************************/
// FlyBehavior.h #ifndef __FLYBEHAVIOR__ #define __FLYBEHAVIOR__ class FlyBehavior { public: virtual void fly(){} }; #endif // __FLYBEHAVIOR__
// FlyNoWay.h #ifndef __FLYNOWAY__ #define __FLYNOWAY__ #include <iostream> class FlyBehavior; class FlyNoWay: public FlyBehavior { public: virtual void fly(){ std::cout << "I can fly in no way\n"; } }; #endif // __FLYNOWAY__
// FlyRocketPowered.h #ifndef __FLYROCKETPOWERED__ #define __FLYROCKETPOWERED__ #include <iostream> class FlyBehavior; class FlyRocketPowered: public FlyBehavior { public: virtual void fly(){ std::cout << "I'm flying with a rocket\n"; } }; #endif // __FLYROCKETPOWERED__
// FlyWithWings.h #ifndef __FLYWITHWINGS__ #define __FLYWITHWINGS__ #include <iostream> class FlyBehavior; class FlyWithWings: public FlyBehavior { public: virtual void fly(){ std::cout << "I can Fly With Wings\n"; } }; #endif // __FLYWITHWINGS__
// QuackBehavior.h #ifndef __QUACKBEHAVIOR__ #define __QUACKBEHAVIOR__ class QuackBehavior { public: virtual void quack(){} }; #endif // __QUACKBEHAVIOR__
// Quack.h #ifndef __QUACK__ #define __QUACK__ #include <iostream> class QuackBehavior; class Quack: public QuackBehavior { public: virtual void quack(){ std::cout << "I can Quack, gua gua ...\n"; } }; #endif // __QUACK__
// MuteQuack.h #ifndef __MUTEQUACK__ #define __MUTEQUACK__ #include <iostream> class QuackBehavior; class MuteQuack: public QuackBehavior { public: virtual void quack(){ std::cout << "I am MuteQuack, I can't Quack.\n"; } }; #endif // __MUTEQUACK__
// Squeak.h #ifndef __SQUEAK__ #define __SQUEAK__ #include <iostream> class QuackBehavior; class Squeak: public QuackBehavior { public: virtual void quack(){ std::cout << "I am Squeak, I can Quack, zi zi ...\n"; } }; #endif // __SQUEAK__
// Duck.h #ifndef __DUCK__ #define __DUCK__ #include "FlyBehavior.h" #include "QuackBehavior.h" #include <iostream> class Duck { protected: FlyBehavior * flyBehavior; QuackBehavior * quackBehavior; public: Duck(){ flyBehavior = 0; quackBehavior = 0; } virtual ~Duck(){ if(NULL != flyBehavior){ delete flyBehavior; flyBehavior = 0; } if(NULL != quackBehavior){ delete quackBehavior; quackBehavior = 0; } } void setFlyBehavior(FlyBehavior * fb) { if(NULL != flyBehavior){ delete flyBehavior; } flyBehavior = fb; } void setQuackBehavior(QuackBehavior * qb){ if(NULL != quackBehavior){ delete quackBehavior; } quackBehavior = qb; } void performFly(){ flyBehavior -> fly(); } void performQuack() { quackBehavior -> quack(); } void swim() { std::cout << "All ducks can Swim.\n"; } virtual void display(){ std::cout << "I'm Base Duck"; } }; #endif // __DUCK__
// DecoyDuck.h #ifndef __DECOYDUCK__ #define __DECOYDUCK__ #include <iostream> class Duck; class DecoyDuck: public Duck { public: DecoyDuck() :Duck(){ flyBehavior = new FlyNoWay(); quackBehavior = new MuteQuack(); } virtual ~DecoyDuck(){} virtual void display(){ std::cout << "I'm a duck Decoy\n"; } }; #endif // __DECOYDUCK__
// MallardDuck.h #ifndef __MALLARDDUCK__ #define __MALLARDDUCK__ #include <iostream> class Duck; class MallardDuck: public Duck { public: MallardDuck() { quackBehavior = new Quack(); flyBehavior = new FlyWithWings(); } virtual ~MallardDuck(){} virtual void display(){ std::cout << "I'm Mallard duck!\n"; } }; #endif // __MALLARDDUCK__
// MiniDuckSimulator.h #ifndef __MINIDUCKSIMULATOR__ #define __MINIDUCKSIMULATOR__ #include <iostream> class Duck; class MiniDuckSimulator: public Duck { public: MiniDuckSimulator():Duck() { flyBehavior = new FlyNoWay(); quackBehavior = new MuteQuack(); } virtual ~MiniDuckSimulator(){} virtual void display(){ std::cout << "I'm MiniDuckSimulator!\n"; } }; #endif // __MINIDUCKSIMULATOR__
// RedheadDuck.h #ifndef __REDHEADDUCK__ #define __REDHEADDUCK__ #include <iostream> class Duck; class RedheadDuck: public Duck { public: RedheadDuck():Duck() { flyBehavior = new FlyWithWings(); quackBehavior = new Quack(); } virtual ~RedheadDuck(){} virtual void display(){ std::cout << "I'm Red Headed duck\n"; } }; #endif // __REDHEADDUCK__
// RubberDuck.h #ifndef __RUBBERDUCK__ #define __RUBBERDUCK__ #include <iostream> class Duck; class RubberDuck: public Duck { public: RubberDuck():Duck() { flyBehavior = new FlyNoWay(); quackBehavior = new MuteQuack(); } virtual ~RubberDuck(){} virtual void display(){ std::cout << "I'm Red Headed duck\n"; } }; #endif // __RUBBERDUCK__
P022_C#代码实现:
/** * 项目名称:P022StrategyPerfectDuck * 文件说明: 实现《Head Frist 设计模式》P22书本UML图的代码。 * 以书上的UML图为例,以策略模式(Strategy)设计本程序。 * 程序说明:本程序共含三个包: * Duck包,含一个Duck抽象基类,基类中包含两个接口数据成员, * 其它派生类通过定义这两数据成员实现动作委托。 * Fly包,含一个FlyBehavior接口,其它类为实现该接口,定义出含该接口的类的特征。 * Quack包,含一个QuackBehavior接口,其它类为实现该接口,定义出含该接口的类的特征。 * 开发环境:Microsoft Visual Studio 2010 * 开发语言:C# * 文件作者:Neicole * 联系方式:http://blog.csdn.net/neicole * 联系方式:http://neicole.blog.51cto.com/ * 制作日期:2012.09.17 * 附:策略模式——定义了算法族,分别封装起来,让它们之间可以互相替换, * 此模式让算法的变化独立于使用算法的客户。 **/ using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace P022StrategyPerfectDuck { using Quack; using Fly; using Duck; class Program { static void Main(string[] args) { Duck.Duck [] duck = { new DecoyDuck(), new MallardDuck(), new RedheadDuck(), new RubberDuck(), new MiniDuckSimulator() }; for(int i = 0; i < duck.Length; ++i){ switch(i){ case 0: Console.WriteLine("\nNow,DocoyDuck Testing Start...");break; case 1: Console.WriteLine("\nNow,MallardDuck Testing Start...");break; case 2: Console.WriteLine("\nNow,RedheadDuck Testing Start...");break; case 3: Console.WriteLine("\nNow,RubberDuck Testing Start...");break; case 4: Console.WriteLine("\nNow,MiniDuckSimulator Testing Start...");break; } duck[i].swim(); duck[i].display(); duck[i].performFly(); duck[i].performQuack(); } Console.WriteLine("\nNow, Trying to change MiniDuckSimulator"); duck[4].setFlyBehavior(new FlyRocketPowered()); duck[4].setQuackBehavior(new Quack.Quack()); duck[4].display(); duck[4].performFly(); duck[4].performQuack(); } } } /*********** 运行结果 *************** Now,DocoyDuck Testing Start... All ducks can Swim. I'm a duck Decoy I can fly in no way I am MuteQuack, I can't Quack. Now,MallardDuck Testing Start... All ducks can Swim. I'm Mallard duck I can Fly With Wings I can Quack, gua gua ... Now,RedheadDuck Testing Start... All ducks can Swim. I'm Red Headed duck I can Fly With Wings I can Quack, gua gua ... Now,RubberDuck Testing Start... All ducks can Swim. I'm RubberDuck. I can fly in no way I am MuteQuack, I can't Quack. Now,MiniDuckSimulator Testing Start... All ducks can Swim. I'm MiniDuckSimulator I can fly in no way I am MuteQuack, I can't Quack. Now, Trying to change MiniDuckSimulator I'm MiniDuckSimulator I'm flying with a rocket I can Quack, gua gua ... 请按任意键继续. . . ***********************************************/
// FlyBehavior.cs using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace P022StrategyPerfectDuck.Fly { public interface FlyBehavior { void fly(); } }
// FlyNoWay.cs using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace P022StrategyPerfectDuck.Fly { public class FlyNoWay: FlyBehavior { public void fly(){ Console.WriteLine("I can fly in no way"); } } }
// FlyRocketPowered.cs using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace P022StrategyPerfectDuck.Fly { public class FlyRocketPowered: FlyBehavior { public void fly(){ Console.WriteLine("I'm flying with a rocket"); } } }
// FlyWithWings.cs using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace P022StrategyPerfectDuck.Fly { public class FlyWithWings: FlyBehavior { public void fly(){ Console.WriteLine("I can Fly With Wings"); } } }
// QuackBehavior.cs using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace P022StrategyPerfectDuck.Quack { public interface QuackBehavior { void quack(); } }
// Quack.cs using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace P022StrategyPerfectDuck.Quack { public class Quack:QuackBehavior { public void quack(){ Console.WriteLine("I can Quack, gua gua ..."); } } }
// MuteQuack.cs using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace P022StrategyPerfectDuck.Quack { public class MuteQuack: QuackBehavior { public void quack(){ Console.WriteLine("I am MuteQuack, I can't Quack."); } } }
// Squeak.cs using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace P022StrategyPerfectDuck.Quack { public class Squeak: QuackBehavior { public void quack(){ Console.WriteLine("I am Squeak, I can Quack, zi zi ..."); } } }
// Duck.cs using System; using System.Collections.Generic; using System.Linq; using System.Text; using P022StrategyPerfectDuck.Fly; using P022StrategyPerfectDuck.Quack; namespace P022StrategyPerfectDuck.Duck { public abstract class Duck { protected FlyBehavior flyBehavior; protected QuackBehavior quackBehavior; public Duck() { } public void setFlyBehavior(FlyBehavior fb) { flyBehavior = fb; } public void setQuackBehavior(QuackBehavior qb) { quackBehavior = qb; } public void performFly() { flyBehavior.fly(); } public void performQuack() { quackBehavior.quack(); } public void swim() { Console.WriteLine("All ducks can Swim."); } public abstract void display(); } }
// DecoyDuck.cs using System; using System.Collections.Generic; using System.Linq; using System.Text; using P022StrategyPerfectDuck.Fly; using P022StrategyPerfectDuck.Quack; namespace P022StrategyPerfectDuck.Duck { public class DecoyDuck: Duck { public DecoyDuck() { flyBehavior = new FlyNoWay(); quackBehavior = new MuteQuack(); } public override void display() { Console.WriteLine("I'm a duck Decoy"); } } }
// MallardDuck.cs using System; using System.Collections.Generic; using System.Linq; using System.Text; using P022StrategyPerfectDuck.Fly; using P022StrategyPerfectDuck.Quack; namespace P022StrategyPerfectDuck.Duck { class MallardDuck:Duck { public MallardDuck() { quackBehavior = new Quack.Quack(); flyBehavior = new FlyWithWings(); } public override void display() { Console.WriteLine("I'm Mallard duck"); } } }
// MiniDuckSimulator.cs using System; using System.Collections.Generic; using System.Linq; using System.Text; using P022StrategyPerfectDuck.Fly; using P022StrategyPerfectDuck.Quack; namespace P022StrategyPerfectDuck.Duck { public class MiniDuckSimulator: Duck { public MiniDuckSimulator():base(){ setFlyBehavior(new FlyNoWay()); setQuackBehavior(new MuteQuack()); } public override void display() { Console.WriteLine("I'm MiniDuckSimulator"); } } }
// RedheadDuck.cs using System; using System.Collections.Generic; using System.Linq; using System.Text; using P022StrategyPerfectDuck.Fly; using P022StrategyPerfectDuck.Quack; namespace P022StrategyPerfectDuck.Duck { public class RedheadDuck: Duck { public RedheadDuck() { flyBehavior = new FlyWithWings(); quackBehavior = new Quack.Quack(); } public override void display() { Console.WriteLine("I'm Red Headed duck"); } } }
// RubberDuck.cs using System; using System.Collections.Generic; using System.Linq; using System.Text; using P022StrategyPerfectDuck.Fly; using P022StrategyPerfectDuck.Quack; namespace P022StrategyPerfectDuck.Duck { public class RubberDuck:Duck { public RubberDuck():base(){ setFlyBehavior(new FlyNoWay()); setQuackBehavior(new MuteQuack()); } public override void display() { Console.WriteLine("I'm RubberDuck."); } } }
P022_Java代码实现:
/** * 项目名称:P022StrategyPerfectDuck * 文件说明: 实现《Head Frist 设计模式》P22书本UML图的代码。 * 以书上的UML图为例,以策略模式(Strategy)设计本程序。 * 程序说明:本程序共含三个包: * Duck包,含一个Duck抽象基类,基类中包含两个接口数据成员, * 其它派生类通过定义这两数据成员实现动作委托。 * Fly包,含一个FlyBehavior接口,其它类为实现该接口,定义出含该接口的类的特征。 * Quack包,含一个QuackBehavior接口,其它类为实现该接口,定义出含该接口的类的特征。 * 开发环境:Eclipse-SDK-3.4.2-win32 * 开发语言:Java * 文件作者:Neicole * 联系方式:http://blog.csdn.net/neicole * 联系方式:http://neicole.blog.51cto.com/ * 制作日期:2012.09.17 * 附:策略模式——定义了算法族,分别封装起来,让它们之间可以互相替换, * 此模式让算法的变化独立于使用算法的客户。 **/ import Duck.*; import Fly.*; import Quack.*; public class Main { public static void main(String[] args) { Duck [] duck = { new DecoyDuck(), new MallardDuck(), new RedheadDuck(), new RubberDuck(), new MiniDuckSimulator() }; for(int i = 0; i < duck.length; ++i){ switch(i){ case 0: System.out.println("\nNow,DocoyDuck Testing Start...");break; case 1: System.out.println("\nNow,MallardDuck Testing Start...");break; case 2: System.out.println("\nNow,RedheadDuck Testing Start...");break; case 3: System.out.println("\nNow,RubberDuck Testing Start...");break; case 4: System.out.println("\nNow,MiniDuckSimulator Testing Start...");break; } duck[i].swim(); duck[i].display(); duck[i].performFly(); duck[i].performQuack(); } System.out.println("\nNow, Trying to change MiniDuckSimulator"); duck[4].setFlyBehavior(new FlyRocketPowered()); duck[4].setQuackBehavior(new Quack()); duck[4].display(); duck[4].performFly(); duck[4].performQuack(); } } /****************** 运行结果 ******************* Now,DocoyDuck Testing Start... All ducks can Swim. I'm a duck Decoy I can fly in no way I am MuteQuack, I can't Quack. Now,MallardDuck Testing Start... All ducks can Swim. I'm Mallard duck I can Fly With Wings I can Quack, gua gua ... Now,RedheadDuck Testing Start... All ducks can Swim. I'm Red Headed duck I can Fly With Wings I can Quack, gua gua ... Now,RubberDuck Testing Start... All ducks can Swim. I'm RubberDuck. I can fly in no way I am MuteQuack, I can't Quack. Now,MiniDuckSimulator Testing Start... All ducks can Swim. I'm MiniDuckSimulator I can fly in no way I am MuteQuack, I can't Quack. Now, Trying to change MiniDuckSimulator I'm MiniDuckSimulator I'm flying with a rocket I can Quack, gua gua ... ************************************************/
// FlyBehavior.java package Fly; public interface FlyBehavior { public void fly(); }
// FlyNoWay.java package Fly; public class FlyNoWay implements FlyBehavior { public void fly() { System.out.println("I can fly in no way"); } }
// FlyRocketPowered.java package Fly; public class FlyRocketPowered implements FlyBehavior { public void fly(){ System.out.println("I'm flying with a rocket"); } }
// FlyWithWings.java package Fly; public class FlyWithWings implements FlyBehavior { public void fly(){ System.out.println("I can Fly With Wings"); } }
// QuackBehavior.java package Quack; public interface QuackBehavior { public void quack(); }
// Quack.java package Quack; public class Quack implements QuackBehavior { public void quack(){ System.out.println("I can Quack, gua gua ..."); } }
// MuteQuack.java package Quack; public class MuteQuack implements QuackBehavior { public void quack(){ System.out.println("I am MuteQuack, I can't Quack."); } }
// Squeak.java package Quack; public class Squeak implements QuackBehavior { public void quack(){ System.out.println("I am Squeak, I can Quack, zi zi ..."); } }
// Duck.java package Duck; import Fly.*; import Quack.*; public abstract class Duck { protected FlyBehavior flyBehavior; protected QuackBehavior quackBehavior; public Duck() { } public void setFlyBehavior (FlyBehavior fb) { flyBehavior = fb; } public void setQuackBehavior(QuackBehavior qb) { quackBehavior = qb; } public void performFly() { flyBehavior.fly(); } public void performQuack() { quackBehavior.quack(); } public void swim() { System.out.println("All ducks can Swim."); } public abstract void display(); }
// DecoyDuck.java package Duck; import Fly.*; import Quack.*; public class DecoyDuck extends Duck { public DecoyDuck() { flyBehavior = new FlyNoWay(); quackBehavior = new MuteQuack(); } public void display() { System.out.println("I'm a duck Decoy"); } }
// MallardDuck.java package Duck; import Fly.*; import Quack.*; public class MallardDuck extends Duck { public MallardDuck() { quackBehavior = new Quack(); flyBehavior = new FlyWithWings(); } public void display() { System.out.println("I'm Mallard duck"); } }
// MiniDuckSimulator.java package Duck; import Fly.*; import Quack.*; public class MiniDuckSimulator extends Duck { public MiniDuckSimulator(){ super(); super.setFlyBehavior(new FlyNoWay()); super.setQuackBehavior(new MuteQuack()); } public void display(){ System.out.println("I'm MiniDuckSimulator"); } }
// RedheadDuck.java package Duck; import Fly.*; import Quack.*; public class RedheadDuck extends Duck { public RedheadDuck() { flyBehavior = new FlyWithWings(); quackBehavior = new Quack(); } public void display() { System.out.println("I'm Red Headed duck"); } }
// RubberDuck.java package Duck; import Fly.FlyNoWay; import Quack.MuteQuack; public class RubberDuck extends Duck { public RubberDuck(){ super(); setFlyBehavior(new FlyNoWay()); setQuackBehavior(new MuteQuack()); } public void display(){ System.out.println("I'm RubberDuck."); } }
末尾,我还是将《Head First 设计模式》的一章重要知识摘录下来吧:
00基础:
01 抽象,
02 封装,
03 多态,
04 继承。
00原则:
01 封装变化,
02 多用组合,少用继承,
03 针对接品编程,不针对实现编程。
00模式:
01 (Strategy Pattern)策略模式――定义算法族,分别封装起来,让它们之间可以互相替换,此模式让算法的变化独立于使用算法的客户。
00要点
01 知道OO基础,并不足以让你设计出良好的OO系统。
02 良好的OO设计必须具备可复用、可扩充、可维护三个特性。
03 模式可以让我们建造出具有良好的OO设计质量的系统。
04 模式被认为是历经验证的OO设计经验。
05 模式不是代码,而是针对设计问题的通用解决方案。你可把它们应用到特定的应用中。
06 模式不是被发明,而是被发现。
07 大多数的模式和原则,都着眼于软件变化的主题。
08 大多数的模式都允许系统局部改变独立于其他部分。
09 我们常把系统中会变化的部分抽出来封装。
10 模式让开发人员之间有共享的语言,能够最大化沟通的价值。