zoukankan      html  css  js  c++  java
  • 设计模式--策略模式(strategy)

    1.策略模式(strategy ['strætədʒi])

          我的理解是:方案候选模式 (反正关键就是有很多的候选,哈哈)

         看了很多例子,都是在说鸭子的,那个例子很好,在这里可以看

        他们生产鸭子,我们就制造人

         父类 Person类

    1 public abstract class Person {
    2     //唱歌可就不一样了,唱法不同,唱功不同;而且哑巴不能唱歌
    3     public void singing(){
    4         System.out.println("我要唱歌");
    5     }
    6     
    7     //吃饭,大家没什么区别吧
    8     public abstract void eating();
    9 }
    View Code

     /*每个人都会吃饭,所以eating()可以继承,但singing()就不能一样处理了,因为有些人天生不能发声,或者差别很大

           所以在Person类中就不应该写这个方法,否则Dummy哑巴类就会从Person类继承到singing(),这明显是不合理的,

           而这里可以考虑将singing()独立成一个singable接口

    1 public interface Singable {
    2      public void sing();
    3 }
    View Code

        实现singable的ZhangSan:

    public class ZhangSan extends Person implements Singable{
        @Override
        public void sing() {
            // TODO Auto-generated method stub
            
        }
        
    }
    View Code

           再根据需要实现这个接口,原理上是可以实现,但是接口有个缺点:

           就是不能实现具体的方法:接口什么都不做,你实现后还是要写代码,根本做不到代码重用,如果实现接口的类数量很大的话

           那这个工作量很不划算。

          **虽然每个人唱歌都不同,而且还有人不能唱,但其实唱歌的种类是可以预计的

             唱法也就那么几种:通俗,美声,民族,R&B·····

        接口是不能重用代码,那我们就先预先实现一组的接口实现类

      通俗唱法:

    public class TongSuSinging implements Singable {
    
        @Override
        public void sing() {
            System.out.println("找不到方向,到彩虹天堂·····");
        }
    
    }
    View Code

    美声唱法:

    public class MeiShengSinging implements Singable{
    
        @Override
        public void sing() {
            System.out.println("you and me,together.");
        }
    
    }
    View Code

    民族唱法:

    public class MinZuSinging implements Singable{
    
        @Override
        public void sing() {
            System.out.println("五十六个民族,五十六枝花....");
        }
        
    }
    View Code

       这里,我们不打算直接实现singable接口类,而是使用了组合,所以父类Person类,修改成:

    public abstract class Person {
        //使用组合,将Singable作为Person的成员变量
        private Singable singable;
        //再增加动态赋值的方法
        public void setSingable(Singable s){
            singable = s;
        }
        //此时的sing()方法应该这样写
        public void sing(){
            singable.sing();//这里就是面向接口编程,可以使用多态
        }
        
        //吃饭,大家没什么区别吧
        public abstract void eating();
    }
    View Code

    李四类,

    1 public class LiSi extends Person {
    2 
    3     @Override
    4     public void eating() {
    5         // TODO Auto-generated method stub
    6         
    7     }
    8 
    9 }
    View Code

    测试类Test

     1 public class Test {
     2 
     3     public static void main(String[] args) {
     4         LiSi ls = new LiSi();
     5         //想要美声唱法,那就生成美声唱法的对象,但是类型统一用Singable
     6         Singable s = new MeiShengSinging();
     7         ls.setSingable(s);
     8         ls.sing();
     9 
    10         //想要通俗唱法,就生成通俗唱法的对象
    11         s = new TongSuSinging();//调用的代码完全不变,仅仅是new的对象类型变了而已
    12         ls.setSingable(s);
    13         ls.sing();
    14     }
    15 
    16 }
    View Code

    我也说一下我对策略模式的看法吧,有错误欢迎指正,大家共同进步嘛

    优势:

          如上所述,第一:避免了普通继承的一味重复,因为不变的内容还留在父类中,会改变的内容通过组合的方式来加成;

                        第二:同时使用了面向接口编程,代码修改率大大变小(其实所有的设计模式都有这个优点,不再是一次性代码了)

                        第三:用户要实现不同的功能是只要实现接口,生成新的类就可以了,并且这些类之间是可以随时替换的(因为多态嘛)

    缺点:第一:还是要生成不少类(每个方法一个类···)

            第二:你要预先知道大概要生成多少个类,(虽然总数不能确定,但变化是可以预见的情况下,才推荐使用策略模式)

       */

    (PS:要写一篇好的博客真的好辛苦也好不容易啊····)

    最后推荐大家看这两篇博客 12

        

  • 相关阅读:
    Linux 中改变主机名的 4 种方法
    如何成为优秀开发人员(一):怎样算是优秀的?
    Java中需要知道的关键字
    Java集合类常见的问题
    如何在 Linux 上复制文件/文件夹到远程系统?
    你还在 Select * 吗?
    技术人解决问题的思路
    如何创建编程语言,以及设计决策中的内容?
    Java内存溢出异常(下)
    如何在 Linux 中查看可用的网络接口
  • 原文地址:https://www.cnblogs.com/tommy-huang/p/4268489.html
Copyright © 2011-2022 走看看