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;
}
}