书写代码必须符合高质量高性能要求,这也是能够在视觉上和其他程序员拉开差距的技能,同时也是一个优秀程序员的基本要求。
何为高质量: 代码具备可维护性,可读性,可扩展性,灵活性,简洁性,可复用性, 可测试性。
何为高性能: 代码能尽可能的提高处理效率。
如何写高质量高性能代码: 首先要做的就是精通设计模式,设计原则,掌握各种算法以及了解硬件底层相关内容。
今天我们来说一说观察者模式。
1观察者模式
在对象之间定义一个一对多的依赖,当一个对象状态改变的时候,所有依赖的对象都会自动收到通知。
//定义被观察者接口
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);
}
}
}
//实现观察者1
public class ConcreteObserverOne implements Observer {
@Override
public void update(Message message) {
//TODO: 获取消息通知,执行自己的逻辑...
System.out.println("ConcreteObserverOne is notified.");
}
}
//实现观察者2
public class ConcreteObserverTwo implements Observer {
@Override
public void update(Message message) {
//TODO: 获取消息通知,执行自己的逻辑...
System.out.println("ConcreteObserverTwo is notified.");
}
}
//模拟代码运行demo
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());
}
}
设计模式最大的一个好处就是解耦,观察者模式就是将观察者和被观察者代码解耦。
观察者模式有同步阻塞的实现方式,也有异步非阻塞的实现方式; 同步方式比较简单,对于异步非阻塞观察者模式,如果只是实现一个简易版本,不考虑任何通用性、复用性,实际上是非常容易的。
以上面的代码为例我们有两种实现方式:
1.在每个handleRegSuccess()函数中创建一个新的线程执行代码逻辑;
2.在UserController的register()函数中使用线程池来执行每个观察者的handleRegSuccess()函数。
对于第一种实现方式,频繁地创建和销毁线程比较耗时,并且并发线程数无法控制,创建过多的线程会导致堆栈溢出。第二种实现方式,尽管利用了线程池解决了第一种实现方式的问题,但线程池、异步执行逻辑都耦合在了register()函数中,增加了这部分业务代码的维护成本。
EventBus是一个框架,它提供了实现观察者模式的骨架代码。我们可以基于此框架,非常容易地在自己的业务场景中实现观察者模式,不需要从零开始开发。其中,Google Guava EventBus就是一个比较著名的EventBus框架,它不仅仅支持异步非阻塞模式,同时也支持同步阻塞模式,案例代码如下:
public class UserController {
private UserService userService;
private EventBus eventBus;
private static final int DEFAULT_EVENTBUS_THREAD_POOL_SIZE = 20;
public UserController() {
//同步阻塞模式
eventBus = new EventBus();
// 异步非阻塞模式
eventBus = new AsyncEventBus(Executors.newFixedThreadPool(DEFAULT_EVENTBUS_THREAD_POOL_SIZE));
}
public void setRegObservers(List<Object> observers) {
for (Object observer : observers) {
eventBus.register(observer);
}
}
public Long register(String telephone, String password) {
//省略输入参数的校验代码
//省略userService.register()异常的try-catch代码
long userId = userService.register(telephone, password);
eventBus.post(userId);
return userId;
}
}
public class RegPromotionObserver {
private PromotionService promotionService;
//依赖注入
@Subscribe
public void handleRegSuccess(long userId) {
promotionService.issueNewUserExperienceCash(userId);
}
}
public class RegNotificationObserver {
private NotificationService notificationService;
@Subscribe
public void handleRegSuccess(long userId) {
notificationService.sendInboxMessage(userId, "...");
}
}
如果需要带注释的spring源码或者了解更多行业技能请关注微信公众号 码农本农