定義為組合關(guān)系的產(chǎn)品和工廠,保證一個(gè)對象只能由固定的對象初始化的方法叫做Single Call,兩者有相同的生命期:
Product 產(chǎn)品類
// 帶工廠的構(gòu)建方法
public Product(Factory, xxx...) {
/* 工廠能否生產(chǎn)指定product的布爾值屬性
判斷邏輯在product里定義,產(chǎn)品和工廠同時(shí)決定是否有生產(chǎn)權(quán)限,這種方式叫Single Call
普通的工廠模式益眉,可能只是工廠單方面授權(quán)生產(chǎn)產(chǎn)品
*/
if (factory.canCreateProduct()) {
this.xxx = xxx;
...
}
}
Factory 工廠類
private boolean canPermittedCreate = false;
// 起到橋梁的作用,將產(chǎn)品和事件銜接在一起
public Product createProduct() {
Product p = new Product(this, ...);
// 產(chǎn)生事件
new ProductEvent(p, ProductEventType.ADD);
return p;
}
// 刪除邏輯 + 產(chǎn)生刪除事件
public void abandonProduct(Product p) {
new ProductEvent(...);
p = null;
}
// 更新同理
public void editProduct(Product p, String xxx) {
...
}
public boolean canCreateProduct() {
return canPermittedCreate
}
ProductEventType 產(chǎn)品的事件類型枚舉
枚舉自帶單例模式,避免實(shí)例數(shù)量膨脹郭脂,同時(shí)存在線程安全的隱患(要盡量設(shè)計(jì)成無狀態(tài)年碘,檢驗(yàn)的一種想法是多次調(diào)用返回同樣的結(jié)果,這種線程問題適用于所有靜態(tài)方法設(shè)計(jì)的考慮點(diǎn)展鸡;如果存在狀態(tài)就需要加鎖同步屿衅,這種情況下單例模式相比多實(shí)例會(huì)有性能問題)
enum EventType {
ADD, DEL,EDIT;
}
ProductEvent 事件類
// 繼承了Observable類
// 這個(gè)jdk提供的被觀察者模式類,提供了localArr莹弊,synchronize涤久,Vector等線程安全機(jī)制
class ProductEvent extends Observable {
Product sourceProduct; // 事件發(fā)起方
ProductEventType type; // 時(shí)間類型
public ProductEvent(Product, ProductEventType) {
this.source = product;
this.type = type;
notifyEventDispatch(); // 創(chuàng)建完事件后立即觸發(fā)事件
}
// 主要調(diào)用jdk提供的觀察者模式流程
private void notifyEventDispatch() {
// 增加觀察者
super.addObserver(EventDispatch.getEvenetDispatchc());
// 打開通知開關(guān)
super.setChanged();
// 通知觀察者
super.notifyObserver(source);
}
}
EventDispatch
- 作為觀察者觀察事件
- 同時(shí)作為中介者分發(fā)事件
- 管理事件處理者(觀察到事件變化,分發(fā)事件給對應(yīng)的處理者)
// 實(shí)現(xiàn)jdk提供的觀察者接口
class EventDispatch implements Observer {
// 內(nèi)部實(shí)例化了自己一個(gè)常量私有實(shí)例忍弛,單例模式
private final static EventDispatch dispatch = new EventDispatch();
// 事件消費(fèi)者集合
private Vector<EventConsumer> customer = new Vector<EventConsumer>();
// 私有化構(gòu)造方法响迂,保證單例
private EventDispatch() {}
public static EventDispatch getEventDispatchc() {
return dispatch; // 獲取單例
}
public void update(Observable o, Object arg) {
ProductEvent event = (ProductEvent)o; // 獲取事件對象
// 這里的兩層循環(huán)匹配,不是很好细疚;一般做法是通過文件或者容器配置規(guī)則
// 另外如果一個(gè)處理角色對應(yīng)多個(gè)事件的情況蔗彤,可以使用責(zé)任鏈模式(一個(gè)處理者有一個(gè)責(zé)任鏈屬性,責(zé)任鏈上每個(gè)handler處理一種類型的事件)
for (EventConsumer e : customer) {
for (EventConsumeType t : e.getConsumeType()) {
// 處理能力是否匹配
if (t == event.getEventType) {
e.exec(event); // 處理事件
}
}
}
}
public void registerConsumer(EventConsumer consumer) {
// 注冊事件處理角色
customer.add(consumer);
}
}
EventConsumer 事件處理類
abstract class EventConsumer {
// 能夠處理的事件類型集合
private Vector<EventConsumerType> customType =
new Vector<EventConsumerType>();
public void add(type) {
customType.add(type);
}
abstract void exec(event);
}
事件處理實(shí)現(xiàn)類
Beggar extends EventConsumer {
public Beggar() {
// 硬編碼該事件處理角色能夠處理的事件類型
super(EventType.DEL);
}
}
例子
// 單例實(shí)例化
dispatch = EventDispatch.getEventDispatchc();
// 注冊處理類
dispatch.registerConsumer(new Beggar());
factory = new Factory();
// 這一步會(huì)觸發(fā)添加事件疯兼,交給添加事件的consumer處理
product = factory.createProduct(...);