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== 1)
                return new SampleA();
         else if (which== 2)
                return new SampleB();
}
}

    1
    2
    3
    4
    5
    6
    7
    8
    9

實例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 ();
    }
}

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15

二、建造模式(Builder)

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

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

        //創建部件B 比如創建汽車方向盤
        void buildPartB();  

        //創建部件C 比如創建汽車發動機
        void buildPartC(); 

        //返回最後組裝成品結果 (返回最後裝配好的汽車)
        //成品的組裝過程不在這裏進行,而是轉移到下面的Director類別中進行。    
         //從而實現瞭解耦過程和部件
        Product getResult();
}

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15

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

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15

三、原始模型模式(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"); 
        }
 }

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28

四、單例模式(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;
       }
}

    1
    2
    3
    4
    5
    6
    7
    8
    9

五、適配器(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);
        }
}

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25

六、橋樑模式(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();
}

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14

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

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10

七、合成模式(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;
    }

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12

    //注意這裏,這裏就提供一種用於訪問組合體類別的部件方法。
    public Iterator iter() {
        return null;
    }
    public Equipment(final String name) {
         this.name=name;
    }
}

    1
    2
    3
    4
    5
    6
    7
    8

八、裝飾模式(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())) + " 正在進行");
        }
    }
}

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32

九、門面模式(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;
    }
}

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16

十、享元模式(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;
}
}

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51

十一、代理模式(Proxy)

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

public class ForumPermissions implements Cacheable;

public class ForumProxy implements Forum;

public class DbForum implements Forum, Cacheable

    1
    2
    3
    4
    5

十二、職責鏈(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);
}
}
}

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29

十三、命令模式(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();
}
}

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23

十四、解釋器模式(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();
}
}

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12

十六、調停者模式(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 { }
public class ConcreteColleague2 { }

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17

十七、備忘錄模式(Memento)

實例:同時跟幾個MM聊天時,一定要記清楚剛纔跟MM說了些什麼話,不然MM發現了會不高興的哦,幸虧我有個備忘錄,剛纔與哪個MM說了什麼話我都拷貝一份放到備忘錄裏面保存,這樣可以隨時察看以前的記錄啦。

public class Originator {

private int number;
  private File file = null;
public Originator(){} // 創建一個Memento
public Memento getMemento(){
return new Memento(this);
} // 恢復到原始值
public void setMemento(Memento m){
number = m.number;
file = m.file;
}
}
private class Memento implements java.io.Serializable{
       private int number;
private File file = null;
public Memento( Originator o){
number = o.number;
file = o.file;
}
}

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21

十八、觀察者模式(Obserber)

實例:想知道咱們公司最新MM情報嗎?加入公司的MM情報郵件組就行了,tom負責蒐集情報,他發現的新情報不用一個一個通知我們,直接發佈給郵件組,我們作爲訂閱者(觀察者)就可以及時收到情報啦 。

public class product extends Observable{
private String name;
private float price;
public String getName(){ return name;}
public void setName(){
this.name=name;
//設置變化點
setChanged();
notifyObservers(name);
}
}
public class NameObserver implements Observer{ private String name=null;
public void update(Observable obj,Object arg){

if (arg instanceof String){
name=(String)arg;
//産品名稱改變值在name中
System.out.println("NameObserver :name changet to "+name);
}
}
}

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21

十九、狀態模式(State)

實例:跟MM交往時,一定要注意她的狀態哦,在不同的狀態時她的行爲會有不同,比如你約她今天晚上去看電影,對你沒興趣的MM就會說“有事情啦”,對你不討厭但還沒喜歡上的MM就會說“好啊,不過可以帶上我同事麼?”,已經喜歡上你的MM就會說“幾點鐘?看完電影再去泡吧怎麼樣?”,當然你看電影過程中表現良好的話,也可以把MM的狀態從不討厭不喜歡變成喜歡哦。

public class BlueState extends State{
  public void handlepush(Context c){
//根據push方法"如果是blue狀態的切換到green" ;
c.setState(new GreenState());
}
public void handlepull(Context c){
//根據pull方法"如果是blue狀態的切換到red" ;
c.setState(new RedState());
}
public abstract void getcolor(){ return (Color.blue)}
}
public class Context{
private Sate state=null; //我們將原來的 Color state 改成了新建的State state;
//setState是用來改變state的狀態 使用setState實現狀態的切換
pulic void setState(State state){

this.state=state;
}
public void push(){
//狀態的切換的細節部分,在本例中是顔色的變化,已經封裝在子類別的handlepush中實現,這裏無需關心
state.handlepush(this);

//因爲sample要使用state中的一個切換結果,使用getColor()
Sample sample=new Sample(state.getColor());
sample.operate();
}
 
public void pull(){
state.handlepull(this);

Sample2 sample2=new Sample2(state.getColor());
sample2.operate();
}
}

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34

二十、策略模式(Strategy)

實例:跟不同類型的MM約會,要用不同的策略,有的請電影比較好,有的則去吃小吃效果不錯,有的去海邊浪漫最合適,單目的都是爲了得到MM的芳心,我的追MM錦囊中有好多Strategy哦。

public abstract class RepTempRule{

protected String oldString="";
public void setOldString(String oldString){
this.oldString=oldString;
}

protected String newString="";

public String getNewString(){
return newString;
}
public abstract void replace() throws Exception;

}
public class test{ ......
public void testReplace(){ //使用第一套方案進行替換。
RepTempRule rule=new RepTempRuleOne();
rule.setOldString(record);
rule.replace(); }.....
}

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21

二十一、模板方法模式(Template Method)

實例:追MM聖經規定了追MM在不同時期有不同的步驟(Template method),但每個步驟針對不同的情況,都有不一樣的做法,這就要看你隨機應變啦(具體實現);

public abstract class Benchmark
{
/**
* 下面操作是我們希望在子類別中完成
*/
public abstract void benchmark(); /**
* 重復執行benchmark次數
*/
public final long repeat (int count) {
if (count <= 0)
return 0;
else {
long startTime = System.currentTimeMillis();
for (int i = 0; i < count; i++)
benchmark();

long stopTime = System.currentTimeMillis();
return stopTime - startTime;
}
}
}
public class MethodBenchmark extends Benchmark
{
/**
* 真正定義benchmark內容
*/
public void benchmark() {

for (int i = 0; i < Integer.MAX_VALUE; i++){
System.out.printtln("i="+i);
}
}
}

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33

二十二、訪問者模式(Visitor)

實例:情人節到了,要給每個MM送一束鮮花和一張卡片,可是每個MM送的花都要針對她個人的特點,每張卡片也要根據個人的特點來挑,我一個人哪搞得清楚,還是找花店老闆和禮品店老闆做一下Visitor,讓花店老闆根據MM的特點選一束花,讓禮品店老闆也根據每個人特點選一張卡,這樣就輕鬆多了。

public interface Visitable
{
public void accept(Visitor visitor);
}
public class ConcreteVisitor implements Visitor
{
//在本方法中,我們實現了對Collection的元素的成功訪問
public void visitCollection(Collection collection) {
Iterator iterator = collection.iterator()
while (iterator.hasNext()) {
Object o = iterator.next();
if (o instanceof Visitable)
((Visitable)o).accept(this);
} public void visitString(String string) {
System.out.println("'"+string+"'");
}
public void visitFloat(Float float) {
System.out.println(float.toString()+"f");
}

---------------------
作者:Armymans
來源:CSDN
原文:https://blog.csdn.net/qq_43652509/article/details/84755072
版權聲明:本文爲博主原創文章,轉載請附上博文鏈接!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章