一、为什么要使用模式呢?
我们在编码的过程当中,会写很多看起来很臃肿的代码,我们需要对这些代码的结构进行优化与重构。将一些比较稳定的,不容易改变的代码给它提取出来,放到一个接口或者是抽象类当中,然后将一些经常变动的代码放进具体的实现类当中,即接口与抽象类的子类当中,这样使我们所编写的代码具有强类聚,弱偶合的特点,这样使们我的程序具有很好的扩展性。
怎么来理解扩展性呢?
也就是说,我们经常会遇到需求不断改变的情况,一会说xxx你能不能给我实现xxx功能,一会儿又说你帮我在将xxx功能做个补充。此时所有的行动都集中在了一个字上面,那就是“变”。转到程序代码上来说,是怎么一回事儿呢?那就是要能够扩展功能,怎么办呢?使用接口、抽象类、具体实现的子类呗,把它们几个有条理的揉在一起。比如在接口中新增一个方法,然后在不同的子类当中去分别实现。或者说,在接口中定义方法,由抽象类实现接口,然后由具体的实现子类有选择的去实现接口中的方法。这些操作与设计模式当然是紧密相关的。
二、什么是策略模式?为什么要使用策略模式,它是来干什么的,它主要解决的问题是什么呢?
策略模式主要是解决类继承的一个问题。什么问题呢?
我们都知道,多个子类在继承了父类之后,子类中就可以使用父类中的方法,那么,如果当我们过一段时间之后,对父类中的某一个方法做一下修改,那么情况是怎样的呢?在多个子类中使用的这个方法,就同时受到影响。举个例子,我有一个鸭子类,这个鸭子类有一个方法叫做jiaoShen(),它有这样几个子类,黑鸭子,白鸭子类,这两个类里面都使用了父类jiaoShen()这个方法,如果在应用程序运用一段时间之后,一个不怎么了解这个应用程序的人来对超类鸭子类的jiaoShen()方法的代码做了一些修改,这时候,麻烦就大了,整个系统肯定就成问题了啊,子类里面的调用与之前的调用肯定不一样了,这就坏事了。
那么我们该怎么样来解决这个问题呢?我要保证我的这个jiaoShen()这个方法的改动,即不影响到黑鸭子,又不影响到白鸭子。我把叫声这个类定义成一个IJiaoShen接口,然后怎么做呢?在IJiaoShen接口中定义一个jiaoShen()这样一个方法,然后写几个不同叫声的子类去实现IJiaoShen这个接口,例如DiaoIJiaoShenImpl,XiaoIJiaoShenImpl,最后在这些子类中去实现jiaoShen()这个方法,也就是具体怎么叫.
为了使jiaoShen()这个方法能够在不同的子类中得到不同的叫声,因此只需要鸭子这个超类里面创建一个IJiaoShen接口类的一个引用,然后通过set()方法将这个引用赋予具体的叫声类,就可以得到不同的叫声了。子类在使用父类中的jiaoShen()这个方法的时候,它就可以得到不同的叫声了,即黑鸭子叫黑鸭子的,白鸭子叫白鸭子的。
三、策略模式演示代码
package com.celuemodel;
public class Duck {
protected IJiaoShen jiaoShen;
public void setJiaoShen(IJiaoShen jiaoShen) {
this.jiaoShen = jiaoShen;
}
public void swim(){
System.out.println("鸭子正在游泳!");
}
public void run(){
System.out.println("鸭子跑起来了!");
}
public void jiaoShen(IJiaoShen jiaoShen){
}
}
package com.celuemodel;
public class BlackDuck extends Duck {
public void jiaoShen(IJiaoShen jiaoShen){
System.out.println("黑鸭子叫起来了!");
jiaoShen.jiaoShen();
}
}
package com.celuemodel;
public class WhiteDuck extends Duck {
public void jiaoShen(IJiaoShen jiaoshen){
System.out.println("白鸭子叫起来了!");
jiaoshen.jiaoShen();
}
}
package com.celuemodel;
public interface IJiaoShen {
public void jiaoShen();
}
package com.celuemodel;
public class XiaoIJiaoShen implements IJiaoShen {
@Override
public void jiaoShen() {
System.out.println("小叫声!");
}
}
package com.celuemodel;
public class DaIJiaoShen implements IJiaoShen {
@Override
public void jiaoShen() {
System.out.println("大叫声!!!");
}
}
package com.celuemodel;
import org.junit.Before;
import org.junit.Test;
public class DuckTest {
private Duck duck;
@Before
public void setUp() throws Exception {
// duck = new WhiteDuck();
duck = new BlackDuck();
}
@Test
public void testJiaoShen(){
IJiaoShen ijiaoshen1 = new DaIJiaoShen();
IJiaoShen ijiaoshen2 = new XiaoIJiaoShen();
duck.jiaoShen(ijiaoshen1);
duck.jiaoShen(ijiaoshen2);
}
}