本篇来介绍一下设计模式之策略模式。
以下是本文目录大纲:
1.用策略模式改进一个设计实例。
2.策略模式的介绍和设计思路。
3.策略模式用到的设计原则。
4.设计实例的java实现。
转载请注明原文出处。
若有不正确的地方,欢迎大家的批评指正。
1.用策略模式改进一个设计的实例
现在要做一款模拟人生类游戏,游戏中有各种职业的人(教师、学生、工人、司机)。这些人都有着像姓名、性别等属性,行走、吃饭等相同的行为,当然他们有着不同的工作。我们这里为各种职业的人设计一个类来描述他们的特征,按照OO设计的思想,产生了如下的设计:
用一个抽象类来描述不同职业的人共用的特征,并将work方法在基类中设置为抽象方法,让继承People类的子类去实现不同的work方法,来区别不同职业人的工作。这时游戏中增加了乞丐的人物设定,这时这个设计就出现了问题:乞丐类也要去继承抽象类People,那必须去实现work方法,而乞丐并不存在职业。所以从这种设计我们可以体会到,当涉及系统的维护时,为了达到代码复用的目的而使用继承的方法并不是一个好的选择。
此时我们可以考虑使用接口将方法work()从基类People分离出来,让那些拥有工作的人去实现这个接口,从而满足设计的需求,于是产生了如下的设计:
这种设计模式虽然解决了乞丐的问题,但随着游戏规模的扩大,越来越多的职业加入了其中,并且有有很多职业(假设Teacher和Student)有着相同的工作方法,难道我们为每一种职业都重新实现一个work函数么?所以上述设计造成了代码的无法复用,仍然会给我们带来很多问题。
我们是否能够设计出一种模式,不但能解决乞丐问题,还能够解决代码的复用问题呢?好,我们采用如下的设计:
如果你能理解上图的设计思路,那恭喜你,你已经学会策略模式了。
2.策略模式的介绍和设计思路
策略模式定义了算法族,分别封装起来,在使用算法的类中放置接口的引用,让不同的算法实现之间可以相互替换,此模式让算法的变化独立于算法的客户,提高的系统的可维护性和代码的复用。
在设计系统时候,我们首先我们要分开变化和不会变化的部分。就拿上例来说,对于不同职业的人,他们的姓名(name)、性别(Sex)等属性和吃饭(eat)、行走(walk)等行为是不会变化的部分,我们可以将他们留在原来的类中;而工作(work)是随着职业的不同而不同的,所以我们要使用接口将这个行为分离出来。同时为了提高代码的复用率,我们可以写多多个接口的实现,并将他们封装成独立的类,并将接口的引用当作一个属性放在使用该方法的客户类中,利用OO的多态来实现动态的绑定。
3.策略模式用到的设计原则
1 public class People{ 2 3 //属性 4 protected String name; 5 protected String Sex; 6 //算法组接口 7 protected Workable workable; 8 9 public People(String name,String sex){ 10 this.name=name; 11 this.sex=sex; 12 } 13 14 public void eat(){ 15 System.out.println("正在吃饭"); 16 } 17 18 public void walk(){ 19 System.out.println("正在走路"); 20 } 21 22 public void work(){ 23 workable.work(); 24 } 25 }
1 interface Workable{ 2 public void work(); 3 }
1 public class WorkInClass implements Workable{ 2 public void work(){ 3 System.out.println("I work in class"); 4 } 5 } 6 7 public class WorkInFactory implements Workable{ 8 public void work(){ 9 System.out.println("I work in factory"); 10 } 11 } 12 13 public class WorkInCar implements Workable{ 14 public void work(){ 15 System.out.println("I work in car"); 16 } 17 }
1 public class Teacher extends People{ 2 public Teacher(String name,String sex){ 3 super(name,sex); 4 //请注意这里仍然针对具体实现编程了,看起来和设计原则违背 5 //等介绍了下面的设计模式之后会对此进行改进 6 this.workable=new WorkInClass(); 7 } 8 } 9 10 public class Student extends People{ 11 public Student(String name,String sex){ 12 super(name,sex); 13 this.workable=new WorkInClass(); 14 } 15 } 16 17 public class Worker extends People{ 18 public Worker(String name,String sex){ 19 super(name,sex); 20 this.workable=new WorkInFactory(); 21 } 22 } 23 24 public class Driver extends People{ 25 public Driver(String name,String sex){ 26 super(name,sex); 27 this.workable=new WorkInCar(); 28 } 29 }
当有新的职业和工作方法加入时候,工作方法去实现Workable接口,定义新的算法,职业去继承People类,并在自己的构造函数绑定自己职业的工作方法即可。
原文:http://www.cnblogs.com/LDht/p/4881245.html