设计模式(一)之策略模式

策略模式定义了算法族,分别封装起来,让它们之间可以互相替换,此模式让算法的变化独立于使用算法的客户。这抽象的定义看得醉了吧,还是来点代码比较“温馨”。

现在的需求是要设计一个Person类,要包含几个“人”所拥有的东西、特征,如代码:

public abstract class Person {public void eat() {// 我会吃东西System.out.println("我会吃");}public void swim() {// 我会游泳System.out.println("我会游泳");}public void hasHouse() {// 我有房System.out.println("我有房");}public abstract void display();// 人的长相}如你所见,Person类中有个四个方法,每个人的长相不一样,有的颜值高得爆表,有的颜值……所以把display()设计成抽象方法。现在我们要具体化一个高富帅,一个屌丝。代码如下:public class RichPerson extends Person{@Overridepublic void display() {System.out.println("我是高富帅");}@Overridepublic void swim() {//这是继承超类的swim()方法super.swim();}@Overridepublic void eat() {//这是继承超类的eat()方法super.eat();}@Overridepublic void hasHouse() {//这是继承超类的hasHouse()方法super.hasHouse();}}public class PoorPerson extends Person {@Overridepublic void display() {System.out.println("我是屌丝");}<pre name="code" class="java">@Overridepublic void swim() {//这是继承超类的swim()方法super.swim();}@Overridepublic void eat() {//这是继承超类的eat()方法super.eat();}@Overridepublic void hasHouse() {//这是继承超类的hasHouse()方法super.hasHouse();}}高富帅与屌丝的座谈:

高富帅:我家那别墅里有个超大size的游泳池,每天都住那房子,游泳,日子还可以。

屌丝:(擦了泪)我没房也不会游泳,还能拿到这个有房会游泳的称号(方法)?我只会吃啊有木有,泪崩啊有木有T^T

高富帅:好吧。。。

听完他们的座谈终于才知道,Person类不能这么干呀,这不是为难屌丝么,,我也是屌丝呀!!Person类改!!

怎么改呢?我们先分析下:

因为不是所有的人都能有Person超类里面的东西,比如没房,没车的,总不能强加给人家吧,于是我们想到了抽取封装,好,把房跟游泳这两个方法设计成接口,然后有房也会游泳的人实现它们,上代码:

(设计原则一:找出应用中可能需要变化之处,把它们独立出来,不要和那些不需要变化的代码混在一起)

我们先把需要变化的地方独立出来,即将有房跟会游泳封装成接口:

public interface HouseApi {public void hasHouse();}public interface SwimApi {public void swim();}然后再实现接口:public class PoorPerson extends Person implements HouseApi, SwimApi {@Overridepublic void display() {System.out.println("我是屌丝");}@Overridepublic void swim() {//这是实现SwimApi接口的方法super.swim();}@Overridepublic void eat() {//这是继承Person的方法super.eat();}@Overridepublic void hasHouse() {//这是实现HouseApi接口的方法super.hasHouse();}}你没看错,屌丝逆袭了,开始有了房,建了游泳池,也会游泳了,但是屌丝需要的东西越来越多了,准备买车,买金手表,买苹果,买买买。。。这样一来就会出现:public class PoorPerson extends Person implements HouseApi, SwimApi,CarApi, WatchApi,AppleApi….. { }屌丝终于升职加薪,出任CEO,迎娶白富美,走向了人生巅峰。但是他的物质需求还在不断的变多,我们还得老帮屌丝改这代码,不断的implements,hi爆了。。

看来公共方法留在超类显得设计合理,但不是共享的方法抽取出来也不能只用一个接口来封装了(设计原则二:针对接口编程,而不是针对实现编程;设计原则三:多用组合,少用继承),设计原则二我是这么理解的,如果只是让继承超类的对象(PoorPerson类)实现接口,就是进行针对实现编程,接下来是针对接口编程,思路分析:如果我们通过对每个接口都建立一个类去实现它,然后在超类中设置这些类的变量,最后在具体化的类中实例化这些类,那么这就是组合。好像还是好抽象是吧,哟西,我们把”思路分析“这段话分割,然后边上代码。

一:如果我们通过对每个接口都建立一个类去实现它,代码如下:

public class HouseFunction implements HouseApi{@Overridepublic void hasHouse() {//实现HouseApi接口的方法System.out.println("我有房");}}public class SwimFunction implements SwimApi {@Overridepublic void swim() {//实现SwimApi接口的方法System.out.println("我会游泳");}}通过建立上面两个类,分别实现”有房“接口、”游泳“接口。

二:然后在超类中设置这些类的变量,代码如下:

public abstract class Person {public HouseApi houseApi;public SwimApi swimApi;public void hasHouse() {houseApi.hasHouse();}public void canSwim() {swimApi.swim();}public void eat() {System.out.println("我会吃");}}三:最后在具体化的类中实例化这些类public class RichPerson extends Person {public RichPerson() {swimApi = new SwimFunction();houseApi = new HouseFunction();}@Overridepublic void hasHouse() {// 我有房super.hasHouse();}@Overridepublic void canSwim() {// 我会游泳super.canSwim();}@Overridepublic void display() {System.out.println("我是高富帅");}}RichPerson类继承了Person类,因此拥有hasHouse()、canSwim()方法。

好了,刚才那段思路分析分割后对应的没段代码都贴上去,还差一句就是“那么这就是组合”。

最后就是测试代码:

public class Test {public static void main(String[] args) {Person richPerson = new RichPerson();richPerson.canSwim();richPerson.hasHouse();}}打印结果:

这就是我对策略模式的理解:超类中变化多的抽取封装成接口,通过一个中间类实现,在超类中设置所需要的类的变量,然后在具体化的类中重载其方法,达到对象之间的相互独立,让代码更加灵活。

原以为“得不到”和“已失去”是最珍贵的,可原来把握眼前才是最重要的。

设计模式(一)之策略模式

相关文章:

你感兴趣的文章:

标签云: