策略设计模式理解

我们开发过程中,常因为一开始的架构不怎么合理而有可能造成后边客户或者项目经理改需求时,造成我们需要修改原来的代码,一方面是可能写的时间久了回顾起来麻烦,另一方面是牵一发而动全身,改动一个地方造成所有的地方都需要改动,由此可见一个好的架构是多么重要。那么今天给大家讲一种策略设计模式来定义一个利于扩展的框架。

 
简单举个例子,我们开发一款游戏如果有需要定义一个角色,有武器攻击,有武器防御,那我们可能会觉得很简单,然后一开始定义就直接定义一个父类,再加一个子类实现,代码如下:
abstract class Role {
    protected String name;
 
    protected abstract void attack();
 
    protected abstract void defend();
 
}
子类实现如下:
class RoleA extends Role {
 
    public RoleA(String name) {
        this.name = name;
    }
 
    protected void attack() {
        System.out.println("多兰剑");
    }
 
    protected void defend() {
        System.out.println("多兰盾");
    }
}
 
那么这个时候项目经理告诉你改需求了,又新创建了一个角色法师他也有攻击也有防御,这个时候你又得重新创建一个类
class RoleB extends Role {
 
    public RoleB(String name) {
        this.name = name;
    }
 
    protected void attack() {
        System.out.println("多兰戒");
    }
 
    protected void defend() {
        System.out.println("多兰盾");
    }
}
 
这个时候你会发现代码重用的效果根本就没有达到,而且如果我人物角色又添加了其他的攻击方式,或者有多个武器装备的时候,就得改源代码了,那么今天我们先解决这个代码重用且利于扩展的问题,这里就引出我们的策略设计模式了,至于多个攻击方式,我们后边给大家介绍装饰者设计模式再说。那么重新定义该怎么定义呢,首先,我们把这些可变的攻击方式抽取出来,单独形成一个接口:
//攻击的接口
interface Attackable{
    void attack();
}
 
 
//防御的接口  
interface Denfenseable{
    void denfense();
}
 
其次,攻击方式我们单独实现攻击接口,防御方式单独实现防御接口
class 多兰剑 implements Attackable{
 
    public void attack() {
        System.out.println("多兰剑攻击犀利");
    }
}
 
 
class 多兰盾 implements Denfenseable{
 
    public void denfense() {
        System.out.println("防御我在行");
    }
 
}
 
class 多兰戒 implements Attackable{
 
    public void attack() {
        System.out.println("多兰戒法强高");
    }
}
 
那么我们在抽象一个共同的父类出来,定义一些每个角色共有的一些属性
abstract class Role{
    public String name;
    Attackable a;            //将接口的引用封装到Role中,利用多态来更利于变化
    Denfenseable d;
 
    public Role(){}
 
    public void setAttackable(Attackable a){
        this.a = a;
    }
 
    public void setDenfenseable(Denfenseable d){
        this.d = d;
    }
 
    protected void attack() {       
         a.attack();    
    }
 
    protected void defend() {       
        d.denfense();   
    }
}
 
这个时候我们需要角色A,比如剑圣的话,就可以直接创建剑圣来实现Role类
class RoleA extends Role{
 
    public RoleA(String name){
        this.name = name;
    }
}
真正调用过程中直接
RoleA a = new RoleA ("剑圣");
        a.setAttackable(new 多兰剑());
        a.setDenfenseable(new 多兰盾());
 
        a.attack();
        a.defend();
这样即重用了代码,又降低了耦合。一举多得。
 
那么总结起来的话:

策略模式:建立行为族,将不同的行为分别封装,同时彼此可相互替代,算法的变化可以独立于使用者。
优点:提高了可复用性,将行为和使用者解耦出来

应用场景:

1、多个类只区别在表现行为不同,可以使用Strategy模式,在运行时动态选择具体要执行的行为。

2、 需要在不同情况下使用不同的策略(算法),或者策略还可能在未来用其它方式来实现。(具体实现可任意变化或扩充)

3、 对客户隐藏具体策略(算法)的实现细节,彼此完全独立。

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
posted @ 2016-07-10 09:04  波波老湿  阅读(189)  评论(0编辑  收藏  举报