案例分析:设计模式与代码的结构特性

设计模式:

  • 使用设计模式是为了重用代码、让代码更容易被他人理解、保证代码的可靠性。项目中合理地运用设计模式可以完美地解决很多问题,每种模式在现实中都有相应的原理来与之对应,每种模式都描述了一个在我们周围不断重复发生的问题,以及该问题的核心解决方案,这也是设计模式能被广泛应用的原因。
  • 设计模式的参考书 Design Patterns - Elements of Reusable Object-Oriented Software 中总共有23种设计模式,下面将选择一种经典的设计模式--观察者模式进行分析。

观察者模式(Observer Pattern):

观察者模式的适用场景:

  • 当一个抽象模型有两个方面,其中一个方面依赖于另一个方面,需要将这两个方面分别封装到独立的对象中,彼此独立地改变和复用的时候;
  • 当一个系统中一个对象的改变需要同时改变其他对象内容,但是又不知道待改变的对象到底有多少个的时候,可以降低对象之间的耦合度;
  • 当一个对象的改变必须通知其他对象做出相应的变化,但是不能确定通知的对象是谁的时候。

实例分析:

将十进制数转化为十六进制、八进制和二进制数

  • 创建 Subject类
import java.util.ArrayList;
import java.util.List;

public class Subject {
    private List<Observer> observers
            = new ArrayList<Observer>();
    private int state;

    public int getState() {
        return state;
    }

    public void setState(int state) {
        this.state = state;
        notifyAllObservers();
    }

    public void attach(Observer observer){
        observers.add(observer);
    }

    public void notifyAllObservers(){
        for (Observer observer : observers) {
            observer.update();
        }
    }
}
  • 创建 Observer类
public class Observer {
    protected Subject subject;
    public abstract void update();
}
  • 创建实体观察者类
public class BinaryObserver extends Observer{
   //二进制观察者:扩展自Observer类
   public BinaryObserver(Subject subject){
      this.subject = subject;
      this.subject.attach(this);
   }

   @Override
   public void update() {
      System.out.println( "Binary String: "
      + Integer.toBinaryString( subject.getState() ) );
   }
}
public class OctalObserver extends Observer{
   //八进制观察者:扩展自Observer类
   public OctalObserver(Subject subject){
      this.subject = subject;
      this.subject.attach(this);
   }

   @Override
   public void update() {
     System.out.println( "Octal String: "
     + Integer.toOctalString( subject.getState() ) );
   }
}
public class HexaObserver extends Observer{
   //十六进制观察者:扩展自Observer类
   public HexaObserver(Subject subject){
      this.subject = subject;
      this.subject.attach(this);
   }

   @Override
   public void update() {
      System.out.println( "Hex String: "
      + Integer.toHexString( subject.getState() ).toUpperCase() );
   }
}

观察者模式的优点:

  • 观察者模式在被观察者和观察者之间建立一个抽象的耦合。被观察者角色所知道的只是一个具体现察者聚集,每一个具体观察者都符合一个抽象观察者的接口。被观察者并不认识任何一个具体观察者,它只知道它们都有一个共同的接口。由于被观察者和观察者没有紧密地耦合在一起,因此它们可以属于不同的抽象化层次。
  • 观察者模式支持广播通信 。

观察者模式的缺点:

  • 如果一个被观察者对象有很多直接和间接的观察者的话,将所有的观察者都通知到会花费很多时间。
  • 如果在被观察者之间有循环依赖的话,被观察者会触发它们之间进行循环调用,导致系统崩溃。在使用观察考模式时要特别注意这一点。
  • 虽然观察者模式可以随时使观察者知道所观察的对象发生了变化,但是观察者模式没有相应的机制使观察者知道所观察的对象是怎么发生变化的。

参考: https://www.runoob.com/design-pattern/observer-pattern.html

github: https://github.com/hmy0120/Observer-Pattern

02-12 23:00