三、观察者模式
思路:基于某个Subject主题,然后一堆观察者Observer注册到主题上,有事件发生时,subject根据注册列表,去通知所有的observer。
Observer接口:
public interface Observer { void notify(String orderNo); }
另外,Java 系列面试题和答案全部整理好了,微信搜索Java技术栈,在后台发送:面试,可以在线阅读。
Subject接口:
public interface Subject { void registerObserver(Observer o); void notifyAllObserver(String orderNo); }
Subject接口实现:
public class SubjectImpl implements Subject { private final List<Observer> list = new ArrayList<>(); @Override public void registerObserver(Observer o) { list.add(o); } @Override public void notifyAllObserver(String orderNo) { list.forEach(c -> c.notify(orderNo)); } }
观察者的二个实现:
OrderObserver: public class OrderObserver implements Observer { @Override public void notify(String orderNo) { System.out.println("订单 " + orderNo + " 状态更新为【已支付】"); } }
StockObserver:
public class StockObserver implements Observer { @Override public void notify(String orderNo) { System.out.println("订单 " + orderNo + " 已通知库房发货!"); } }
测试一把:
static void test1() { Subject subject = new SubjectImpl(); subject.registerObserver(new OrderObserver()); subject.registerObserver(new StockObserver()); subject.notifyAllObserver("001"); }
用java8重构后,接口可以提供默认实现方法,我们弄一个新的主题接口
public interface NewSubject { List<Observer> list = new ArrayList<>(); default void registerObserver(Observer o) { list.add(o); } default void nofityAllObserver(String orderNo) { list.forEach(c -> c.notify(orderNo)); } }
使用:
static void test2() { NewSubject subject = new NewSubject() { }; subject.registerObserver((String orderNo) -> System.out.println("订单 " + orderNo + " 状态更新为【已支付】")); subject.registerObserver((String orderNo) -> System.out.println("订单 " + orderNo + " 已通知库房发货!")); subject.nofityAllObserver("002"); }
只用2个接口实现了观察者模式。
四、责任链/职责链模式
核心思想:每个处理环节,都有一个“指针”指向下一个处理者,类似链表一样。
Processor接口:
public interface Processor { Processor getNextProcessor(); void process(String param); }
public abstract class AbstractProcessor implements Processor { private Processor next; public AbstractProcessor(Processor processor) { this.next = processor; } @Override public Processor getNextProcessor() { return next; } @Override public abstract void process(String param); }
定义2个具体的实现
public class ProcessorImpl1 extends AbstractProcessor { public ProcessorImpl1(Processor processor) { super(processor); } @Override public void process(String param) { System.out.println("processor 1 is processing:" + param); if (getNextProcessor() != null) { getNextProcessor().process(param); } } }
public class ProcessorImpl2 extends AbstractProcessor { public ProcessorImpl2(Processor next) { super(next); } @Override public void process(String param) { System.out.println("processor 2 is processing:" + param); if (getNextProcessor() != null) { getNextProcessor().process(param); } } }
使用示例:
static void test1() { Processor p1 = new ProcessorImpl1(null); Processor p2 = new ProcessorImpl2(p1); p2.process("something happened"); }
用java8重构后,只需要一个新接口
@FunctionalInterface
public interface NewProcessor { Consumer<String> process(String param); }
同样的效果,可以写得很简洁:
static void test2() { Consumer<String> p1 = param -> System.out.println("processor 1 is processing:" + param); Consumer<String> p2 = param -> System.out.println("processor 2 is processing:" + param); p2.andThen(p1).accept("something happened"); }
andThen天然就是getNextProcessor的另一种表达。
重要提示:什么时候该用lambda,什么时候不用,这是要看情况的,如果处理逻辑相对比较简单,可以用lamdba来重构,以便让代码更简洁易读,如果处理逻辑很复杂,应该还是用“类”。