編輯:關於Android編程
這篇博客我們介紹一下中介者模式(Mediator Pattern),也是行為型模式之一,中介者模式也稱為調解者模式或者調停者模式,顧名思義,它的作用是在若干類或者若干模塊之間承當中介。
通常情況下,一個程序必然要包含大量的類,隨著項目的進行,類和模塊的數量必然要進一步增加,特別是當需要維護或者重構時,類與類之間復雜的網狀結構會讓事情變得越來越復雜,降低程序的可讀性和可維護性,並且修改一個類需要牽涉到其他類,不符合開閉原則。所以此時中介者模式能夠將這些網狀結構的類變成星型依賴,所以類都只依賴於中介者,不直接依賴於其他類。
中介者模式包裝了一系列對象相互作用的方式,使得這些對象不必相互明顯作用,從而使耦合松散,而且可以獨立地改變它們之間的交互。
中介者模式可以將多對多的網狀結構轉換成一對多的星型結構,達到降低系統的復雜性,提高可擴展性的作用。在沒有中介者角色之前,所有對象都需要依賴其他對象,持有他們的引用,也就是說對象之間是緊耦合的,有了中介者之後,一切就簡單了,每個對象都會在自己狀態改變時,告訴中介者,每個對象都會對中介者發出的請求做出回應。
vcrKus+1xLOhvrC+zbrcw/fIt8HLo7q1sbbUz/PWrrzktcS9u7ulstnX97rctuDH0sO/uPa21M/ztcTQ0M6qstnX97a80sDAtbHLtMvKsaOszqq3wNa51NrQ3rjE0ru49rbUz/O1xNDQzqrKsaOszazKscnmvLDQ3rjEuty24Mbky/u21M/ztcTQ0M6qo6y/ybLJ08PW0L3p1d/Eo8q9o6zAtL3ivva99PHuus+1xM7KzOKhozwvcD4NCjxoMSBpZD0="uml類圖">UML類圖
我們來看看中介者模式的 uml 類圖:
中介者模式有三個角色:
public abstract class Colleague { protected Mediator mediator; public void setMediator(Mediator mediator) { this.mediator = mediator; } public abstract void operation(); }
具體同事類:
ConcreteColleagueA.class && ConcreteColleagueB.class
public class ConcreteColleagueA extends Colleague{ public void notifyColleagueB() { mediator.notifyColleagueB(); } @Override public void operation() { System.out.print("this is ConcreteColleagueA's operation\n"); } }
public class ConcreteColleagueB extends Colleague{ public void notifyColleagueA() { mediator.notifyColleagueA(); } @Override public void operation() { System.out.print("this is ConcreteColleagueB's operation\n"); } }
抽象中介者角色:
Mediator.class
public abstract class Mediator { protected Colleague colleagueA; protected Colleague colleagueB; public Mediator(Colleague colleagueA, Colleague colleagueB) { this.colleagueA = colleagueA; this.colleagueB = colleagueB; } public abstract void notifyColleagueA(); public abstract void notifyColleagueB(); }
ConcreteMediator.class
public class ConcreteMediator extends Mediator{ public ConcreteMediator(Colleague colleagueA, Colleague colleagueB) { super(colleagueA, colleagueB); } @Override public void notifyColleagueA() { if (colleagueA != null) { colleagueA.operation(); } } @Override public void notifyColleagueB() { if (colleagueB != null) { colleagueB.operation(); } } }
測是代碼:
public class Client { public static void main(String[] args) { Colleague colleagueA = new ConcreteColleagueA(); Colleague colleagueB = new ConcreteColleagueB(); Mediator mediator = new ConcreteMediator(colleagueA, colleagueB); colleagueA.setMediator(mediator); colleagueB.setMediator(mediator); ((ConcreteColleagueA)colleagueA).notifyColleagueB(); ((ConcreteColleagueB)colleagueB).notifyColleagueA(); } }
最後結果:
this is ConcreteColleagueB's operation this is ConcreteColleagueA's operation
兩個 Colleague 類成功通過 Mediator 進行了相互作用。上面這個是中介者模式的標准寫法,就我自己在項目中實際使用中介者模式來說,有時候將同事子類抽象出一個 Colleague 父類是不太合理的,因為子類之間的業務邏輯的不同,導致他們很難抽象出一些公用方法,所以這時候使用中介者模式,可以省去 Colleague 這個角色,讓 Mediator 直接依賴於幾個同事子類;同時也可以不定義Mediator接口,把具體的中介者對象實現成為單例,這樣同事對象不再持有中介者,而是在需要的時候直接獲取中介者對象並調用;中介者也不再持有同事對象,而是在具體處理方法裡面去創建,或獲取,或從數據傳入需要的同事對象。
在 Android 源碼中也有很多使用中介者模式的例子,比如最突出的就是 Binder 中的 Binder Driver 這個角色,它連接了 Binder client , Binder server 和 ServiceManager,相當於一個中介者,感興趣的可以去看看我的這篇博客android IPC通信(下)-AIDL。
我這裡仍然以 wiki 的 demo 為例,使用 Mediator 來控制 3 個按鈕實現 book,view 和 search 的功能:
同事類角色:
Command.class
interface Command { void execute(); }
BtnView.class、BtnSearch.class、BtnBook.class、LblDisplay.class
class BtnView extends JButton implements Command { Mediator med; BtnView(ActionListener al, Mediator m) { super("View"); addActionListener(al); med = m; med.registerView(this); } public void execute() { med.view(); } }
class BtnSearch extends JButton implements Command { Mediator med; BtnSearch(ActionListener al, Mediator m) { super("Search"); addActionListener(al); med = m; med.registerSearch(this); } public void execute() { med.search(); } }
class BtnBook extends JButton implements Command { Mediator med; BtnBook(ActionListener al, Mediator m) { super("Book"); addActionListener(al); med = m; med.registerBook(this); } public void execute() { med.book(); } }
class LblDisplay extends JLabel { Mediator med; LblDisplay(Mediator m) { super("Just start..."); med = m; med.registerDisplay(this); setFont(new Font("Arial", Font.BOLD, 24)); } }
中介者角色:
Mediator.class
interface Mediator { void book(); void view(); void search(); void registerView(BtnView v); void registerSearch(BtnSearch s); void registerBook(BtnBook b); void registerDisplay(LblDisplay d); }
ParticipantMediator.class
class ParticipantMediator implements Mediator { BtnView btnView; BtnSearch btnSearch; BtnBook btnBook; LblDisplay show; //.... public void registerView(BtnView v) { btnView = v; } public void registerSearch(BtnSearch s) { btnSearch = s; } public void registerBook(BtnBook b) { btnBook = b; } public void registerDisplay(LblDisplay d) { show = d; } public void book() { btnBook.setEnabled(false); btnView.setEnabled(true); btnSearch.setEnabled(true); show.setText("booking..."); } public void view() { btnView.setEnabled(false); btnSearch.setEnabled(true); btnBook.setEnabled(true); show.setText("viewing..."); } public void search() { btnSearch.setEnabled(false); btnView.setEnabled(true); btnBook.setEnabled(true); show.setText("searching..."); } }
最後測試程序:
class MediatorDemo extends JFrame implements ActionListener { Mediator med = new ParticipantMediator(); MediatorDemo() { JPanel p = new JPanel(); p.add(new BtnView(this, med)); p.add(new BtnBook(this, med)); p.add(new BtnSearch(this, med)); getContentPane().add(new LblDisplay(med), "North"); getContentPane().add(p, "South"); setSize(400, 200); setVisible(true); } public void actionPerformed(ActionEvent ae) { Command comd = (Command) ae.getSource(); comd.execute(); } public static void main(String[] args) { new MediatorDemo(); } }
用法可能和上面的有些差距,但是思想是一樣的,代碼也一目了然。
在面向對象的變成語言裡,一個類必然會與其他類產生依賴關系,如果這種依賴關系如網狀般錯綜復雜,那麼必然會影響我們的代碼邏輯以及執行效率,適當地使用中介者模式可以對這種依賴關系進行解耦使邏輯結構清晰,但是,如果幾個類之間的關系並不復雜,耦合也很少,使用中介者模式反而會使得原本不復雜的邏輯結構變得復雜,所以,我們在決定使用中介者模式之前需要多多考慮,權衡利弊。
優點:
https://github.com/zhaozepeng/Design-Patterns/tree/master/MediatorPattern
上一篇已經帶大家實現了自由的放大縮小圖片,簡單介紹了下Matrix;具體請參考:Android實現手勢滑動多點觸摸縮放平移圖片效果,本篇繼續完善我們的ImageView。
1.什麼是Activity?Activity是用戶接口程序,它是Android應用程序的基本功能單元,它的主要功能是提供界面。Activity是Android的核心類,該
一、實現思路1、在build.gradle中添加依賴,例如:compile com.android.support:support-v4:23.4.0compile co
余額寶和微信理財通是兩大競爭對手,第一:支付寶和微信的競爭,都在搶占移動支付的領地;第二:余額寶和微信理財通各大基金競爭。但是對於我們普通用戶來說,余額寶和