1. 程式人生 > >java23種設計者模式 + 例子

java23種設計者模式 + 例子

java的設計模式大體上分為三大類(個人理解):
*建立型模式(4種):工廠模式,單例模式,建造者模式,原型模式
*結構型模式(7種):介面卡模式,裝飾器模式,代理模式,外觀模式,橋接模式,組合模式,享元模式
*行為型模式(11種):策略模式、模板方法模式、觀察者模式、迭代子模式、責任鏈模式、命令模式、備忘錄模式、狀態模式、訪問者模式、中介者模式、直譯器模式

設計模式遵循的6個原則:
1、開閉原則
  對擴充套件開放,對修改關閉

2、里氏代換原則
  只有當衍生類可以替換掉基類,軟體單位的功能不受到影響時,基類才能真正被複用,而衍生類也能夠在基類的基礎上增加新的行為

3、依賴倒轉原則
 這個是開閉原則的基礎,對介面程式設計,依賴於抽象而不依賴於具體。

4、介面隔離原則
  使用多個隔離的藉口來降低耦合度。

5、迪米特法則(最少知道原則)
  一個實體應當儘量少的與其他實體之間發生相互作用,使得系統功能模組相對獨立。

6、合成複用原則
  原則是儘量使用合成/聚合的方式,而不是使用繼承。繼承實際上破壞了類的封裝性,超類的方法可能會被子類修改。

一、工廠模式(Factory)

例項1:追MM少不了請吃飯了,麥當勞的雞翅和肯德基的雞翅都是MM愛吃的東西,雖然口味有所不同,但不管你帶MM去麥當勞或肯德基,只管向服務員說“來四個雞翅”就行了。麥當勞和肯德基就是生產雞翅的Factory 。

public class Factory
{    public static Sample creator(int which){    //getClass 產生Sample 一般可使用動態類裝載裝入類。  if (which== 1return new SampleA();   else if (which== 2)   return new SampleB();   } }

例項2:請MM去麥當勞吃漢堡,不同的MM有不同的口味,要每個都記住是一件煩人的事情,我一般採用Factory Method模式,帶著MM到服務員那兒,說“要一個漢堡”,具體要什麼樣的漢堡呢,讓MM直接跟服務員說就行了。

public abstract class Factory{   
       public abstract Sample creator();
}
public class AFactory extends Factory{
  public Sample creator(){     
            ......... 
            return new SampleA ();  
    }
}
public class BFactory extends Factory{
  public Sample creator(){     
            ......... 
            return new SampleB ();  
    }
}

二、建造模式(Builder)

例項:MM最愛聽的就是“我愛你”這句話了,見到不同地方的MM,要能夠用她們的方言跟她說這句話哦,我有一個多種語言翻譯機,上面每種語言都有一個按鍵,見到MM我只要按對應的鍵,它就能夠用相應的語言說出“我愛你”這句話了,國外的MM也可以輕鬆搞掂,這就是我的“我愛你”builder。

public interface Builder {   
       //建立部件A  比如建立汽車車輪   
        void buildPartA();    

        //建立部件B 比如建立汽車方向盤   
        void buildPartB();  
  
        //建立部件C 比如建立汽車發動機   
        void buildPartC();   
 
        //返回最後組裝成品結果 (返回最後裝配好的汽車)   
        //成品的組裝過程不在這裡進行,而是轉移到下面的Director類別中進行。     
         //從而實現瞭解耦過程和部件   
        Product getResult(); 
} 
public class Director {   
       private Builder builder; 

   public Director( Builder builder ) {      
            this.builder = builder;    
       }
  
        // 將部件partA partB partC最後組成複雜物件   
        //這裡是將車輪 方向盤和發動機組裝成汽車的過程   
        public void construct() {     
            builder.buildPartA(); 
            builder.buildPartB();     
            builder.buildPartC();   
       } 
}

三、原始模型模式(Prototype)

例項:跟MM用QQ聊天,一定要說些深情的話語了,我搜集了好多肉麻的情話,需要時只要copy出來放到QQ裡面就行了,這就是我的情話prototype了。

public abstract class AbstractSpoon implements Cloneable {   
        String spoonName;    
        public void setSpoonName(String spoonName) {
            this.spoonName = spoonName;
        }   
        public String getSpoonName() {
            return this.spoonName;
        }   
        public Object clone()  {     
            Object object = null;    
            try {       
                    object = super.clone();     
            } catch (CloneNotSupportedException exception) { 
                    System.err.println("AbstractSpoon is not Cloneable"); 
            }     
             return object;   
        }
 } 
public class SoupSpoon extends AbstractSpoon {    
        public SoupSpoon(){     
            setSpoonName("Soup Spoon");   
        }
 }   
public class SaladSpoon extends AbstractSpoon{    
        public SoupSpoon(){     
            setSpoonName("Salad Spoon");    
        }
 }

四、單例模式(Singleton)

1、一個類只有一個例項
2、提供一個全域性訪問點
3、禁止拷貝

public class Singleton {
       private static Singleton instance = null;   

       public static synchronized Singleton getInstance() {   
            if (instance==null)     
                   instance=new Singleton();   
            return instance;   
       } 
}

五、介面卡(Adapter)

例項:在朋友聚會上碰到了一個美女Sarah,從香港來的,可我不會說粵語,她不會說普通話,只好求助於我的朋友kent了,他作為我和Sarah之間的Adapter,讓我和Sarah可以相互交談了。

public interface IRoundPeg{   
    public void insertIntoHole(String msg); 
}
public interface ISquarePeg{   
    public void insert(String str);
}
public class PegAdapter implements IRoundPeg,ISquarePeg{   
        private RoundPeg roundPeg;   
        private SquarePeg squarePeg;   

        // 構造方法1   
        public PegAdapter(RoundPeg peg){
            this.roundPeg=peg;
        }   
        // 構造方法2  
        public PegAdapter(SquarePeg peg)(
            this.squarePeg=peg;
        }
        public void insert(String str){ 
            roundPeg.insertIntoHole(str);
        }
        public void insertIntoHole(String str){
            SquarePeg.insert(str);
        }
}

六、橋樑模式(Bridge)

例項:早上碰到MM,要說早上好,晚上碰到MM,要說晚上好;碰到MM穿了件新衣服,要說你的衣服好漂亮哦,碰到MM新做的髮型,要說你的頭髮好漂亮哦。不要問我“早上碰到MM新做了個髮型怎麼說”這種問題,自己用BRIDGE組合一下不就行了 。

public abstract class Coffee {  
    CoffeeImp coffeeImp; 
    public void setCoffeeImp() {    
        this.CoffeeImp = CoffeeImpSingleton.getTheCoffeImp();   
    }   
    public SodaImp getCoffeeImp() {
        return this.CoffeeImp;
    }    
    public abstract void pourCoffee();
 }

public abstract class CoffeeImp {   
    public abstract void pourCoffeeImp(); 
}
 //bridge
public class CoffeeImpSingleton {   
    private static CoffeeImp coffeeImp;    
    public CoffeeImpSingleton(CoffeeImp coffeeImpIn){
        this.coffeeImp = coffeeImpIn;
    }   
    public static CoffeeImp getTheCoffeeImp() {     
        return coffeeImp;   
    }
 }

七、合成模式(Composite)

例項:Mary今天過生日。“我過生日,你要送我一件禮物。”“嗯,好吧,去商店,你自己挑。”“這件T恤挺漂亮,買,這條裙子好看,買,這個包也不錯,買。”“喂,買了三件了呀,我只答應送一件禮物的哦。”“什麼呀,T恤加裙子加包包,正好配成一套呀,小姐,麻煩你包起來。”“……”,MM都會用Composite模式了,你會了沒有?

public abstract class Equipment {   
    private String name;     
    public abstract double netPrice();   
    public abstract double discountPrice();   
    //增加部件方法     
    public boolean add(Equipment equipment) { 
        return false; 
    }   
    //刪除部件方法   
    public boolean remove(Equipment equipment) {
         return false; 
    }   
    //注意這裡,這裡就提供一種用於訪問組合體類別的部件方法。   
    public Iterator iter() { 
        return null; 
    }      
    public Equipment(final String name) {
         this.name=name; 
    } 
} 

八、裝飾模式(Decorator)

例項:Mary過完輪到Sarly過生日,還是不要叫她自己挑了,不然這個月伙食費肯定玩完,拿出我去年在華山頂上照的照片,在背面寫上“最好的的禮物,就是愛你的Fita”,再到街上禮品店買了個像框(賣禮品的MM也很漂亮哦),再找隔壁搞美術設計的Mike設計了一個漂亮的盒子裝起來……,我們都是Decorator,最終都在修飾我這個人呀,怎麼樣,看懂了嗎?

public interface Work {   
    public void insert(); 
}
public class SquarePeg implements Work{   
    public void insert(){     
        System.out.println("方形樁插入");   
    } 
}
public class Decorator implements Work{   
    private Work work;   //額外增加的功能被打包在這個List中   
    private ArrayList others = new ArrayList(); 
  //在構造器中使用組合new方式,引入Work物件;  
    public Decorator(Work work) {     
        this.work=work;        
        others.add("挖坑");
    others.add("釘木板");   
    }
  public void insert(){
    newMethod();   
    } 
   //在新方法中,我們在insert之前增加其他方法,這裡次序先後是使用者靈活指定的  
    public void newMethod(){     
        otherMethod();     
        work.insert();   
    }
    public void otherMethod(){     
        ListIterator listIterator = others.listIterator();     
        while (listIterator.hasNext()){       
            System.out.println(((String)(listIterator.next())) + " 正在進行");     
        }   
    }  
}

九、門面模式(Facade)

例項:我有一個專業的Nikon相機,我就喜歡自己手動調光圈、快門,這樣照出來的照片才專業,但MM可不懂這些,教了半天也不會。幸好相機有Facade設計模式,把相機調整到自動檔,只要對準目標按快門就行了,一切由相機自動調整,這樣MM也可以用這個相機給我拍張照片了。

public class DBCompare {    
    String sql = "SELECT * FROM <table> WHERE <column name> = ?";     
    try {      
        Mysql msql=new mysql(sql);      
        prep.setString( 1, "<column value>" );      
        rset = prep.executeQuery();      
        if( rset.next() ) {         
            System.out.println( rset.getString( "<column name" ));  
        }   
    } catch( SException e ) {     
         e.printStackTrace();   
    } finally {    
         mysql.close();     
         mysql=null;  
    }
}

十、享元模式(Flyweight)

例項:每天跟MM發簡訊,手指都累死了,最近買了個新手機,可以把一些常用的句子存在手機裡,要用的時候,直接拿出來,在前面加上MM的名字就可以傳送了,再不用一個字一個字敲了。共享的句子就是Flyweight,MM的名字就是提取出來的外部特徵,根據上下文情況使用。

public class CD {   
   private String title;
  private int year;
  private Artist artist;

  public String getTitle() { 
   	  return title; 
  }
  public int getYear() {    
  	  return year;  
  }
  public Artist getArtist() {    
  	   return artist;  
  }

  public void setTitle(String t){
      title = t;
  }
  public void setYear(int y){
  		year = y;
  }
  public void setArtist(Artist a){
  		artist = a;
  }

}
public class Artist {   
       //內部狀態
  private String name; 
  // note that Artist is immutable.
  String getName(){
  		return name;
  }  
  Artist(String n){
    name = n;
  } 
}
public class ArtistFactory {   

	Hashtable pool = new Hashtable();
  Artist getArtist(String key){
    Artist result;
    result = (Artist)pool.get(key);
    ////産生新的Artist
    if(result == null) {
      result = new Artist(key);
      pool.put(key,result);
    }
    return result;
  }
}

十一、代理模式(Proxy)

例項:跟MM在網上聊天,一開頭總是“hi,你好”,“你從哪兒來呀?”“你多大了?”“身高多少呀?”這些話,真煩人,寫個程式做為我的Proxy吧,凡是接收到這些話都設定好了自動的回答,接收到其他的話時再通知我回答。

public class ForumPermissions implements Cacheable;

public class ForumProxy implements Forum;

public class DbForum implements Forum, Cacheable

十二、職責鏈(Chain of Responsibility)

例項:晚上去上英語課,為了好開溜坐到了最後一排,哇,前面坐了好幾個漂亮的MM哎,找張紙條,寫上“Hi,可以做我的女朋友嗎?如果不願意請向前傳”,紙條就一個接一個的傳上去了,糟糕,傳到第一排的MM把紙條傳給老師了,聽說是個老處女呀,快跑!

public interface Handler{
  public void handleRequest(Request request);
}

public class Request{
  private String type;

  public Request(String type){this.type=type;}
  public String getType(){return type;}
  public void execute(){
    //request真正具體行為程式碼
  }
}
public class ConcreteHandler implements Handler{
  private Handler successor;
  public ConcreteHandler(Handler successor){
    this.successor=successor;
  }
  public void handleRequest(Request request){
    if (request instanceof HelpRequest){
      //這裡是處理Help的具體程式碼
    }else if (request instanceof PrintRequst){
      request.execute();
    }else
      //傳遞到下一個
      successor.handle(request);
    }
  }
}

十三、命令模式(Command)

例項:俺有一個MM家裡管得特別嚴,沒法見面,只好藉助於她弟弟在我們倆之間傳送資訊,她對我有什麼指示,就寫一張紙條讓她弟弟帶給我。這不,她弟弟又傳送過來一個COMMAND,為了感謝他,我請他吃了碗雜醬麵,哪知道他說:“我同時給我姐姐三個男朋友送COMMAND,就數你最小氣,才請我吃麵。”

public interface Command {
  public abstract void execute ( );
}
public class producer{
  public static List produceRequests() {
    List queue = new ArrayList();
    queue.add( new DomesticEngineer() );
    queue.add( new Politician() );
    queue.add( new Programmer() );
    return queue; 
  } 
}

public class TestCommand {
  public static void main(String[] args) {
    
    List queue = Producer.produceRequests();
    for (Iterator it = queue.iterator(); it.hasNext(); )
        //取出List中東東,其他特徵都不能確定,只能保證一個特徵是100%正確,
        // 他們至少是介面Command的"兒子"。所以強制轉換類別型為介面Command
        ((Command)it.next()).execute();
     }
}

十四、直譯器模式(Interpreter)

例項:俺有一個《泡MM真經》,上面有各種泡MM的攻略,比如說去吃西餐的步驟、去看電影的方法等等,跟MM約會時,只要做一個Interpreter,照著上面的指令碼執行就可以了。

十五、迭代子模式(Iterator)

例項:

我愛上了Mary,不顧一切的向她求婚。
  Mary:“想要我跟你結婚,得答應我的條件”
  我:“什麼條件我都答應,你說吧”
  Mary:“我看上了那個一克拉的鑽石”
  我:“我買,我買,還有嗎?”
  Mary:“我看上了湖邊的那棟別墅”
  我:“我買,我買,還有嗎?”
  Mary:“我看上那輛法拉利跑車”
  我腦袋嗡的一聲,坐在椅子上,一咬牙:“我買,我買,還有嗎?”

//用來遍曆Collection中物件

public class TestCommand {
  public static void main(String[] args) {
    
    List queue = Producer.produceRequests();
    for (Iterator it = queue.iterator(); it.hasNext(); )
        //取出List中東東,其他特徵都不能確定,只能保證一個特徵是100%正確,
        // 他們至少是介面Command的"兒子"。所以強制轉換類別型為介面Command
        ((Command)it.next()).execute();
     }
}

十六、調停者模式(Mediator)

例項:四個MM打麻將,相互之間誰應該給誰多少錢算不清楚了,幸虧當時我在旁邊,按照各自的籌碼數算錢,賺了錢的從我這裡拿,賠了錢的也付給我,一切就OK啦,俺得到了四個MM的電話。

public interface Mediator { }
public class ConcreteMediator implements Mediator {    //假設當前有兩個成員.
   private ConcreteColleague1 colleague1 = new ConcreteColleague1(); 
   private ConcreteColleague2 colleague2 = new ConcreteColleague2(); 
   ... } 
public class Colleague {
   private Mediator mediator;
   public Mediator getMediator() { 
      return mediator;
   }

   public void setMediator( Mediator mediator ) { 
      this.mediator = mediator; 
   }
} 
public class ConcreteColleague1 { }
pu