定義
將對(duì)象組合成樹(shù)形結(jié)構(gòu)以表示“部分-整體”的層次結(jié)構(gòu),使得用戶(hù)對(duì)單個(gè)對(duì)象和組合對(duì)象的使用具有一致性
釋義:
- 該模式屬于結(jié)構(gòu)型模式,主要用于處理對(duì)象與對(duì)象之間的包含關(guān)系和分層關(guān)系缆娃,比如文件系統(tǒng)洛退,XML文件等
- 單個(gè)對(duì)象與組合對(duì)象的使用一致性表示需要抽象出其相同的地方窘拯,比如文件系統(tǒng)中文件和目錄都具有文字,是否隱藏,權(quán)限控制等。
角色介紹:
- Component 是組合中的對(duì)象聲明接口缨该,在適當(dāng)?shù)那闆r下,實(shí)現(xiàn)所有類(lèi)共有接口的默認(rèn)行為川背。聲明一個(gè)接口用于訪(fǎng)問(wèn)和管理Component
子部件贰拿。 - Leaf 在組合中表示葉子結(jié)點(diǎn)對(duì)象,葉子結(jié)點(diǎn)沒(méi)有子結(jié)點(diǎn)熄云。
- Composite 定義有枝節(jié)點(diǎn)行為膨更,用來(lái)存儲(chǔ)子部件,在Component接口中實(shí)現(xiàn)與子部件有關(guān)操作缴允,如增加(add)和刪除
(remove)等荚守。
實(shí)現(xiàn)
本次實(shí)現(xiàn)我們參照Android中View架構(gòu)設(shè)計(jì)一個(gè)針對(duì)圖片編輯的框架,比如添加/刪除文字,添加/刪除貼紙等
public abstract class Element {
Rect mLayout;
Element mParent;
Element mFocusElement;
public abstract void draw(Canvas canvas);
public abstract void move(int x, int y);
public abstract boolean onTouchEvent(MotionEvent motionEvent);
public Element getParent(){
return mParent;
}
public Element getFocusElement(){
return mFocusElement;
}
}
public class StickerElemet extends Element {
@Override
public void draw(Canvas canvas) {
}
@Override
public void move(int x, int y) {
}
@Override
public boolean onTouchEvent(MotionEvent motionEvent) {
return false;
}
}
public class TextElement extends Element {
@Override
public void draw(Canvas canvas) {
}
@Override
public void move(int x, int y) {
}
@Override
public boolean onTouchEvent(MotionEvent motionEvent) {
return false;
}
}
Element是所有元素的頂級(jí)抽象矗漾,TextElement和StickerElement是單個(gè)元素的具體實(shí)現(xiàn)類(lèi)锈候,分別表示文本元素和貼紙?jiān)兀唧w的Element實(shí)現(xiàn)者只負(fù)責(zé)處理自己的繪制和觸摸事件等缩功,不能操作其父節(jié)點(diǎn)和兄弟節(jié)點(diǎn)晴及。
public interface ElementManager {
public void addElement(Element element);
public void removeElement(Element element);
}
ElementManager是元素管理接口都办,定義了元素的增加和刪除接口嫡锌,其實(shí)現(xiàn)類(lèi)需要實(shí)現(xiàn)約定接口功能。
public abstract class ElementGroup extends Element implements ElementManager{
List<Element> mChildren = new ArrayList<>();
@Override
public boolean onTouchEvent(MotionEvent motionEvent) {
return false;
}
public abstract boolean onIntercepted(MotionEvent motionEvent);
public abstract boolean dispatchTouchEvent(MotionEvent motionEvent);
public abstract void drawChildren(Canvas canvas);
public abstract Element getChildren(int position);
public abstract void justOrder();
}
ElementGroup是Element的組合對(duì)象的抽象類(lèi)琳钉,可以看到其實(shí)現(xiàn)ElementManager接口势木,ElementGroup實(shí)現(xiàn)者的職責(zé)是管理Element子節(jié)點(diǎn),主要是元素操作(增加歌懒,刪除啦桌,調(diào)整zOrder等),事件分發(fā)等及皂。
總結(jié)
從上述demo可以看出甫男,組合模式對(duì)于元素之間的隔離是比較高的,客戶(hù)端程序不必關(guān)心元素具體類(lèi)型验烧,而且可以動(dòng)態(tài)添加元素和容器板驳。其缺點(diǎn)是在構(gòu)建組合元素時(shí),很可能會(huì)依賴(lài)具體的組合元素類(lèi)型碍拆,所以盡可能將組合元素進(jìn)行抽象若治,并且獨(dú)立元素操作接口(增刪改查),使客戶(hù)端面向接口來(lái)操作感混。