Lambda表达式之观察者模式


在设计模式中我们讲述观察者模式的实现方式,这里着重讲述一下如何使用Lambda表达式实现观察者模式,从而达到让代码更加简洁和阅读性更好。

还是依据设计模式中观察者模式的相关对象进行展开:

定义观察者的接口,也就是观察者的响应接口。事实上这是一个函数式接口
public interface NewObserver {
   public void update(NewSubject subject);
}

主题维护了一个接口对象的list集合,通过主题可以添加观察者,以及通知观察者自身内部的变化。

public class NewSubject {
    //维护一份观察者列表,以便动态地添加和删除
    private List observerList = new ArrayList<>();
    private int state;

    public int getState(){
        return state;
    }

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

    private void notifyAllObservers(){
        //针对接口编程而不是实现编程
        for(NewObserver observer : observerList){
            observer.update(this);
        }
    }

    public void attach(NewObserver observer){
        observerList.add(observer);
    }
}

向主题列表中一般会添加具体的观察者,也就是实现了观察者接口的具体类对象,但是我们这里考虑到观察者接口是一个函数式接口,想利用lambda表达式的特性做一点事情,进而省去创建具体的观察者。下面我们直接看客户端代码,主题是如何通知变化的:

public class NewSubjectTest extends TestCase {
   public void testLambdaImplObserver(){
      NewSubject subject = new NewSubject();

      subject.attach((NewSubject)->{System.out.println("Binary String:" + Integer.toBinaryString(subject.getState()));});
      subject.attach((NewSubject)->{System.out.println("HexObserver String: "+Integer.toHexString(subject.getState()));});
      subject.attach((NewSubject)->{System.out.println("OctalObserver String:"+Integer.toOctalString(subject.getState()));});
      subject.setState(12);
   }

测试结果:

Binary String:1100
HexObserver String: c
OctalObserver String:14

观察者何时实现时采用Lambda表达式还是传统的类,取决于观察者代码的复杂度。我这里所举的例子代码很简单,只是一个方法调用,很适合使用Lambda表达式实现。然而在有些情况下,观察者本身就是一个很复杂的类,这时将很多代码塞进一个方法中会大大降低代码的可读性。