定義:Compose objects into tree structures to represent part-wholejava
hierarchies.Composite lets clients treat individual objects and compositions of數據庫
objects uniformly.(將對象組合成樹形結構以表示「部分-總體」的層次結構,使得用數組
戶對單個對象和組合對象的使用具備一致性。)安全
● Component 抽象構件角色性能優化
定義參加組合對象的共有方法和屬性,能夠定義一些默認的行爲或屬性,好比咱們架構
例子中的 getInfo 就封裝到了抽象類中。併發
● Leaf 葉子構件框架
葉子對象,其下再也沒有其餘的分支,也就是遍歷的最小單位。異步
● Composite 樹枝構件分佈式
樹枝對象,它的做用是組合樹枝節點和葉子節點造成一個樹形結構。
樹枝構件的通用代碼:
public class Composite extends Component {
//構件容器
private ArrayList componentArrayList = new
ArrayList();
//增長一個葉子構件或樹枝構件
public void add(Component component){
this.componentArrayList.add(component);
}
//刪除一個葉子構件或樹枝構件
public void remove(Component component){
this.componentArrayList.remove(component);
}
//得到分支下的全部葉子構件和樹枝構件
public ArrayList getChildren(){
return this.componentArrayList;
}
}
使用場景:
● 維護和展現部分-總體關係的場景,如樹形菜單、文件和文件夾管理。
● 從一個總體中可以獨立出部分模塊或功能的場景。
注意:
只要是樹形結構,就考慮使用組合模式。
定義:Define a one-to-many dependency between objects so that when one
object changes state,all its dependents are notified and updated automatically.
(定義對象間一種一對多的依賴關係,使得每當一個對象改變狀態,則全部依賴於
它的對象都會獲得通知並被自動更新。)
● Subject 被觀察者
定義被觀察者必須實現的職責,它必須可以動態地增長、取消觀察者。它通常是抽
象類或者是實現類,僅僅完成做爲被觀察者必須實現的職責:管理觀察者並通知觀
察者。
● Observer 觀察者
觀察者接收到消息後,即進行 update(更新方法)操做,對接收到的信息進行處
理。
● ConcreteSubject 具體的被觀察者
定義被觀察者本身的業務邏輯,同時定義對哪些事件進行通知。
● ConcreteObserver 具體的觀察者
每一個觀察在接收到消息後的處理反應是不一樣,各個觀察者有本身的處理邏輯。
被觀察者通用代碼:
public abstract class Subject {
//定義一個觀察者數組
private Vector obsVector = new Vector();
//增長一個觀察者
public void addObserver(Observer o){
this.obsVector.add(o);
}
//刪除一個觀察者
public void delObserver(Observer o){
this.obsVector.remove(o);
}
//通知全部觀察者
public void notifyObservers(){
for(Observer o:this.obsVector){
o.update();
}
}
}
使用場景:
● 關聯行爲場景。須要注意的是,關聯行爲是可拆分的,而不是「組合」關係。
● 事件多級觸發場景。
● 跨系統的消息交換場景,如消息隊列的處理機制。
注意:
● 廣播鏈的問題
在一個觀察者模式中最多出現一個對象既是觀察者也是被觀察者,也就是說消息最
多轉發一次(傳遞兩次)。
● 異步處理問題
觀察者比較多,並且處理時間比較長,採用異步處理來考慮線程安全和隊列的問
題。
定義:Provide a unified interface to a set of interfaces in a subsystem.Facade
defines a higher-level interface that makes the subsystem easier to use.(要求一
個子系統的外部與其內部的通訊必須經過一個統一的對象進行。門面模式提供一個
高層次的接口,使得子系統更易於使用。)
● Facade 門面角色
客戶端能夠調用這個角色的方法。此角色知曉子系統的全部功能和責任。通常狀況
下,本角色會將全部從客戶端發來的請求委派到相應的子系統去,也就說該角色沒
有實際的業務邏輯,只是一個委託類。
● subsystem 子系統角色
能夠同時有一個或者多個子系統。每個子系統都不是一個單獨的類,而是一個類
的集合。子系統並不知道門面的存在。對於子系統而言,門面僅僅是另一個客戶
端而已。
使用場景:
● 爲一個複雜的模塊或子系統提供一個供外界訪問的接口
● 子系統相對獨立——外界對子系統的訪問只要黑箱操做便可
● 預防低水平人員帶來的風險擴散
注意:
●一個子系統能夠有多個門面
●門面不參與子系統內的業務邏輯
定義:Without violating encapsulation,capture and externalize an object's internal
state so that the object can be restored to this state later.(在不破壞封裝性的前提
下,捕獲一個對象的內部狀態,並在該對象以外保存這個狀態。這樣之後就可將該
對象恢復到原先保存的狀態。)
● Originator 發起人角色
記錄當前時刻的內部狀態,負責定義哪些屬於備份範圍的狀態,負責建立和恢復備
忘錄數據。
● Memento 備忘錄角色(簡單的 javabean)
負責存儲 Originator 發起人對象的內部狀態,在須要的時候提供發起人須要的內部
狀態。
● Caretaker 備忘錄管理員角色(簡單的 javabean)
對備忘錄進行管理、保存和提供備忘錄。
使用場景:
● 須要保存和恢復數據的相關狀態場景。
● 提供一個可回滾(rollback)的操做。
● 須要監控的副本場景中。
● 數據庫鏈接的事務管理就是用的備忘錄模式。
注意:
●備忘錄的生命期
●備忘錄的性能
不要在頻繁創建備份的場景中使用備忘錄模式(好比一個 for 循環中)。
clone 方式備忘錄:
● 發起人角色融合了發起人角色和備忘錄角色,具備雙重功效
多狀態的備忘錄模式
● 增長了一個 BeanUtils 類,其中 backupProp 是把發起人的全部屬性值轉換到
HashMap 中,方便備忘錄角色存儲。restoreProp 方法則是把 HashMap 中的值返
回到發起人角色中。
BeanUtil 工具類代碼:
public class BeanUtils {
//把 bean 的全部屬性及數值放入到 Hashmap 中
public static HashMap backupProp(Object bean){
HashMap result = new
HashMap();
try {
//得到 Bean 描述
BeanInfo
beanInfo=Introspector.getBeanInfo(bean.getClass());
//得到屬性描述
PropertyDescriptor[]
descriptors=beanInfo.getPropertyDescriptors();
//遍歷全部屬性
for(PropertyDescriptor des:descriptors){
//屬性名稱
String fieldName = des.getName();
//讀取屬性的方法
Method getter = des.getReadMethod();
//讀取屬性值
Object fieldValue=getter.invoke(bean,new
Object[]{});
if(!fieldName.equalsIgnoreCase("class")){
result.put(fieldName, fieldValue);
}
}
} catch (Exception e) {
//異常處理
}
return result;
}
//把 HashMap 的值返回到 bean 中
public static void restoreProp(Object bean,HashMap
propMap){
try {
//得到 Bean 描述
BeanInfo beanInfo =
Introspector.getBeanInfo(bean.getClass());
//得到屬性描述
PropertyDescriptor[] descriptors =
beanInfo.getPropertyDescriptors();
//遍歷全部屬性
for(PropertyDescriptor des:descriptors){
//屬性名稱
String fieldName = des.getName();
//若是有這個屬性
if(propMap.containsKey(fieldName)){
//寫屬性的方法
Method setter = des.getWriteMethod();
setter.invoke(bean, new
Object[]{propMap.get(fieldName)});
}
}
} catch (Exception e) {
//異常處理
System.out.println("shit");
e.printStackTrace();
}
}
}
多備份的備忘錄:略
封裝得更好一點:保證只能對發起人可讀
●創建一個空接口 IMemento——什麼方法屬性都沒有的接口,而後在發起人
Originator 類中創建一個內置類(也叫作類中類)Memento 實現 IMemento 接口,
同時也實現本身的業務邏輯。
粉絲福利
給你們免費分享一套阿里架構師傳授的一套教學資源。幫助你們在成爲架構師的道路上披荊斬棘。
這套視頻課程詳細講解了(Spring,MyBatis,Netty源碼分析,高併發、高性能、分佈式、微服務架構的原理,JVM性能優化、分佈式架構)等這些成爲架構師必備的內容!
並且還把框架須要用到的各類程序進行了打包,根據基礎視頻可讓你輕鬆搭建分佈式框架環境,像在企業生產環境同樣進行學習和實踐。