package design; /** *靜態工廠模式 */ public class Factory { /** *構造方法私有化 */ private Factory (){ } /** * 獲取指定類名稱的對象 * @param className * @param <T> * @return T */ public static <T> T getInstance(String className){ T object =null; try { object = (T) Class.forName(className).newInstance(); }catch (Exception e){ e.printStackTrace(); } return object; } }
package design; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; /** * 動態代理模式 */ public class DynamicProxy implements InvocationHandler { private Object target; /** * 代理的目標對象 * @param target * @return */ public Object proxy(Object target){ this.target=target; return Proxy.newProxyInstance(target.getClass().getClassLoader(),target.getClass().getInterfaces(),this); } /** * 目標方法執行前執行 * @param object */ public void before(Object object){ System.out.println("目標方法執行前執行"); } /** * 目標方法執行後執行 * @param object */ public void after(Object object){ System.out.println("目標方法執行後執行"); } /** * Processes a method invocation on a proxy instance and returns * the result. This method will be invoked on an invocation handler * when a method is invoked on a proxy instance that it is * associated with. * @param proxy * @param method * @param args * @return * @throws Throwable */ @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { this.before(proxy); Object result =method.invoke(proxy,args); this.after(result); return result; } }
package design; /** * 單例模式一 */ public class SingletonOne { /** * 實例化對象惟一 */ private static final SingletonOne INSTANCE =new SingletonOne(); /** * 構造方法私有化 */ private SingletonOne(){ } /** * 獲取單例對象 * @return */ public static SingletonOne getInstance(){ return INSTANCE; } }
volatile定義的變量,將直接使用原始數據進行處理,更改後當即生效
package design; /** * 單例模式二 */ public class SingletonTwo { /** * 使用volatile關鍵字修飾單例對象 * volatile定義的變量,將直接使用原始數據進行處理,更改後當即生效 */ public static volatile SingletonTwo instance; /** * 構造方法私有化 */ private SingletonTwo(){ } /** * 獲取單例對象 * @return */ public static SingletonTwo getInstance(){ if(instance ==null){ //經過同步鎖住當前類,來保證線程安全,並提升性能,若直接同步該方法,會大大下降性能 synchronized (SingletonTwo.class){ if (instance ==null){ instance =new SingletonTwo(); } } } return instance; } }
/** * 單例模式三 */ public class ClassSingletonDemo { /** * 構造方法私有化 */ private ClassSingletonDemo(){}; /** * 靜態方法獲取實例 */ public static ClassSingletonDemo getInstance(){ return SingletonHandler.singleton; } /** * 內部靜態類保證只初始化一次 */ private static class SingletonHandler { private static ClassSingletonDemo singleton = new ClassSingletonDemo(); static { System.out.println("This's innerClass's static code block"); } } }
/** * 單例模式四 */ public class EnumSingletonDemo { /** * 構造方法私有化 */ private EnumSingletonDemo(){} /** * 靜態方法獲取實例 */ public static EnumSingletonDemo getInstance(){ return Singleton.INSTANCE.getInstance(); } /** * 私有枚舉,只被JVM加載一次,只實例化一次 */ private enum Singleton{ INSTANCE; private EnumSingletonDemo singleton; Singleton(){ singleton = new EnumSingletonDemo(); } public EnumSingletonDemo getInstance(){ return singleton; } } }
中介者模式的定義:用一箇中介對象來封裝一些列的對象交互,中介者使得各對象不須要顯式地相互引用,從而使其耦合鬆散,並且能夠獨立地改變它們之間的交互。中介者模式解決問題的思路很簡單,就是經過引入一箇中介對象,讓其餘對象只與中介對象交互,而中介對象知道如何和其餘全部對象的交互,這樣對象之間的交互關係就沒有了,從而實現了對象之間的解耦。由此,咱們也能夠看出一個問題,那就是中介對象控制着整個系統的邏輯,它會過於複雜,這是一個缺點。中介者模式的本質是封裝交互:java
中介者模式中的角色:設計模式
示例:安全
以電腦來看電影爲例子,首先光驅從光盤中讀取數據,而後通知CPU將數據分離成音頻和視頻,CPU處理完畢後再分別將數據傳送給聲卡和顯卡進行播放。從上面的描述的中發現,光驅盒CPU是耦合的,CPU又和聲卡顯卡是耦合的,怎麼解耦的呢?若是使用中介者模式,經過引入主板做爲中介者,全部的對象都與主板交互,那麼播放電影的流程就變成了這樣:ide
這樣一個過程當中,全部的類只與主板耦合,而不與其餘類保持關係,作到了解耦,並且過程很清晰。實際上計算機硬件就是這樣通訊的,只不過更復雜一些,因此這些東西都是相通的,重要的是思想。性能
Java實現:this
package design; /** * 同事對象的父類,通常實現成抽象類,用於約束同事對象的類型 * 同時實現一些功能公共方法,例如持有中介者對象 */ public abstract class Colleague { //全部的同事對象都須要持有中介對象 private Mediator mediator; public Colleague(Mediator mediator) { this.mediator = mediator; } public Mediator getMediator() { return mediator; } }
package design; /** * 中介者接口 */ public interface Mediator { /** * 同事對象自身狀態改變時,經過這個方法通知中介者對象 * @param obj */ public void changed(Colleague obj); /** * 中介者對象須要知道全部同事對象 * @param instance */ public void setCDDriver(CDDriver instance); public void setCPU(CPU instance); public void setVideoCard(Video instance); public void setSoundCard(Sound instance); }
package design; /** * 光驅類,負責從光盤中讀取數據 */ class CDDriver extends Colleague { //從光盤讀取的原始數據 private String originData; public CDDriver(Mediator mediator) { super(mediator); } public String getOriginData() { return originData; } /** * 讀取光盤數據,一旦讀取到數據,就要通知中介者對象數據已經準備好了 */ public void readCD(String originData) { this.originData = originData; //通知中介對象,本身的狀態發生了改變 getMediator().changed(this); } }
package design; /** * CPU類,負責將原始數據分離成音頻和視頻 */ public class CPU extends Colleague { //聲音數據 private String soundData; //視頻數據 private String videoData; public CPU(Mediator mediator) { super(mediator); } public String getSoundData() { return soundData; } public String getVideoData() { return videoData; } /** * 將數據分離,同時通知中介者對象,數據已經分離 * @param originData */ public void sperateData(String originData) { this.soundData = originData.split(",")[1]; this.videoData = originData.split(",")[0]; //通知中介對象,本身的狀態發生了改變 getMediator().changed(this); } }
package design; /** * 顯卡類,播放視頻 */ public class Video extends Colleague { public Video(Mediator mediator) { super(mediator); } public void showVideo(String videoData) { System.out.println("正在觀看:" + videoData); } }
package design; /** * 聲卡類,播放聲音 */ public class Sound extends Colleague { public Sound(Mediator mediator) { super(mediator); } public void showSound(String soundData) { System.out.println("解說:" + soundData); } }
package design; /** * 主板類,實現中介者 */ public class MainBoard implements Mediator { private CDDriver cd; private CPU cpu; private Video vc; private Sound sc; public void setCDDriver(CDDriver instance) { this.cd = instance; } public void setCPU(CPU instance) { this.cpu = instance; } public void setVideoCard(Video instance) { this.vc = instance; } public void setSoundCard(Sound instance) { this.sc = instance; } /** * 當同時對象自身狀態發生改變時,調用此方法通知中介者對象 * 中介者對象在進行邏輯控制,與其餘同對象交互 */ public void changed(Colleague obj) { //若是是光驅類,須要通知CPU去分離數據 if(obj instanceof CDDriver) { String originData = ((CDDriver) obj).getOriginData(); this.cpu.sperateData(originData); }else if(obj instanceof CPU){//若是是CPU類,須要通知聲卡和顯卡去播放 String videoData = ((CPU) obj).getVideoData(); String soundData = ((CPU) obj).getSoundData(); this.vc.showVideo(videoData); this.sc.showSound(soundData); } } }
package design; /** * 客戶端 */ public class Client { public static void main(String[] args) { Mediator mediator = new MainBoard(); CDDriver cd = new CDDriver(mediator); CPU cpu = new CPU(mediator); Video vc = new Video(mediator); Sound sc = new Sound(mediator); mediator.setCDDriver(cd); mediator.setCPU(cpu); mediator.setSoundCard(sc); mediator.setVideoCard(vc); //光驅讀數據,通知中介者,中介者通知CPU去分離數據,CPU分離數據完成,通知中介者,中介者通知聲卡和顯卡播放 cd.readCD("終結者,終結者音頻"); } }