美文网首页
行为型-Observer

行为型-Observer

作者: acc8226 | 来源:发表于2021-06-29 08:09 被阅读0次

    行为型设计模式主要解决的就是“类或对象之间的交互”问题。

    原理及应用场景剖析

    观察者模式(Observer Design Pattern)也被称为发布订阅模式(Publish-Subscribe Design Pattern)。在 GoF 的《设计模式》一书中,它的定义是这样的:

    Define a one-to-many dependency between objects so that when one object changes state, all its dependents are notified and updated automatically.

    翻译成中文就是:在对象之间定义一个一对多的依赖,当一个对象状态改变的时候,所有依赖的对象都会自动收到通知。

    public interface Subject {
      void registerObserver(Observer observer);
      void removeObserver(Observer observer);
      void notifyObservers(Message message);
    }
    
    public interface Observer {
      void update(Message message);
    }
    
    public class ConcreteSubject implements Subject {
      private List<Observer> observers = new ArrayList<Observer>();
    
      @Override
      public void registerObserver(Observer observer) {
        observers.add(observer);
      }
    
      @Override
      public void removeObserver(Observer observer) {
        observers.remove(observer);
      }
    
      @Override
      public void notifyObservers(Message message) {
        for (Observer observer : observers) {
          observer.update(message);
        }
      }
    
    }
    
    public class ConcreteObserverOne implements Observer {
      @Override
      public void update(Message message) {
        //TODO: 获取消息通知,执行自己的逻辑...
        System.out.println("ConcreteObserverOne is notified.");
      }
    }
    
    public class ConcreteObserverTwo implements Observer {
      @Override
      public void update(Message message) {
        //TODO: 获取消息通知,执行自己的逻辑...
        System.out.println("ConcreteObserverTwo is notified.");
      }
    }
    
    public class Demo {
      public static void main(String[] args) {
        ConcreteSubject subject = new ConcreteSubject();
        subject.registerObserver(new ConcreteObserverOne());
        subject.registerObserver(new ConcreteObserverTwo());
        subject.notifyObservers(new Message());
      }
    }
    

    实际上,上面的代码算是观察者模式的“模板代码”,只能反映大体的设计思路。在真实的软件开发中,并不需要照搬上面的模板代码。观察者模式的实现方法各式各样,函数、类的命名等会根据业务场景的不同有很大的差别,比如 register 函数还可以叫作 attach,remove 函数还可以叫作 detach 等等。不过,万变不离其宗,设计思路都是差不多的。

    应用一:用户注册成功之后,给用户发放投资体验金功能

    修改前代码

    
    public class UserController {
      private UserService userService; // 依赖注入
      private PromotionService promotionService; // 依赖注入
    
      public Long register(String telephone, String password) {
        //省略输入参数的校验代码
        //省略userService.register()异常的try-catch代码
        long userId = userService.register(telephone, password);
        promotionService.issueNewUserExperienceCash(userId);
        return userId;
      }
    }
    

    修改后代码

    
    public interface RegObserver {
      void handleRegSuccess(long userId);
    }
    
    public class RegPromotionObserver implements RegObserver {
      private PromotionService promotionService; // 依赖注入
    
      @Override
      public void handleRegSuccess(long userId) {
        promotionService.issueNewUserExperienceCash(userId);
      }
    }
    
    public class RegNotificationObserver implements RegObserver {
      private NotificationService notificationService;
    
      @Override
      public void handleRegSuccess(long userId) {
        notificationService.sendInboxMessage(userId, "Welcome...");
      }
    }
    
    public class UserController {
      private UserService userService; // 依赖注入
      private List<RegObserver> regObservers = new ArrayList<>();
    
      // 一次性设置好,之后也不可能动态的修改
      public void setRegObservers(List<RegObserver> observers) {
        regObservers.addAll(observers);
      }
    
      public Long register(String telephone, String password) {
        //省略输入参数的校验代码
        //省略userService.register()异常的try-catch代码
        long userId = userService.register(telephone, password);
    
        for (RegObserver observer : regObservers) {
          observer.handleRegSuccess(userId);
        }
    
        return userId;
      }
    }
    

    当我们需要添加新的观察者的时候,比如,用户注册成功之后,推送用户注册信息给大数据征信系统,基于观察者模式的代码实现,UserController 类的 register() 函数完全不需要修改,只需要再添加一个实现了 RegObserver 接口的类,并且通过 setRegObservers() 函数将它注册到 UserController 类中即可。

    回顾

    设计模式要干的事情就是解耦,创建型模式是将创建和使用代码解耦,结构型模式是将不同功能代码解耦,行为型模式是将不同的行为代码解耦,具体到观察者模式,它将观察者和被观察者代码解耦。借助设计模式,我们利用更好的代码结构,将一大坨代码拆分成职责更单一的小类,让其满足开闭原则、高内聚低耦合等特性,以此来控制和应对代码的复杂性,提高代码的可扩展性。

    观察者模式的应用场景非常广泛,小到代码层面的解耦,大到架构层面的系统解耦,再或者一些产品的设计思路,都有这种模式的影子,比如,邮件订阅、RSS Feeds,本质上都是观察者模式。不同的应用场景和需求下,这个模式也有截然不同的实现方式,有同步阻塞的实现方式,也有异步非阻塞的实现方式;有进程内的实现方式,也有跨进程的实现方式。

    参考

    设计模式之美设计模式代码重构-极客时间
    https://time.geekbang.org/column/intro/250

    相关文章

      网友评论

          本文标题:行为型-Observer

          本文链接:https://www.haomeiwen.com/subject/dsdtyltx.html