常用設計模式舉例,觀察者模式,裝飾模式,工廠模式,單列模式---Head Frist 設計模式源碼

1.概念

設計原則:要依賴抽象,不要依賴具體類。針對接口編程。

策略模式:定義算法族,分別封裝起來,讓它們之間可以互相替換。此模式讓算法的變化獨立於使用算法的客戶。

觀察者模式:定義了對象之間的一對多依賴,這樣一來,當一個對象改變狀態時,它的所有依賴者都會收到通知並自動更新。

裝飾者模式:動態地將責任附加到對象上。若要擴展功能,裝飾者提供了比繼承更有彈性的替代方案。

工廠模式 :通過讓子類決定該創建的對象是什麼,來達到將對象創建的過程封裝的目的。

工廠方法模式:定義了一個創建對象的接口,但由子類決定要實例化的類是哪一個。工廠方法讓類把實例化推遲到子類。

抽象工廠模式:提供一個接口,用於創建相關或依賴對象的家族,而不需要明確指定具體類。

單例設計模式:確保一個類只有一個實例,並提供一個局部訪問點。

命令模式:將請求封裝成對象,,以便使用不同的請求。隊列或者日誌來參數化其它對象,命令模式也支持課撤銷的操作。

2.舉例和源代碼

觀察者模式:

//實現氣象站
//1,建立接口開始
public interface Subject{
	public void registerObserver(Observer o);//前面兩個方法都需要一個觀察者作爲變量,該觀察者是用來註冊或被刪除的
	public void removeObserver(Observer o);
	public void notfiyObserver();//當主題狀態改變時,這個方法會被調用,以通知所有的觀察者
}
public interface Observer{
	public void update(float temp,float humidity,float pressure);//當氣象觀測值改變時主題會把這些狀態值當作方法的參數,傳給觀察者。
	//所有的觀察者都必須實現update()方法,以實現觀察者接口
}
public interface DisplayElement{
	public void display();//DisplayElement接口只包含一個方法,也就是display。顯示時,調用此方法。
}
//實現接口
public class WeatherData implements Subject{//WeatherData現在實現了Subject接口
	private ArrayList observers;
	private float temperature;
	private float humidity;
	private float pressure;
	public WeatherData(){
		observer=new ArrayList();//記錄觀察者
	}
	public void registerObserver(Observer o){//當註冊觀察者時,我們只要把它加到ArrayList的後面即可
	observers.add(o);
		
	}
	public void removeObserver(Observer o){
		int i=observers.indexOf(o);
		if(i>=0){
			observers.remove(i);
		}
	}
	public void notfiyObservers(){//我們把狀態告訴每一個觀察者。因爲都實現了update
		for(int i=0;i<observers.size();i++){
			Observer observer=(Observer)observers.get(i);
			observer.update(temperature,humidity,pressure);
		}
	}
	public void measurementsChanged(){
		//當從氣象站得到更新觀測值是,我們通知觀察者
		notfiyObservers();
	}
	public void setMeasurements(float temperature,float humidity,float pressure){
		this.temperature=temperature;
		this.humidity=humidity;
		this.pressure=pressure;
		measurementsChanged();
	}
	//WeatherData的其它方法
}
//建立佈告板:目前狀況、統計、預測
public class CurrentConditionDisplay implements Observer,DisplayElement{
	private float temperature;
	private float humidity;
	private Subject weatherData;
	public CurrentConditionDisplay(Subject weatherData){//構造器需要weatherData對象作爲政策從之後
	this.temperature=temperature;
	this.humidity=humidity;
	display();
		
	}
	public void display(){
		System.out.println(".........");
	}
}

//測試程序
public class WeatherDataTest{
	public static void main(String[] args){
		WeatherData weatherData=new WeatherData();//首先建立對象
		CurrentConditionDisplay currentDisplay=new CurrentConditionDisplay(weatherData);
		StatisticsDisplay statisticDisplay=new StatisticsDisplay(weatherData);
		ForecastDisplay forecastDisplay=new ForecastDisplay(weatherData);
		
		weatherData.setMeasurements(80,65,30.4f);
	}
}
工廠模式:

//建造原料工廠
/*
現在,我們要建造一個工廠來生產原料;這個工廠將負責創建原料家族中的每一種原料。也就是說,工廠將需要生產麪糰、
醬料、等待會兒,你就會知道如何處理各個區域的差異了。
開始先爲工廠定義一個接口,這個接口負責創建所有的原料。
*/ 
public interface PizzaIngredientFactory{
	public Dough createDough();
	public Sauce createSauce();
	public Veggies[] createVeggies();
	public Chese createCheese();
	public Pepperoni createPepperoni();
	public Clams createClam();
}
/*
要做的事:1.爲每個區域建造一個工廠,你需要創建一個繼承自PizzaIngredientFactory的子類來實現每一個創建方法。
2.實現一組原料類供應工廠使用
3.然後你仍然需要將這一切組織起來,將新的原料工廠整合進舊的PizzaStore代碼中
*/
public class NYPizzIngredientFactory implements PizzaIngredientFactory{
	public Dough createDough(){
		return new ThinCrustDough();
	}
	public Sauce createSauce(){
		return new MarinaraSauce();
		
	}
	public Chese createCheese(){
		return new ReggainoCheese();
	}
	public Veggies[] createVeggies(){
		Veggies veggies[] ={new Garlic(),new Onion(),new Mushroom(),new RedPepper()};
		return veggies;
	}
	public Pepperoni createPepperoni(){
		return new SlicesPepperoni();
	}
	public Clams createClam(){
		return new FreshClams();
	}
}
//重做披薩
public abstract class Pizza{
	String name;
	Dough dough;
	Sauce sauce;
	Veggies veggies[];
	Chese cheses;
	Pepperoni pepperoni;
	Clams clam;
	abstract void perpare();
	void bake(){
		system.out.println("披薩");
	}
	void setName(String name){
		this.name=name;
	}
	String getName(){
		return name;
	}
}
public class ChesePizza extends Pizza{
	PizzaIngredientFactory ingredientFactory;
	public ChesePizza (PizzaIngredientFactory ingredientFactory){
		this.ingredientFactory=ingredientFactory;
	}
	void perpare(){
		dough=ingredientFactory.createDough();
		sauce=ingredientFactory.createSauce();
		cheses=ingredientFactory.createCheese();
	}
}
//哈利披薩
public class ClamPizza extends Pizza{
	PizzaIngredientFactory ingredientFactory;
	public ClamPizza(PizzaIngredientFactory ingredientFactory){//其實這個就像依賴注入一樣。
		this.ingredientFactory=ingredientFactory;
	}
	void perpare(){
		dough=ingredientFactory.createDough();
		sauce=ingredientFactory.createSauce();
		cheses=ingredientFactory.createCheese();
		clam=ingredientFactory.createClam();
	}
}
裝飾模式:

public class SwingObserverExample{
	
}
public abstract class Beverage{//裝飾着類
	String description="Unkonwn Beverage";
	public String getDescription(){
		return description;
	}
	public abstract double cost();
	
}
public abstract class CondimentDecorator extends Beverage{
	public abstract String getDescription();//所有的裝飾者都必須重新實現getDescription()方法 
	
}
public class Espresso extends Beverage{//一種飲料
	public Espresso(){
		description="Espresso";//爲了要設置飲料的描述,我們寫了一個構造器。記住description實例變量繼承自Beverage.
		
	}
	public double cost(){
		return 1.99;//最後設置價錢
	}
	
}
public class HouseBlend extends Beverage{
	public HouseBlend(){
		description="House Blend Coffe";
		
	}
	public double cost(){
		return 0.89;
	}
}
public class Mocha extends CondimentDecorator{
	Beverage beverage;
	public Mocha (Beverage beverage){
		this.beverage=beverage;
	}
	public String getDescription(){
		return beverage.getDescription()+",Mocha";
	}
	public double cost(){
		return 20+beverage.cost();//
	}
}
//測試類
public class StardbuzzCoffee{
	public static void main(String[] args){
		Beverage beverage =new Espresso();
		Beverage beverage2 =new DarkRoast();
	}
}

單列模式

public  class Singleton{
	private static Singleton uniqueInstance;
	//這裏是其它的有用實例化變量
	private Singleton(){}//把構造器聲明爲私有的。
	private static Singleton getInstance(){
		if(uniqueInstance == null){
			uniqueInstance = new Singleton();
		}
		return uniqueInstance;
			
	}
	//這裏有其它的有用的方法
	
	
}
//處理多線程
/*
只要把getInstance()變成{synchronized}方法,多線程的問題就可以解決
*/
public class Singleton{
	private static Singleton uniqueInstance;
	//其它有用的實例化變量
	private Singleton(){}
	public static synchronized Singleton getInstance(){
		if(uniqueInstance == null){
			uniqueInstance= new Singleton();
		}
		return uniqueInstance;
	}
}
/*
上面可能出現延遲加載的問題,性能低
*/
public class Singleton{
	private static Singleton uniqueInstance = new Singleton();//保證線程的安全
	private Singleton(){}
	public static Singleton getInstance(){
		return uniqueInstance;//已經有實例了,直接使用它
	}
}
/*
第二種方法。利用雙重檢查加鎖
*/
public class Singleton{
	private volatile static Singleton uniqueInstance;//volatile關鍵字確保,當uniqueInstance變量被初始化成,多個線程正確處理變量
	private Singleton(){
		
	}
	public static Singleton getInstance(){
		if(uniqueInstance == null){
			synchronized(Singleton.class){
				if( uniqueInstance == null){
					uniqueInstance = new Singleton();
				}
			}
		}
		return uniqueInstance;
	}
}





發佈了41 篇原創文章 · 獲贊 5 · 訪問量 4萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章