zoukankan      html  css  js  c++  java
  • 设计模式之策略模式

    我们先从一个经典的例子说起,假如现在我应聘去一家公司上班,第一天老板让我设计一个鸭子的类,

    public abstract class Duck {
    
        public void quack(){            //叫唤
            System.out.println("gua...");
        }
        
        public void swim(){                //游泳
            System.out.println("swimming...");
        }
        
        public  abstract void display();//外观
        
    }

    考虑到每个鸭子的外观都不同,所以把外观定为抽象类,

    过了两天,老板决定给鸭子增加一个飞行的方法,that's so easy!,在Duck类里面加上就行了,

    public abstract class Duck {
    
        public void quack(){            //叫唤
            System.out.println("gua...");
        }
        
        public void swim(){                //游泳
            System.out.println("swimming...");
        }
        
        public void fly() {          //飞行
            System.out.println("fly...");
        }
        public  abstract void display();//外观
        
    }

    但是这样做有个问题,有的鸭子不会飞,比如橡皮鸭之类的东东,如果继承这个类的话,也会飞起来,这该肿么办呢?

    可以让不会飞的鸭子在继承Duck类时,覆盖fly()方法,例如:

    public class RubberDuck extends Duck {
    
        @Override
        public void display() {
            System.out.println("I am a rubberDuck");
        }
    
           @Override
        public void fly() {     
            
        }
    }

    有的鸭子即不会飞,也不会叫,也可以通过覆盖来完成,比如诱饵鸭

    public class DecoyDuck extends Duck {
    
        @Override
        public void display() {
            System.out.println("I am a decoyDuck");
        }
    
        @Override
        public void quack() {
            
        }
    
        @Override
        public void fly() {
            
        }    
    }

    但鸭子种类太多,方法也各不相同,每种鸭子都要写一些无用的代码来覆盖父类的方法,实在麻烦,所以我想到了接口,用接口就可以不用写那些无用的代码

    //定义两个接口
    public interface Flyable {  
        public void fly();
    }
    public interface Quackable {
        public void quack();  
    }
    //Duck类可以改写为
    public abstract class Duck {
    
        public void swim(){    //游泳
            System.out.println("swimming...");
        }
        public abstract void display();//外观
    
    }
    //橡皮鸭就可以不用写fly()这种无用的代码
    public class RubberDuck extends Duck implements Quackable{
    
        @Override
        public void display() {
            System.out.println("I am a rubberDuck");
        }
    
        public void quack() {
            System.out.println("RubberDuck's quack...");
        }    
    }

    这又产生一个问题,那就是代码无法像原来继承那样复用了,比如现在有100种各式各样的鸭子,其中50种鸭子的quack()方法一样,如果用上面的方法,就要写50次一模一样的quack(),也是麻烦,这里涉及到了一条重要的规则:找出应用中可能需要变化之处,把它们独立出来,不要和那些不需要变化的代码混在一起

    现在我们分开“变化和不会变化的部分”,建立两组类(完全远离Duck类),一组是和“fly”相关的,一组和“quack”相关,每组类实现各自的动作

    //定义两个接口
    public interface Flyable {  
        public void fly();
    }
    public interface Quackable {
        public void quack();  
    }
    //Duck类可以改写为
    public abstract class Duck {
    
        Flyable fly;
        Quackable quack;
        public void swim(){    //游泳
            System.out.println("swimming...");
        }
        public abstract void display();//外观
    }
    
    public class FlyWithWings implements Flyable{
        public void  fly(){
         //实现了所有有翅膀的鸭子飞行行为。
       }
     }
    public class FlyNoWay implements Flyable{
        public void  fly(){
          //什么都不做,不会飞
        }
     }   
    
    public class Quack implements Quackable{
        public void quack(){
          //实现呱呱叫的鸭子
      }
    }
     
    public class Squeak implements Quackable{
        public void quack(){
          //实现吱吱叫的鸭子 
      }
    }
     
    public class MuteQuack implements Quackable{
        public void quack(){
          //什么都不做,不会叫
      }
    }
    
    
    //橡皮鸭
    public class RubberDuck extends Duck {
    
        public RubberDuck() {
            quack = new MuteQuack();
            fly   = new FlyNoWay();
        }
        @Override
        public void display() {
            System.out.println("I am a rubberDuck");
        }
    
    }

    这样做就比较容易扩展了,

  • 相关阅读:
    把旧表中数据加入到新表中
    mysql字段-创建时间与更新时间
    springboot-maven依赖源
    刚刚下载的IDEA打不开
    matplotlib-实战01
    实战1-数据清理
    python函数(三)
    交换机配置DHCP中继
    python函数(二)
    用事实说话
  • 原文地址:https://www.cnblogs.com/fengz/p/6747566.html
Copyright © 2011-2022 走看看