Java设计模式之策略模式

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
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

NobiGo

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值