• java设计模式之策略模式


    最近学习了设计模式方面的一些知识,感觉设计模式真的太重要了,深感之前写的代码就是渣啊,只是为了实现功能,一点复用性都没有,都是一次性代码,这个以后要改。

    问题:以鸭子为例,我们关心它的几个属性:叫、吃、飞、外观。所有的鸭子都会叫、吃,但是并不是所有的鸭子都会飞,外观都有,但不同种类不一样。我们就简单设计A、B、C...类表示。

    第一种方式:

     1 public class ADuck{
     2     public void sing(){
     3         System.out.println("gua gua...");
     4     }
     5     public void eat(){
     6         System.out.println("I love fish.");
     7     }
     8     public void color(){
     9         System.out.println("I am black.");
    10     }
    11 }
    12 public class BDuck{
    13     public void sing(){
    14         System.out.println("gua gua...");
    15     }
    16     public void eat(){
    17         System.out.println("I love grass");
    18     }
    19     public void color(){
    20         System.out.println("I am yellow");
    21     }
    22 }

    这种方式就是典型的一次性代码。第二种实现方式:

     1 public class Duck{
     2     public void sing(){
     3         System.out.println("gua gua...");
     4     }
     5     public abstract void eat();
     6     public abstract void color();
     7 }
     8 
     9 public class ADuck extends Duck{
    10     public void eat(){
    11         System.out.println("I love fish.");
    12     }
    13     public void color(){
    14         System.out.println("I am black");
    15     }
    16 }

    BDuck实现同理,这样就把功能相同的代码写在基类里,子类实现不一样的代码,从而实现了代码的复用。但是,这还是不够好的。

    如果此时有了新需求,要加一个飞的功能。那么我们只能向下面这样在基类中添加了,不会飞的不实现该功能即可:

    public class Duck{
        public void sing(){
            System.out.println("gua gua...");
        }
        public abstract void eat();
        public abstract void color();
        public abstract void fly();
    }
    
    public class ADuck extends Duck{
        public void eat(){
            System.out.println("I love fish.");
        }
        public void color(){
            System.out.println("I am black.");
        }
        public void fly(){
            System.out.println("I can fly.");//不会飞的该方法为空,不实现
        }
    }

    这样好像是能解决我们的问题,但是每次有新的需求都要修改基类,耦合太高,好像不是一个好的解决方式。

    我们继续改进,把fly()方法放在一个接口里面,会飞的就继承该接口,不会飞的不继承即可。

     1 public interface IFly{
     2     public void fly(); 
     3 }
     4 public class Duck{
     5     public void sing(){
     6         System.out.println("gua gua...");
     7     }
     8     public abstract void eat();
     9     public abstract void color();
    10 }
    11 public class ADuck extends Duck implements IFly{
    12     public void eat(){
    13         System.out.println("I love fish.");
    14     }
    15     public void color(){
    16         System.out.println("I am black.");
    17     }
    18     public void fly(){
    19         System.out.println("I can fly.");
    20     }
    21 }
    22 public class BDuck extends Duck{
    23     public void eat(){
    24         System.out.println("I love grass.");
    25     }
    26     public void color(){
    27         System.out.println("I am yellow.");
    28     }
    29 }

    这样感觉好多了,但是接口并不会有具体实现,也就是不能复用,只能在每个继承的基类中具体去实现,那么就要用到策略模式了。

    public interface FlyBehavior{
        public void fly();
    }
    public interface EatBehavior{
        public void eat();
    }
    public class FlyByWing implements FlyBehavior{
        public void fly(){
            System.out.println("I fly with my wings");
        }
    }
    public class FlyNoWay implements FlyBehavior{
        public void fly(){
            System.out.println("I can not fly.");
        }
    }
    public class EatFish implements EatBehavior{
        public void eat(){
            System.out.println("I eat fish.");
        }
    }
    public class EatGrass implements EatBehavior{
        public void eat(){
            System.out.println("I eat grass.");
        }
    }
    public class Duck{
        private FlyBehavior flyBehavior;
        private EatBehavior eatBehavior;
        public Duck{};
        public void setFlyBehavior(FlyBehavior flyBehavior){
            this.flyBehavior=flyBehavior;
        }
        public void setEatBehavior(EatBehavior eatBehavior){
            this.eatBehavior=eatBehavior;
        }
        public void sing(){
            System.out.println("gua gua...");
        }
        public abstract void color();
        public void fly(){
            flyBehavior.fly();
        }
        public void eat(){
            eatBehavior.eat();
        }
    }
    public class ADuck extends Duck{
        public ADuck(FlyBehavior flyBehavior,EatBehavior eatBehavior){
            this.setFlyBehavior(flyBehavior);
            this.setEatBehavior(eatBehavior);
        }
        public void color(){
            System.out.println("I am black.");
        }
    }

    上面的代码有什么好处呢,我们实现了多个继承自同一个接口的功能类,并且这些功能类与下面的具体类没有继承关系,耦合性非常低,而且这些功能我们在别的地方还可以复用,比如吃的功能,是动物类都会有的,是可以重复利用的。

  • 相关阅读:
    C#刷遍Leetcode系列连载 索引
    C#刷遍Leetcode面试题系列连载(2): No.38
    C#刷遍Leetcode面试题系列连载(1)
    Windows新终端中玩转ASCII和Emoji游戏的正确姿势
    终于等到你!微软正式上线 Windows Terminal 预览版
    任意公众号的文中插入外链的方法找到了,亲测有效
    只需3步,即可将你的Chromium Edge 浏览器设置成中文
    重磅福利 | 知乎上赞同数最高的1000个回答2019最新版
    黑科技抢先尝(续)
    GitHub上最火爆!码代码不得不知的所有定律法则
  • 原文地址:https://www.cnblogs.com/nannanITeye/p/3308247.html
Copyright © 2020-2023  润新知