策略模式(Strategy Pattern):定义了算法族,分别封装起来,让它们之间可相互替换,此模式让算法的变化独立于使用算法的客户。

好 了,对于定义,肯定不是一眼就能看明白的,不然这篇文章就收尾了,对于定于大家简单扫一眼,知道个大概,然后继续读下面的文章,读完以后再来回味,效果嘎 嘣脆。大家应该都玩过武侠角色游戏,下面我就以角色游戏为背景,为大家介绍:假设公司需要做一款武侠游戏,我们就是负责游戏的角色模块,需求是这样的:每 个角色对应一个名字,每类角色对应一种样子,每个角色拥有一个逃跑、攻击、防御的技能。

初步的代码

    package com.zhy.bean;  
      
    /** 
     * 游戏的角色超类 
     *  
     * @author zhy 
     *  
     */  
    public abstract class Role  
    {  
        protected String name;  
      
        protected abstract void display();  
      
        protected abstract void run();  
      
        protected abstract void attack();  
      
        protected abstract void defend();  
      
    }  

[java] view plain copy
在CODE上查看代码片派生到我的代码片

    package com.zhy.bean;  
      
    public class RoleA extends Role  
    {  
        public RoleA(String name)  
        {  
            this.name = name;  
        }  
      
        @Override  
        protected void display()  
        {  
            System.out.println("样子1");  
        }  
      
        @Override  
        protected void run()  
        {  
            System.out.println("金蝉脱壳");  
        }  
      
        @Override  
        protected void attack()  
        {  
            System.out.println("降龙十八掌");  
        }  
      
        @Override  
        protected void defend()  
        {  
            System.out.println("铁头功");  
        }  
      
    }  

没几分钟,你写好了上面的代码,觉得已经充分发挥了OO的思想,正在窃喜,这时候项目经理说,再添加两个角色

RoleB(样子2 ,降龙十八掌,铁布衫,金蝉脱壳)。

RoleC(样子1,拥有九阳神功,铁布衫,烟雾弹)。

于是你觉得没问题,开始写代码,继续集成Role,写成下面的代码:

    package com.zhy.bean;  
      
    public class RoleB extends Role  
    {  
        public RoleB(String name)  
        {  
            this.name = name;  
        }  
      
        @Override  
        protected void display()  
        {  
            System.out.println("样子2");  
        }  
      
        @Override  
        protected void run()  
        {  
            System.out.println("金蝉脱壳");//从RoleA中拷贝  
        }  
      
        @Override  
        protected void attack()  
        {  
            System.out.println("降龙十八掌");//从RoleA中拷贝  
        }  
      
        @Override  
        protected void defend()  
        {  
            System.out.println("铁布衫");  
        }  
      
    }  
    package com.zhy.bean;  
      
    public class RoleC extends Role  
    {  
        public RoleC(String name)  
        {  
            this.name = name;  
        }  
      
        @Override  
        protected void display()  
        {  
            System.out.println("样子1");//从RoleA中拷贝  
        }  
      
        @Override  
        protected void run()  
        {  
            System.out.println("烟雾弹");  
        }  
      
        @Override  
        protected void attack()  
        {  
            System.out.println("九阳神功");  
        }  
      
        @Override  
        protected void defend()  
        {  
            System.out.println("铁布衫");//从B中拷贝  
        }  
      
    }  

写完之后,你自己似乎没有当初那么自信了,你发现代码中已经存在相当多重复的代码,需要考虑重新设计架构了。于是你想,要不把每个技能都写成接口,有什么 技能的角色实现什么接口,简单一想,觉得这想法高大尚啊,但是实现起来会发现,接口并不能实现代码的复用,每个实现接口的类,还是必须写自己写实现。于 是,we need change ! 遵循设计的原则,找出应用中可能需要变化的部分,把它们独立出来,不要和那些不需要变化的代码混在一起。我们发现,对于每个角色的 display,attack,defend,run都是有可能变化的,于是我们必须把这写独立出来。再根据另一个设计原则:针对接口(超类型)编程,而 不是针对实现编程,于是我们把代码改造成这样:

    package com.zhy.bean;  
      
    public interface IAttackBehavior  
    {  
        void attack();  
    }  
    package com.zhy.bean;  
      
    public interface IDefendBehavior  
    {  
        void defend();  
    }  
    package com.zhy.bean;  
      
    public interface IDisplayBehavior  
    {  
        void display();  
    }  
    package com.zhy.bean;  
      
    public class AttackJY implements IAttackBehavior  
    {  
      
        @Override  
        public void attack()  
        {  
            System.out.println("九阳神功!");  
        }  
      
    }  
    package com.zhy.bean;  
      
    public class DefendTBS implements IDefendBehavior  
    {  
      
        @Override  
        public void defend()  
        {  
            System.out.println("铁布衫");  
        }  
      
    }  
    package com.zhy.bean;  
      
    public class RunJCTQ implements IRunBehavior  
    {  
      
        @Override  
        public void run()  
        {  
            System.out.println("金蝉脱壳");  
        }  
      
    }  

这时候需要对Role的代码做出改变:

    package com.zhy.bean;  
      
    /** 
     * 游戏的角色超类 
     *  
     * @author zhy 
     *  
     */  
    public abstract class Role  
    {  
        protected String name;  
      
        protected IDefendBehavior defendBehavior;  
        protected IDisplayBehavior displayBehavior;  
        protected IRunBehavior runBehavior;  
        protected IAttackBehavior attackBehavior;  
      
        public Role setDefendBehavior(IDefendBehavior defendBehavior)  
        {  
            this.defendBehavior = defendBehavior;  
            return this;  
        }  
      
        public Role setDisplayBehavior(IDisplayBehavior displayBehavior)  
        {  
            this.displayBehavior = displayBehavior;  
            return this;  
        }  
      
        public Role setRunBehavior(IRunBehavior runBehavior)  
        {  
            this.runBehavior = runBehavior;  
            return this;  
        }  
      
        public Role setAttackBehavior(IAttackBehavior attackBehavior)  
        {  
            this.attackBehavior = attackBehavior;  
            return this;  
        }  
      
        protected void display()  
        {  
            displayBehavior.display();  
        }  
      
        protected void run()  
        {  
            runBehavior.run();  
        }  
      
        protected void attack()  
        {  
            attackBehavior.attack();  
        }  
      
        protected void defend()  
        {  
            defendBehavior.defend();  
        }  
      
    }  

每个角色现在只需要一个name了:

    package com.zhy.bean;  
      
    public class RoleA extends Role  
    {  
        public RoleA(String name)  
        {  
            this.name = name;  
        }  
      
    }  

现在我们需要一个金蝉脱壳,降龙十八掌!,铁布衫,样子1的角色A只需要这样:

    package com.zhy.bean;  
      
    public class Test  
    {  
        public static void main(String[] args)  
        {  
      
            Role roleA = new RoleA("A");  
      
            roleA.setAttackBehavior(new AttackXL())//  
                    .setDefendBehavior(new DefendTBS())//  
                    .setDisplayBehavior(new DisplayA())//  
                    .setRunBehavior(new RunJCTQ());  
            System.out.println(roleA.name + ":");  
            roleA.run();  
            roleA.attack();  
            roleA.defend();  
            roleA.display();  
        }  
    }  

最后总结一下OO的原则:

1、封装变化(把可能变化的代码封装起来)

2、多用组合,少用继承(我们使用组合的方式,为客户设置了算法)

3、针对接口编程,不针对实现(对于Role类的设计完全的针对角色,和技能的实现没有关系)

 

posted on 2016-09-08 20:06  青年程序猿  阅读(169)  评论(0)    收藏  举报