日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > asp.net >内容正文

asp.net

java 常用十种设计模式示例归纳 | 已打包请带走

發布時間:2025/3/21 asp.net 33 豆豆
生活随笔 收集整理的這篇文章主要介紹了 java 常用十种设计模式示例归纳 | 已打包请带走 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

設計模式(Design pattern)是一套被反復使用、多數人知曉的、經過分類編目的、代碼設計經驗的總結。

GitHub地址

DesignPattern

文章說明

一個Demo,集合常用的十種設計模式,每個模式使用易被人們接受的案例講述,按模式分包,使用設計模式前后對比,界面顯示定義講解,讓你更深刻的了解每種設計模式。 大部分案例來自張鴻洋的博客。如有錯誤歡迎指正,如有侵權,請聯系我刪除。

項目結構

包結構.png

設計模式分為三種類型,共23種:

  • 創建型模式:單例模式、抽象工廠模式、建造者模式、工廠模式、原型模式。
  • 結構型模式:適配器模式、橋接模式、裝飾模式、組合模式、外觀模式、享元模式、代理模式。
  • 行為型模式:模版方法模式、命令模式、迭代器模式、觀察者模式、中介者模式、備忘錄模式、解釋器模式、狀態模式、策略模式、職責鏈模式(責任鏈模式)、訪問者模式。 上面鏈接點擊直接跳轉到GitHub對應模式解析內
MainActivity.png

博客目錄

  • 1 . 設計模式 觀察者模式(Observer Pattern) 以微信公眾服務為例
  • 2 . 設計模式 工廠模式(Factory Pattern) 從賣肉夾饃說起
  • 3 . 設計模式 單例設計模式(Singleton Pattern) 完全解析
  • 4 . 設計模式 策略模式(Strategy Pattern) 以角色游戲為背景
  • 5 . 設計模式 適配器模式(Adapter Pattern) 以手機充電器為例
  • 6 . 設計模式 命令模式(Command Pattern) 管理智能家電
  • 7 . 設計模式 裝飾者模式(Decorator Pattern) 帶你重回傳奇世界
  • 8 . 設計模式 外觀模式(Facade Pattern) 一鍵電影模式
  • 9 . 設計模式 模版方法模式(TemplateMethod Pattern) 展現程序員的一天
  • 10 . 設計模式 狀態模式(State Pattern) 以自動售貨機為例

對應模式所在的包

  • 1 . Observer
  • 2 . Factory
  • 3 . Singleton
  • 4 . Strategy
  • 5 . Adapter
  • 6 . Command
  • 7 . Decorator
  • 8 . Facade
  • 9 . Template Method
  • 10 . State

模式分析

1. 觀察者模式

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

  • 對于JDK或者Andorid中都有很多地方實現了觀察者模式,比如XXXView.addXXXListenter , 當然了 XXXView.setOnXXXListener不一定是觀察者模式,因為觀察者模式是一種一對多的關系,對于setXXXListener是1對1的關系,應該叫回調。

  • 專題接口:Subject.java ;

    /*** 注冊一個觀察者*/public void registerObserver(Observer observer);/*** 移除一個觀察者*/public void removeObserver(Observer observer);/*** 通知所有觀察者*/public void notifyObservers();
    • 3D服務號的實現類:ObjectFor3D.java

      @Override public void registerObserver(Observer observer) {observers.add(observer); } @Override public void removeObserver(Observer observer) {int index = observers.indexOf(observer);if (index >= 0) {observers.remove(index);} } @Override public void notifyObservers() {for (Observer observer : observers) {observer.update(msg);} } /** * 主題更新信息 */ public void setMsg(String msg) {this.msg = msg;notifyObservers(); }
  • 所有觀察者需要實現此接口:Observer.java

    public ObserverUser1(Subject subject) {subject.registerObserver(this);}@Overridepublic void update(String msg) {Log.e("-----ObserverUser1 ", "得到 3D 號碼:" + msg + ", 我要記下來。 ");}
  • 最后測試:ObserverActivity.java

    // 創建服務號objectFor3D = new ObjectFor3D();// 創建兩個訂閱者observerUser1 = new ObserverUser1(objectFor3D);observerUser2 = new ObserverUser2(objectFor3D);// 兩個觀察者,發送兩條信息objectFor3D.setMsg("201610121 的3D號為:127");objectFor3D.setMsg("20161022 的3D號為:000");

2. 工廠模式

簡單列一下這個模式的家族:

  • 1、靜態工廠模式

    • 這個最常見了,項目中的輔助類,TextUtil.isEmpty等,類+靜態方法。
  • 2、簡單工廠模式(店里買肉夾饃)

    • 定義:通過專門定義一個類來負責創建其他類的實例,被創建的實例通常都具有共同的父類。
    • 根據類型直接創建肉夾饃:SimpleRoujiaMoFactory.java

      public RoujiaMo creatRoujiaMo(String type) {RoujiaMo roujiaMo = null;switch (type) {case "Suan":roujiaMo = new ZSuanRoujiaMo();break;case "La":roujiaMo = new ZLaRoujiaMo();break;case "Tian":roujiaMo = new ZTianRoujiaMo();break;default:// 默認為酸肉夾饃roujiaMo = new ZSuanRoujiaMo();break;}return roujiaMo; }
  • 3、工廠方法模式(開分店)

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

      • 1、定義了創建對象的一個接口:public abstract RouJiaMo sellRoujiaMo(String type);
      • 2、由子類決定實例化的類,可以看到我們的饃是子類生成的。
      • 提供創建肉夾饃店抽象方法:RoujiaMoStore.java
      public abstract RoujiaMo sellRoujiaMo(String type);
    • 具體實現抽象方法:XianRoujiaMoStore.java
    • 分店依舊使用簡單工廠模式:XianSimpleRoujiaMoFactory.java
  • 4、抽象工廠模式(使用官方提供的原料)

    • 定義:提供一個接口,用于創建相關的或依賴對象的家族,而不需要明確指定具體類。
    • 對比定義:
      • 1、提供一個接口:public interface RouJiaMoYLFactroy
      • 2、用于創建相關的或依賴對象的家族 public Meat createMeat();public YuanLiao createYuanliao();我們接口用于創建一系列的原材料。
    • 創建用于提供原料的接口工廠:RoujiaMoYLFactory.java
    • 各自分店實現接口,完成原料提供:XianRoujiaMoYLFoctory.java
    • 準備時,使用官方的原料:RoujiaMo.java

      /*** 準備工作*/ public void prepare(RoujiaMoYLFactory roujiaMoYLFactory) {Meet meet = roujiaMoYLFactory.creatMeet();YuanLiao yuanLiao = roujiaMoYLFactory.creatYuanLiao();Log.e("---RoujiaMo:", "使用官方的原料 ---" + name + ": 揉面-剁肉-完成準備工作 yuanLiao:"+meet+"yuanLiao:"+yuanLiao); }

3. 單例設計模式

單例模式主要是為了避免因為創建了多個實例造成資源的浪費,且多個實例由于多次調用容易導致結果出現錯誤,而使用單例模式能夠保證整個應用中有且只有一個實例

  • 定義:只需要三步就可以保證對象的唯一性
    • (1) 不允許其他程序用new對象
    • (2) 在該類中創建對象
    • (3) 對外提供一個可以讓其他程序獲取該對象的方法
  • 對比定義:
    • (1) 私有化該類的構造函數
    • (2) 通過new在本類中創建一個本類對象
    • (3) 定義一個公有的方法,將在該類中所創建的對象返回
  • 餓漢式[可用]:SingletonEHan.java
  • 含懶漢式[雙重校驗鎖 推薦用]:SingletonLanHan.java

    private SingletonLanHan() {} private static SingletonLanHan singletonLanHanFour; public static SingletonLanHan getSingletonLanHanFour() {if (singletonLanHanFour == null) {synchronized (SingletonLanHan.class) {if (singletonLanHanFour == null) {singletonLanHanFour = new SingletonLanHan();}}}return singletonLanHanFour; }
  • 內部類[推薦用]:SingletonIn.java

  • 枚舉[推薦用]:SingletonEnum.java

單例設計模式.png

4. 策略模式

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

  • 以創建游戲角色為例子:
    • 最初的游戲角色的父類:Role.java
    • 發現有重復代碼后,重構后的父類:Role.java
  • 總結:
    • 1、封裝變化(把可能變化的代碼封裝起來)
    • 2、多用組合,少用繼承(我們使用組合的方式,為客戶設置了算法)
    • 3、針對接口編程,不針對實現(對于Role類的設計完全的針對角色,和技能的實現沒有關系)
  • 最后測試:創建角色:

    RoleA roleA = new RoleA("---A"); roleA.setiDisplayBehavior(new DisplayYZ()).setiAttackBehavior(new AttackXL()).setiDefendBehavior(new DefendTMS()).setiRunBehavior(new RunJCTQ()); roleA.display();// 樣子 roleA.attack();// 攻擊 roleA.run();// 逃跑 roleA.defend();// 防御

5. 適配器模式

定義:將一個類的接口轉換成客戶期望的另一個接口,適配器讓原本接口不兼容的類可以相互合作。這個定義還好,說適配器的功能就是把一個接口轉成另一個接口。

  • 以充電器為實例: 手機充電器一般都是5V左右吧,咱天朝的家用交流電壓220V,所以手機充電需要一個適配器(降壓器)
  • 一部手機: Mobile.java
  • 手機依賴一個提供5V電壓的接口: V5Power.java
  • 我們擁有的是220V家用交流電: V220Power.java
  • 適配器,完成220V轉5V的作用:V5PowerAdapter.java
  • 最后測試:給手機沖個電:

    Mobile mobile = new Mobile(); V5Power v5Power = new V5PowerAdapter(new V200Power()); mobile.inputPower(v5Power);

6. 命令模式

定義:將“請求”封裝成對象,以便使用不同的請求、隊列或者日志來參數化其他對象。命令模式也支持可撤銷的操作。(簡化: 將請求封裝成對象,將動作請求者和動作執行者解耦。)

  • 需求:最近智能家電很火熱,假設現在有電視、電腦、電燈等家電,現在需要你做個遙控器控制所有家電的開關,要求做到每個按鈕對應的功能供用戶個性化,對于新買入家電要有非常強的擴展性。
  • 1、家電的API:Door.java
  • 2、把命令封裝成類:
    • 統一的命令接口:Command.java
    • 家電實現該接口:DoorOpenCommand.java
  • 3、遙控器:ControlPanel.java
  • 4、定義一個命令,可以干一系列的事情:QuickCommand.java

    QuickCommand quickCloseCommand = new QuickCommand(new Command[]{new LightOffCommand(light), new ComputerOffCommand(computer), new DoorCloseCommand(door)}); controlPanel.setCommands(6, quickOpenCommand); controlPanel.keyPressed(6);
  • 5、遙控器面板執行:CommandActivity.java

    controlPanel.setCommands(0, new DoorOpenCommand(door));// 開門 controlPanel.keyPressed(0);

命令模式

7. 裝飾者模式

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

  • 先簡單描述下裝飾者模式發揮作用的地方,當我們設計好了一個類,我們需要給這個類添加一些輔助的功能,并且不希望改變這個類的代碼,這時候就是裝飾者模式大展雄威的時候了。這里還體現了一個原則:類應該對擴展開放,對修改關閉。

  • 需求:設計游戲的裝備系統,基本要求,要可以計算出每種裝備在鑲嵌了各種寶石后的攻擊力和描述:

  • 1、裝備的超類:IEquip.java
  • 2、各個裝備的實現類:
    • eg:武器的實現類: ArmEquip.java
  • 3、裝飾品的超類(裝飾品也屬于裝備):IEquipDecorator.java
  • 4、裝飾品的實現類:

    • eg:藍寶石的實現類(可累加): BlueGemDecorator.java
  • 5、最后測試:計算攻擊力和查看描述:

    Log.e("---", "一個鑲嵌2顆紅寶石,1顆藍寶石的靴子: ");IEquip iEquip = new RedGemDecotator(new RedGemDecotator(new BlueGemDecotator(new ShoeEquip())));Log.e("---", "攻擊力:" + iEquip.caculateAttack());Log.e("---", "描述語:" + iEquip.description());

8. 外觀模式

定義:提供一個統一的接口,用來訪問子系統中的一群接口,外觀定義了一個高層的接口,讓子系統更容易使用。其實就是為了方便客戶的使用,把一群操作,封裝成一個方法。

  • 需求:我比較喜歡看電影,于是買了投影儀、電腦、音響、設計了房間的燈光、買了爆米花機,然后我想看電影的時候,我需要一鍵觀影和一鍵關閉。
  • 每個設備類的開關等操作:
    • eg: 爆米花機:PopcornPopper.java
  • 電影院類:HomeTheaterFacade.java

    /*** 一鍵觀影*/public void watchMovie() {computer.on();light.down();popcornPopper.on();popcornPopper.makePopcorn();projector.on();projector.open();player.on();player.make3DListener();}
    • 最后測試:一鍵觀影:

      new HomeTheaterFacade(computer, light, player, popcornPopper, projector).watchMovie();

9. 模板方法模式

定義:定義了一個算法的骨架,而將一些步驟延遲到子類中,模版方法使得子類可以在不改變算法結構的情況下,重新定義算法的步驟。

  • 需求:簡單描述一下:本公司有程序猿、測試、HR、項目經理等人,下面使用模版方法模式,記錄下所有人員的上班情況
  • 模板方法模式中的三類角色
    • 1、具體方法(Concrete Method)
    • 2、抽象方法(Abstract Method)
    • 3、鉤子方法(Hook Method)
  • 工人的超類:Worker.java

    // 具體方法public final void workOneDay() {Log.e("workOneDay", "-----------------work start----------------");enterCompany();work();exitCompany();Log.e("workOneDay", "-----------------work end----------------");}// 工作 抽象方法public abstract void work();// 鉤子方法public boolean isNeedPrintDate() {return false;}private void exitCompany() {if (isNeedPrintDate()) {Log.e("exitCompany", "---" + new Date().toLocaleString() + "--->");}Log.e("exitCompany", name + "---離開公司");}
  • 程序員實現類(可得知時間):ITWorker.java

    /*** 重寫父類的此方法,使可以查看離開公司時間*/@Overridepublic boolean isNeedPrintDate() {return true;}
  • 最后測試:

    • 查看所有人員的工作情況:

      QAWorker qaWorker = new QAWorker("測試人員");qaWorker();HRWorker hrWorker = new HRWorker("莉莉姐");hrWorker.workOneDay();...
    • 查看程序猿離開公司的時間:

      ITWorker itWorker = new ITWorker("jingbin");itWorker.workOneDay();

10. 狀態模式

定義:允許對象在內部狀態改變時改變它的行為,對象看起來好像修改了它的類。

  • 定義又開始模糊了,理一下,當對象的內部狀態改變時,它的行為跟隨狀態的改變而改變了,看起來好像重新初始化了一個類似的。

  • 需求:已自動售貨機為例(有已投幣、未投幣等狀態和投幣、投幣等方法)

  • 最初實現待改進的售貨機:VendingMachine.java
  • 改進后的售貨機(更具有延展性):VendingMachineBetter.java

    // 放錢public void insertMoney() {currentState.insertMoney();}// 退錢public void backMoney() {currentState.backMoney();}// 轉動曲柄public void turnCrank() {currentState.turnCrank();if (currentState == soldState || currentState == winnerState) {currentState.dispense();//兩種情況會出貨}}// 出商品public void dispense() {Log.e("VendingMachineBetter", "---發出一件商品");if (count > 0) {count--;}}// 設置對應狀態public void setState(State state) {this.currentState = state;}
  • 狀態的接口:State.java

  • 對應狀態的接口實現類:
    • eg: 中獎狀態:WinnerState.java
    • eg: 售賣狀態:SoldState.java
  • 改進后的售貨機測試:

    // 初始化售貨機,且里面有3個商品VendingMachineBetter machineBetter = new VendingMachineBetter(3);machineBetter.insertMoney();machineBetter.turnCrank();

參考鏈接

  • http://blog.csdn.net/lmj623565791/article/category/2206597

Thanks

  • CSDN:張鴻洋
  • CSDN:dmk877

End

感興趣的小伙伴可以Star哦~

GitHub:DesignPattern



作者:Jingbin_
鏈接:http://www.jianshu.com/p/61b67ca754a3
來源:簡書

總結

以上是生活随笔為你收集整理的java 常用十种设计模式示例归纳 | 已打包请带走的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。