设计模式--策略模式

策略模式

场景

小张,刚刚参加工作,就职于一家游戏公司,公司正在做一款动作游戏,隔壁的老王(没错就是隔壁王叔叔^_^)负责带小张,老王交代小张实现一个功能:游戏角色可以切换手上的武器对其其他角色进行攻击。

小张的实现

小张,想这不是很简单的是事情吗!小张,很快就设计出了角色可以根据武器进行攻击。

    /**
    *
    *角色
    **/
    class User(){

        private static  Logger logger = LoggerFactory.getClass(User.class); 

        public void attack(String weapon){
            if("club".equal(waepon)){
                logger.info("使用木棍伤害为30");
            }else if("fist".equal(weapon)){
                logger.info("拳头的伤害为10");
            }else if("pistol".equal(weapon)){
                logger.info("手枪的伤害为50")
            }else if("automaticrifle".equal(weapon)){
                looger.info("自动步枪的伤害为100");
            }
        }
    }

    /**
    *游戏,测试小张的代码
    *
    **/
    class Game(){
        public static void main(){
            User user = new User();
            user.attack("club");
            user.attack("fist");
        }
    }

小张,满心欢喜的把代码给了老王看,老王看了一眼,深切的眼神关怀着小张。
老王:小张啊,如果产品为了增加盈利,现在要再增加一种武器怎么办?

小张(心想这还不简单): 再加一个if 做个判断,就可以了。

老王:在学校的时候,学习面向对象的时候,老师有没有讲过设计原则。

小张:老师有讲过,大概就是要多用继承,对扩展开放,对修改关闭。

老王:那你再仔细想想,你的代码有没有对扩展开放,对修改关闭。

小张想想了,觉得自己太大意,竟然违反了设计原则,就怪自己太心急,急着完成任务,没有在接到需求实现代码之前好好设计一下

老王:小张,你可以使用策略模式,对你的代码改造一下,你先百度谷歌了解一下什么是策略模式,之后改造好了代码,给我再看一下。

小张,赶紧去百度谷歌一下,去了解策略模式了。

小张新的实现–策略模式

小张根据了解的策略模式,对应到自己的代码。

    /**
    *   武器接口
    **/
interface Weapon{

    pubic void attack();

}
    /**
    * 木棍
    **/
class Club implements Weapon{
        private static Logger logger = LoggerFactory.getClass(Club.class);

        public void attack(){
            logger.info("使用木棍的伤害为30");
        }

}

    /**
    * 拳头 
    **/
class Fist implements Weapon{

    private static Logger logger = LoggerFactory.getClass(Fist.class);

    public void attack(){
            logger.info("拳头的伤害为10");
    }
}   

    /**
    * 手枪
    **/
class Pistol implements Weapon{

    private static Logger logger = LoggerFactory.getClass(Pistol.class);

    public void attack(){
        logger.info("手枪的伤害为50");
    }

}   

 /**
 * 自动步枪
 **/
class  Automaticrifle implements Weapon{

    private static Logger logger = LoggerFactory.getClass(Automaticrifle.class);

    public void attack(){
        logger.info("自动步枪的伤害为100");
    }

}

/**
* 新的角色
**/
class User{

    private Weapon weapon;

    public User(){ //默认为拳头
        weapon = new Fist(); 
    }

    pubic void chooseWeapon(Weapon weapon){
        this.weapon = weapon;
    }

    public void attack(){
        weapon.attack();
    }

}

/*
*游戏
**/
class Game{

    public static void main(String [] args){

        User user = new User();//初始默认为拳头
        user.attack();
        user.setWeapon(new Club());
        user.attack();

    }
}

下面是小张画的类图

设计模式--策略模式_第1张图片

现在小张的代码符合‘开闭原则’:对扩展开放,对修改关闭,如果要加一种新的武器,只需要继承Weapon,角色使用方法chooseWeapon()就可以变换武器。

小张,马上给老王看了自己的类图和代码,老王连连夸奖。

实现完了,老王让小张总结一下什么是策略模式,巩固下来。

策略模式

我们加入了新的接口和新的类,weapon是武器的接口,所有武器都要继承它,武器接口作为角色的域。角色初始化使用拳头作为武器,并且我们在角色user类增加了新的方法chooseWeapon()用来切换武器。
来看看我们新的代码与之前的区别:

  • 我们把武器独立出来了,对于角色来说它是经常变化的。
  • 角色是针对接口Weapon编程,而不是针对实现编程。

策略模式定义了算法族,分别封装起来,让他们之间可以相互转换,此模式让算法的变化独立于使用算法的客户。

设计要点

  • 知道OO基础,并不足以让你设计出良好的OO系统
  • 良好的OO设计必须具备可复用,可扩充,可维护三个特性
  • 模式可以让我们建造出具有良好OO设计质量的系统
  • 模式被认为是历经验证的OO设计经验
  • 模式不是特定代码,而是针对设计问题的通用解决方案。你可把他们应用到特定的应用中。
  • 模式不是被发明的,而是被发现的。
  • 大多数的模式和原则,都着眼于软件变化的主题
  • 我们常把系统中会变化的部分抽出来封装
  • 模式让开发人员之间有共享的语言,能够最大化沟通的价值

没有疑问了吗?

我们看到,开始的代码很简单几个if else就解决了问题,之后使用了设计模式,代码复杂度增加了很多,难道设计模式真的就这么好?
是的,使用设计模式会增加结构的复杂,会有很的类,会增加开发人员的理解,但是我们之间有共享词汇,我告诉你,我是使用了策略模式,你就很快能够立理解,如果没有共享词汇,那么看类图也可以看懂,但是如果没有共享词汇,没有类图,那么使用设计模式,会增加开发人员之间的理解。

设计模式会增加系统中类的数量,会增加理解代码的复杂度,但是这些是值得的,为了创造易于扩展的系统,这些都是值得的,并且如果有共享词汇那么复杂度也就不会那么严重了。

最后,喊出我们口号

为设计低耦合,高内聚的软件而努力!!





关注我的公众号第一时间阅读有趣的技术故事
扫码关注:

也可以在微信搜索公众号即可关注我:codexiulian
渴望与你一起成长进步!

你可能感兴趣的:(设计模式,设计模式-入门指南)