Java设计模式之策略模式

来源:互联网 发布:有什么二次元软件 编辑:程序博客网 时间:2024/06/13 23:49

1. 设计模式入门


设计模式不是代码的具体实现,它是解决某一类问题的通用设计方案。
设计模式的本质目的是:使软件工程在维护性、扩展性、变化性、复杂度方面成0(N)
OO设计是原则,设计模式是具体方法、工具。
例如:
在Java里IO流的类设计,为什么把BufferedReader设计成:

new BufferedReader(new FileReader(“F:\test.java”));//而不是设计成:BufferedReader extends FileReader;new BufferedReader("F:\test.java");

2. 策略模式原理


2.1 模拟鸭子项目

2.1.1 从OO的角度设计这个项目

鸭子具有相同的叫声以及都会游泳,但是每只鸭子的颜色不同,比如说有绿头鸭,红头鸭等。

2.1.2 从OO的角度设计这个项目

  • 1.设置鸭子超类
public abstract class SuperDuck {    //颜色让子类去具体实现    public abstract void display();    public void quack(){        System.out.println("~GaGa~");    }    public void swim(){        System.out.println("~In Swim~");    }}
  • 2.生成绿头鸭子类
public class GreenDuck extends SuperDuck {    @Override    public void display() {        // TODO Auto-generated method stub        System.out.println("~show Green Head~");    }}
  • 3.生成红头鸭子类
public class RedDuck extends SuperDuck {    @Override    public void display() {        // TODO Auto-generated method stub        System.out.println("~Show Red Head~");    }}

使用OO基本满足了项目的需求。

2.2 项目的新需求

2.2.1 应对新的需求,看看这个设计的可扩展性

需求1)添加会飞的鸭子
在OO思维解决这个问题,使用:
在鸭子超类中添加这个方法:

public abstract class SuperDuck {    //颜色让子类去具体实现    public abstract void display();    public void quack(){        System.out.println("~GaGa~");    }    public void swim(){        System.out.println("~In Swim~");    }    public void fly(){        System.out.println("In Fly");    }}

2.3 用OO原则解决需求的不足

问题出现:这个fly()让所有的鸭子都飞起来了,这是不科学的
继承问题:对类的局部的变动,尤其是超类的局部变动,会影响其他部分。影响会有溢出效应。
使用覆盖解决问题:
在子类中对超类的方法进行覆盖,在超类中,进行改动的话,必须在子类中进行全面的覆盖。(如果已经生成上千个子类?需要对这些子类重新进行初始化,这个方法并不可行)
需求2)添加石头鸭子,就需要对以上所有方法进行覆盖。

public class StoneDuck extends Duck{}

超类挖的一个坑,每个子类都要填,增加工作量,复杂度O(N^2)

2.4 用策略模式来解决鸭子的项目

目的:使用新的设计模式,应对项目的扩展性,降低复杂度。
1)分析项目变化与不变部分,提取变化部分,抽象成接口+实现;
2)鸭子哪些功能是会根据新需求变化的?叫声、 飞行…
解决方法:接口

public interface  SuperFly();public interface  SuperQuack();

好处:新增行为简单,行为类更好的复用,组合更方便。 既有继承带来的复用好处,没有挖坑。

2.5 重新设计模拟鸭子项目

2.5.1 dx.com.quack(叫声实现)

  • SuperQuack
package dx.com.quack;public interface SuperQuack {    public void quack();}
  • Gaquack
package dx.com.quack;public class Gaquack implements SuperQuack {    @Override    public void quack() {        // TODO Auto-generated method stub        System.out.println("~Ga~Ga~");    }}
  • GeQuack
package dx.com.quack;public class GeQuack implements SuperQuack {    @Override    public void quack() {        // TODO Auto-generated method stub        System.out.println("~Ge~Ge~");    }}
  • NoQuack
package dx.com.quack;import dx.com.stimulate.SuperDuck;public class NoQuack extends SuperDuck {    @Override    public void display() {        // TODO Auto-generated method stub        System.out.println("~  ~  ~");    }}

2.5.2 dx.com.quack(飞行实现)

  • SuperFly
package dx.com.fly;public interface SuperFly {    public void fly();}
  • NoFly
package dx.com.fly;public class NoFly implements SuperFly {    @Override    public void fly() {        // TODO Auto-generated method stub        System.out.println("NO Fly");    }}
  • GoodFly
package dx.com.fly;public class GoodFly implements SuperFly{    @Override    public void fly() {        // TODO Auto-generated method stub        System.out.println("Good Fly");    }}
  • BadFly
package dx.com.fly;public class BadFly implements SuperFly{    @Override    public void fly() {        // TODO Auto-generated method stub        System.out.println("Bad fly");    }}

2.5.3 dx.com.duck

  • SuperDuck
package dx.com.duck;import dx.com.fly.SuperFly;import dx.com.quack.SuperQuack;public abstract class SuperDuck {    public SuperFly superFly;    public SuperQuack superQuack;    public SuperDuck() {    };    public abstract void display();    public void fly() {        superFly.fly();    }    public void quack() {        superQuack.quack();    }    public void setFly(SuperFly fly) {        this.superFly = fly;    }    public void setQuack(SuperQuack quack) {        this.superQuack = quack;    }}
  • GreenDuck
package dx.com.duck;import dx.com.fly.GoodFly;import dx.com.quack.Gaquack;public class GreenDuck extends SuperDuck {    public GreenDuck(){        superFly = new GoodFly();        superQuack = new Gaquack();    }    @Override    public void display() {        // TODO Auto-generated method stub        System.out.println("show green head");    }}
  • RedDuck
package dx.com.duck;import dx.com.fly.BadFly;import dx.com.quack.GeQuack;import dx.com.quack.SuperQuack;public class RedDuck extends SuperDuck{    public RedDuck(){        superFly = new BadFly();        superQuack = new GeQuack();    }    @Override    public void display() {        // TODO Auto-generated method stub        System.out.println("show red head");    }}

2.6 总结策略模式定义

策略模式:分别封装行为借口,实现算法族,超类里放行为接口对象,在子类里具体设定行为对象。原则就是:分离变化备份,封装接口,基于接口编程各种功能。此模式让行为算法的变化独立于算法的使用者。

3. 策略模式注意点

  • 1.分析项目中变化部分与不变部分
  • 2.多用组合少用继承;用行为类组合,而不是行为的继承。更有弹性
  • 3.设计模式有没有相应的库直接使用?有些库或框架本身就用某种设计模式设计的

代码链接:http://download.csdn.net/detail/it_dx/9667812

0 0
原创粉丝点击