设计模式之——策略模式

什么是策略模式: 定义了算法族,将他们封装起来,让他们之间可以相互替换,通常由一个接口或抽象类实现。此角色给出所有的具体策略类所需的接口。


  现在我们假设一个场景:父类用户类(User),他有三个子类:游客(Tourist),普通用户(GeneralUser),vip用户(VIPUser)。他们都有一个购买行为。游客不可购买需要注册为普通用户,普通用户原价购买,vip九折购买。我们可以抽象User并加一个抽象方法Buy()。子类各自重写方法Buy()去对应每个购买方式。OK!你很快的实现了这个场景。可以隔几天老板又说了,我们得加一个超级会员,或者我们学腾讯一样,我们加些绿钻会员,粉钻会员,蓝钻会员,黑心会员(啊,呸!是黑钻会员)。你怎么办,难道给每个子类重写方法Buy()吗?其实问题是可以解决,但显得代码重用性极差,不够优雅,思想混乱,重复性代码可能会很多。在设计模式中有一个原则,大概意思就是:不要将可能变化得代码与不会变化得代码混在一起。这样做一旦需求有变哪怕是极小的也是一场灾难。在User中把可能变化的购买行为分出来,用接口BuyBehavior代替。同时在抽象父类中实现Buy()方法。甚至在假设购买方式本身不会变,变得只是用户定义的购买方式,我们可以动态的修改用户的购买方式(当然只是某个对象,想要修改子类的购买方式,只要在子类中写改不同的接口对应的实现类就好了),废话不多说,我们直接看代码:

interface BuyBehavior{     
    public void Buy();
}
//具体有哪些购买方法
class DisAllowBuy implements BuyBehavior{
    @Override
    public void Buy() {
        System.out.println("游客无法购买");
    }
}
class CostPriceBuy implements BuyBehavior{
    @Override
    public void Buy() {
        System.out.println("普通用户原价购买");
    }
}
class DiscountBuy implements BuyBehavior{
    @Override
    public void Buy() {
        System.out.println("vip九折购买");
    }
}


//定义子类的购买方式
class Tourist extends User{                  //将游客的购买方式定义为无法购买
    //注意这里继承了父类保护类型的接口BuyBehavior变量

    public Tourist(){
        bb = new DisAllowBuy();
    }
}
class GeneralUser extends User{                  //将普通用户的购买方式定义为原价购买
    //注意这里继承了父类保护类型的接口BuyBehavior变量
    public GeneralUser(){
        bb = new CostPriceBuy();
    }
}
class VipUser extends User{                  //将vip用户的购买方式定义为九折购买
    //注意这里继承了父类保护类型的接口BuyBehavior变量
    public VipUser(){
        bb = new DiscountBuy();
    }
}
abstract class User{                         //可以动态的修改子类的购买方式
    protected BuyBehavior bb;
    public void setBuyBehavior(BuyBehavior b){
        bb = b;
    }
    public void Buy(){                      //父类实现购买方式而不是将它抽象
        bb.Buy();
    }
}
public class Strategy {
    public static void main(String[] args) {
        User u1 = new Tourist();
        User u2 = new GeneralUser();
        User u3 = new VipUser();
        User uu[] = {u1,u2,u3};
        for(User e:uu){
            e.Buy();
        }
        u1.setBuyBehavior(new CostPriceBuy());
        u1.Buy();
    }

}

输出结果:

游客无法购买
普通用户原价购买
vip九折购买
普通用户原价购买

  我们可以看出代码中将购买方式单独放在接口BuyBehavior中,可以尽可能的将购买方式所有的不同实现方式写全。购买方式完全独立于用户,想要增加用户的类型无非就是增加购买方式,加一个超级会员,那么就编写一个超级会员的购买方式,在超级会员的子类构造函数将变量bb赋予这个实现类。我们从结果可以看到当游客对象u1调用方法setBuyBehavior()就改变了u1的购买方式了。


策略模式UML

这里写图片描述



在项目中怎么用策略模式呢


  不知道大家有没有玩过最近很火的FPS类游戏《绝地求生》。游戏有别于其他Fps游戏的地方在玩家控制的人物刚开始是没有装备的,可以理解为User类的装备变量为null,噢,或者是拳头。然后人物不断去游走找散落在各地的枪,我可以理解就是有一个线程一直在监控玩家行为,当玩家确定捡某把枪的时候,就会去调用类似于上列代码中setBuyBehavior(BuyBehavior bb)。只不过参数为武器类的接口,接口不同的实现类又不同的武器性能。当你捡到一把狙的时候,开枪或者命中的伤害步枪强高就是因为你的狙实现类与步枪的实现类不同。当你不想要狙,换成步枪的时候又调用类似与setBuyBehavior(BuyBehavior bb)的方法;策略模式对于类与类之间解耦非常好用,当你有类似于一直变化的用户类型,而购买方式去很少变化时就可以使用策略模式将他们分开。


  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
前台: (1)注册登录模块:按照学校的相关规定进行注册和登录。 (2)招聘信息查看:高校毕业生们可以网站首页上查看所有的招聘信息,除此之外还可以输入公司名称或岗位名称进行搜索。 (3)用人单位模块:此模块为宣传用人单位的主要功能模块,具体包括用人单位简介、岗位需求及职责及公司介绍等功能。 (4)就业指导:学生朋友们在就业前可以通过此模块获取指导。 (5)新闻信息:为了让用户们可以了解到最新的新闻动态,本系统可以通过新闻信息查看功能阅读近期的新闻动态。 (6)在线论坛:毕业季的同学们可以通过此模块相互交流。 后台: (1)系统用户管理模块:可以查看系统内的管理员信息并进行维护。 (2)学生管理模块:通过此功能可以添加学生用户,还可以对学生信息进行修改和删除。 (3)用人单位管理模块:管理员用户通过此模块可以管理用人单位的信息,还可以对用人单位信息进行查看和维护。 (4)招聘管理模块:管理员通过此功能发布和维护系统内的照片信息。 (5)就业指导管理模块:通过此模块可以编辑和发布就业指导信息,从而更好的帮助就业季的同学们。 (6)论坛管理:通过论坛管理可以查看论坛中的主题帖及里面的回复信息,除此之外还可以对论坛中的信息进行维护和管理。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值