設計模式技術(補課)

設計模式簡介    
        設計模式是一套被反覆使用、多數人知曉的、通過分類的、代碼設計經驗的總結。         使用設計模式是爲了可重用代碼、讓代碼更容易被他人理解、保證代碼可靠性。java

設計模式四大要素算法

模式名稱 編程

    以一個恰當的詞來描述模式的問題、解決方案和效果。設計模式

問題 ide

    描述應該在什麼時候使用設計模式。工具

解決方案this

    提供設計問題的抽象描述和怎樣用一個具備通常意義的元素組合(類或對象)來解決這個問題。spa

效果 設計

    描述設計模式應用的效果及使用設計模式應該權衡的問題。代理

 

設計模式六大原則

開閉原則
    面向對象設計/編程 終極目標(實現開閉原則)
    一個是對於拓展是開放的,另外一個是對於修改是關閉的
    儘可能不要修改已有代碼
    
單一職責
    不要讓一個類承擔過多的職責
    
里氏替換
    繼承父類後,儘可能不要重寫父類的方法。

依賴倒轉
    經過抽象或者接口來實現類與類之間的依賴關係。

接口隔離
    創建單一接口,不要創建龐大/臃腫的接口
    
迪米特法則
    一個實體儘量少的與另外一個實體發生接觸(依賴),
    只須要知道入口和結果,沒必要在乎過程的實現。避免代碼過於耦合

    
設計模式分類:
建立型:主要處理對象的建立,實例化對象

結構型:處理類或對象的組合

行爲型:描述類或對象怎樣進行交互、職責分配

 

 

建立型模式之【單例模式】

問題

   對於某些場景,確保一個類只有一個實例對象是很重要的,而且這個實例是易於被訪問的。

解決方案

   將實例化操做隱藏在一個類中,由這個類來保證明例的建立和惟一性。

/** 
 * @redame 單例模式 餓漢
 */
public class SingletonObjectA {
	private static SingletonObjectA instance = new SingletonObjectA();
	
	private SingletonObjectA(){}
	
	public static SingletonObjectA getInstance(){
		return instance;
	}
}
/**
 * @redame 單例模式 懶漢
 */
public class SingletonObjectB {
	private static volatile SingletonObjectB instance = null;
	
	private SingletonObjectB(){}
	
	public static SingletonObjectB getInstance(){
		if(instance==null){
			synchronized(instance){
				if(instance == null){
					instance = new SingletonObjectB();
				}
			}
		}
		return instance;
	}
}

 

建立型模式之【工廠模式】

問題

    當一個類沒法肯定要建立哪一種類的對象,或者須要經過子類來肯定具體對象的建立時。

解決方案

    建立一個建立對象的工廠,工廠在程序執行過程當中具體決定建立哪一個對象。

/**
 * @redame 普通工廠模式
 */
public class MessageFactoryA {
	public static String MAIL="MAIL";
	public static String SMS="SMS";
	public static String WE_CHAT="WE_CHAT";
	
	public Sender product(String type){
		if(MessageFactoryA.MAIL.equals(type)){
			return new MailSender();
		} else if(MessageFactoryA.SMS.equals(type)){
			return new SmsSender();
		} else if(MessageFactoryA.WE_CHAT.equals(type)){
			return new WechatSender();
		}
		return null;
	}
}
/**
 * @redame 工廠方法模式
 */
public class MessageFactoryB {

	public Sender productMail(){
		return new MailSender();
	}
	public Sender productSMS(){
		return new SmsSender();
	}
	public Sender productWechat(){
		return new WechatSender();
	}
}


結構型模式之【適配器模式】

問題

    有時,爲複用而設計的工具箱類不可以被複用的緣由,僅僅是由於它的接口與專業應用領域所須要的接口不匹配。

解決方案

    應用經過適配器調用接口,由適配器使得工具箱類能夠被使用。

public class Source {
	public void method1(){
		System.out.println("一個普通方法實現.");
	}
}
public interface Targetable {
	//與原類中的方法相同
	public void method1();
	//新類中的方法
	public void method2();
}
/**
 * 類適配器
 */
public class SpecialAdapter extends Source implements Targetable {

	@Override
	public void method2() {
		System.out.println("這是一個特殊方法實現.");
	}

}
/**
 * 對象適配器
 */
public class SpecialAdapter implements Targetable {

	/**
	 * 可匹配Source的子類 
	 **/
	private Source source;

	public SpecialAdapter(Source source){
		super();
		this.source = source;
	}
	@Override
	public void method1() {
		source.method1();
	}

	@Override
	public void method2() {
		System.out.println("這是一個特殊方法實現.");
	}

}
public static void main(String[] args) {
        //類適配
		Targetable target = new SpecialAdapter();
		target.method1();
		target.method2();
		//對象適配
		Targetable adapter = new SpecialAdapter(new Source());
		adapter.method1();
		adapter.method2();
	}

 

結構型模式之【代理模式】

問題

    對象的訪問須要被控制,不容許其餘對象任意訪問此對象接口。

解決方案

    代理類開放接口提供訪問,全部訪問由代理類決定具體的調用。

/**
 *抽象類
 */
public abstract class AbstractObject {

	//代理方法
	public abstract void operation();
}
/**
 * 代理對象
 */
public class RealObject extends AbstractObject {

	@Override
	public void operation() {
		System.out.println("具體執行任務.");
	}
}
/**
 * 代理類
 */
public class ProxyObject extends AbstractObject {
    
    //代理對象
	RealObject realObject = new RealObject();

	@Override
	public void operation() {
		System.out.println("執行任務前, 作一些什麼事情.");
		realObject.operation();
	}

}
public static void main(String[] args) {
	AbstractObject obj = new ProxyObject();
	obj.operation();
}

 

行爲模式之【觀察者模式】

問題

    將一個系統分割成一系列相互協做的類有一個常見的反作用:須要維護相關對象間的一致性,然而維護對象間的一致性可能致使各種之間的緊密耦合,這樣將下降它們的可重用性。

解決方案

    觀察者模式創建一個目標和任意個依賴它的觀察者,一旦目標狀態發生改變,全部的觀察者都獲得通知。

public abstract class AbstractSubject implements Subject {

	private Vector<Observer> observerList = new Vector<Observer>();
	
	public void add(Observer observer) {
		observerList.add(observer);
	}

	public void del(Observer observer) {
		observerList.remove(observer);
	}

	public void notifyObservers() {
		for (Observer observer : observerList) {
			observer.update();
		}
	}
}
public class MySubject extends AbstractSubject {

	@Override
	public void operation() {
		System.out.println("執行方法, 狀態修改. ");
		notifyObservers();
	}

}
public interface Observer {
	public void update();
}
public class ObserverA implements Observer {

	@Override
	public void update() {
		System.out.println("觀察者A觀察到對象的變化.");
	}

}
public class ObserverB implements Observer {

	@Override
	public void update() {
		System.out.println("觀察者B觀察到對象的變化.");
	}

}
public static void main(String[] args) {
	AbstractSubject subject = new MySubject();
	subject.add(new ObserverA());
	subject.add(new ObserverB());
	subject.operation();
}

=======================運行結果
執行方法, 狀態修改. 
觀察者A觀察到對象的變化.
觀察者B觀察到對象的變化.

 

行爲模式之【策略模式】

問題

    開發中常見的狀況:實現某功能能夠有多種算法或者策略,可根據實際狀況選擇不一樣的算法或策略來完成該功能。若是將全部算法或策略都封裝在一個類中,提供不一樣方法來實現,這個類就變得臃腫,並且新增算法或策略時,須要修改封裝算法類的源碼。

解決方案

    使用不一樣類來封裝不一樣的算法

public interface MemberStrategy {
	/**
     * 計算圖書的價格
     * @param booksPrice    圖書的原價
     * @return    計算出打折後的價格
     */
    public double calcPrice(double booksPrice);
}
public class AdvancedMemberStrategy implements MemberStrategy {

	@Override
	public double calcPrice(double booksPrice) {
		System.out.println("高級會員8折");
		return booksPrice * 0.8;
	}

}
public class IntermediateMemberStrategy implements MemberStrategy {

	@Override
	public double calcPrice(double booksPrice) {
		System.out.println("中級會員9折");
		return booksPrice * 0.9;
	}

}
public class PrimaryMemberStrategy implements MemberStrategy {

	@Override
	public double calcPrice(double booksPrice) {
		System.out.println("初級會員沒有折扣");
		return booksPrice;
	}

}
public class Price {
	//持有一個具體的策略對象
    private MemberStrategy strategy;

	/**
	 * @param strategy
	 */
	public Price(MemberStrategy strategy) {
		super();
		this.strategy = strategy;
	}
    
	/**
     * 計算圖書的價格
     * @param booksPrice    圖書的原價
     * @return    計算出打折後的價格
     */
    public double quote(double booksPrice){
        return this.strategy.calcPrice(booksPrice);
    }
}
public static void main(String[] args) {
	//選擇並建立須要使用的策略對象
    MemberStrategy strategy = new AdvancedMemberStrategy();
    //建立環境
    Price price = new Price(strategy);
    //計算價格
    double quote = price.quote(300);
    System.out.println("圖書的最終價格爲:" + quote);
}

=========運行結果
高級會員8折
圖書的最終價格爲:240.0
相關文章
相關標籤/搜索