zoukankan      html  css  js  c++  java
  • 设计模式(一):设计模式入门

    举个例子:现在要设计一个程序模拟各种鸭子,包括玩具鸭和真鸭子。

    每个鸭子都具有呱呱叫 quack() 和 飞行 fly() 方法。

    我们首先想到的设计方法是 定义一个超类duck,超类实现fly()、quack()方法。然后定义各种鸭子子类去继承超类duck。

    但是这样导致的问题是有的鸭子只会quack或fly,而且叫声和飞行方式也分很多种,如果继承两个方法每次都要重写显然不方便,会增加代码长度。

    所以,引出设计原则一找出应用中可能需要变化之处,把他们独立出来,不要和那些不需要变化的混合在一起。     设计原则二:针对接口编程,而不是针对实现编程写程序时应该尽可能增加代码的弹性,如果如例子中那样设计,一旦鸭子需要增加新技能,我们都必须到原来的代码中去修改,这种属于静态定义行为,即在代码编写时就决定了对象的行为,这不是我们想要的好的设计。

    我们需要的是在程序运行时能够动态改变行为

    设计原则三:多用组合,少用继承

    于是,我们把fly和quack单独拿出来定义成接口FlyBehavior和QuackBehavior。

    1 public interface FlyBehavior {
    2     public void fly();
    3 }
    1 public interface QuackBehavior {
    2     public void quack();
    3 }

    接着在定义quack类和fly类实现接口

    public class MuteQuack implements QuackBehavior{
        @Override
        public void quack() {        
            System.out.println("<< Silence >>");    
        }
    }
    
    
    public class Quack implements QuackBehavior{
        @Override
        public void quack() {
            System.out.println("quack!");
        }
    }
    
    
    
    public class Squeak implements QuackBehavior{
        @Override
        public void quack() {
            System.out.println("squeak!");
        }
    }
    public class FlyNoWay implements FlyBehavior{
        @Override
        public void fly() {
            System.out.println("i can not fly!");
        }
    }
    
    
    
    public class FlyWithWings implements FlyBehavior{
        @Override
        public void fly() {
            System.out.println("i am flying!");
        }    
    }

    然后再定义超类Duck

     1 public abstract class Duck {
     2     public FlyBehavior flybehavior;
     3     public QuackBehavior quackbehavior;
     4     
     5     public abstract void display();
     6     
     7     public void performFly(){
     8         flybehavior.fly();
     9     }
    10      
    11     public void performQuack(){
    12         quackbehavior.quack();
    13     }
    14     
    15     public void swim(){
    16         System.out.println("all ducks can swim!");
    17     }
    18     
    19     public void setFlyBehavior(FlyBehavior fb){
    20         flybehavior = fb;
    21     }
    22     
    23     public void setQuackBehavior(QuackBehavior qb){
    24         quackbehavior = qb;
    25     }
    26 }

    在超类中实例化引用两个行为接口

    接着定义鸭子具体类继承自超类Duck

     1 public class MallardDuck extends Duck{
     2     public MallardDuck() {
     3         flybehavior = new FlyWithWings();
     4         quackbehavior = new Quack();
     5     }
     6     @Override
     7     public void display() {
     8         // TODO Auto-generated method stub
     9         System.out.println("i am a mallardDuck!");
    10     }
    11 }

    在具体类构造方法中我们将超类的行为引用定义为new FlyWithWings(),new Quack()

    实现类

    public class test {
        public static void main(String[] args) {
            Duck d = new MallardDuck();
            d.performFly();
            d.performQuack();
            d.display();
        }
    }

    这样就可以动态的修改鸭子的行为,用setFlyBehavior(FlyBehavior fb)和setQuackBehavior(QuackBehavior qb).

  • 相关阅读:
    validate BST
    LC282. Expression Add Operators
    nginx统计日志命令
    iptables和firewalld命令
    nginx安装
    测试服务器IO
    规范主机名和设置最大文件进程数
    Docker安装
    MySQL/MariaDB二进制安装
    Docker原理
  • 原文地址:https://www.cnblogs.com/kinsomy/p/5079842.html
Copyright © 2011-2022 走看看