摘要:創建型設計模式結構型設計模式行為型設計模式結構型設計模式簡而言之結構模式主要涉及對象的組成,或者是實體如何相互使用。
1.創建型設計模式
2.結構型設計模式
3.行為型設計模式
簡而言之
結構模式主要涉及對象的組成,或者是實體如何相互使用。或者,另一個解釋是,他們幫助回答“如何構建一個軟件組件?”
維基百科說
在軟件工程中,結構設計模式是通過識別實體之間關系的簡單方法來簡化設計的設計模式。?適配器模式
現實舉例
考慮一下你的記憶卡上有一些圖片,你需要把它們轉移到你的電腦上。為了轉移它們,你需要某種與你的計算機端口兼容的適配器,這樣你就可以將存儲卡附加到你的電腦上。在這個例子中讀卡器就是適配器。
另一個例子是著名的電源適配器;一個三腳插頭不能連接到兩個電源插座,它需要使用一個電源適配器,使它與兩個電源插座兼容。
另一個例子是一個譯者翻譯一個人對另一個人說的話。
簡而言之
適配器模式允許您在適配器中包裝一個不兼容的對象,使其與另一個類兼容。
維基百科說
在軟件工程中,適配器模式是一種軟件設計模式,它允許將現有類的接口用作另一個接口。它通常用于使現有的類與其他類一起工作,而無需修改它們的源代碼。
編程示例
考慮一個游戲,一個獵人追捕獅子。
首先我有一個獅子(Lion)的接口和所有要實現類型的獅子。
public interface Lion { void roar(); }
public class AsianLion implements Lion { @Override public void roar() { System.out.println("AsianLion roar"); } }
public class AfricanLion implements Lion { @Override public void roar() { System.out.println("AfricanLion roar"); } }
獵人希望所有捕獲的獅子都能實現Lion的接口。
public class Hunter { public void hunt(Lion lion) { lion.roar(); } }
現在在我們的游戲里增加一個"野狗"(WildDog),獵人也可以捕獲。但是我們不能直接這樣做,因為野狗(WildDog)有一個不同的接口。為了兼容我們的獵人(hunter),我們必須創建一個適配器來使之兼容。
public class WildDog { public void bark() { System.out.println("WildDog bark"); } }
public class WildDogAdapter implements Lion { private WildDog wildDog; public WildDogAdapter(WildDog wildDog) { this.wildDog = wildDog; } @Override public void roar() { this.wildDog.bark(); } }
現在 WildDog 可以在我們的游戲里使用 WildDogAdapter來代替.
WildDog wildDog = new WildDog(); WildDogAdapter adapter = new WildDogAdapter(wildDog); Hunter hunter = new Hunter(); hunter.hunt(adapter);?橋接模式
現實舉例
考慮你有一個不同頁面的網站,你應該允許用戶改變主題。你會怎么做?為每個主題創建多個頁面的多個副本,或者僅僅根據用戶的喜好創建多帶帶的主題并加載它們?橋式模式允許你做第二件事。
簡而言之
橋式模式是傾向于選擇組合而不是繼承。實現細節從層次結構推送到另一個具有獨立層次結構的對象。
維基百科說
橋式模式是軟件工程中使用的一種設計模式,它的意思是“將抽象與實現分離開來,以便兩者能夠獨立地變化”。
編程示例
翻譯一下上邊的Web頁面(Web Page)的例子。首先是獨立的WebPage層次
public interface WebPage { String getContent(); }
public class About implements WebPage { private Theme theme; public About(Theme theme) { this.theme = theme; } @Override public String getContent() { return "About page in "+theme.getColor(); } }
public class Career implements WebPage { private Theme theme; public Career(Theme theme) { this.theme = theme; } @Override public String getContent() { return "Career Page in "+theme.getColor(); } }
獨立的主題層次
public interface Theme { String getColor(); }
public class AquaTheme implements Theme { @Override public String getColor() { return "Light blue"; } }
public class DarkTheme implements Theme { @Override public String getColor() { return "Dark Black"; } }
public class LightTheme implements Theme { @Override public String getColor() { return "Off White"; } }
And both the hierarchies
Theme aquaTheme = new AquaTheme(); Theme darkTheme = new DarkTheme(); WebPage about = new About(aquaTheme); WebPage career = new Career(aquaTheme); System.out.println(career.getContent()); System.out.println(about.getContent()); System.out.println(""); about = new About(darkTheme); career = new Career(darkTheme); System.out.println(career.getContent()); System.out.println(about.getContent());? 組合模式
現實舉例
每個組織都是由雇員組成的。每個雇員都有相同的特性,即有工資,有一些職責,可以或不可以向某人報告,可以或不可能有一些下屬等。
簡而言之
組合模式允許客戶以統一的方式處理單個對象
維基百科說
在軟件工程中,組合模式是一個分而治之的設計模式。
組合模式描述了以相同的方式對待一組對象和單個對象。 組合的意圖是將對象“組合”到樹結構中,以表示部分整個層次結構。 實現組合模式可以讓客戶端對單個對象和組合進行統一處理。
編程示例
參考我們上邊雇員的例子。我們又幾種類型的雇員。
public interface Employee { String getName(); void setSalary(float salary); float getSalary(); String getRole(); }
public class Developer implements Employee { private String name; private float salary; private String role; public Developer(String name, float salary) { this.name = name; this.salary = salary; this.role = "Developer"; } @Override public String getName() { return name; } @Override public void setSalary(float salary) { this.salary = salary; } @Override public float getSalary() { return this.salary; } @Override public String getRole() { return role; } }
public class Designer implements Employee{ private String name; private float salary; private String role; public Designer(String name, float salary) { this.name = name; this.salary = salary; this.role = "Designer"; } @Override public String getName() { return name; } @Override public void setSalary(float salary) { this.salary = salary; } @Override public float getSalary() { return this.salary; } @Override public String getRole() { return role; } }
下面我們用組織來保存幾種不同類型的雇員。
public class Orgnization { private Listemployees = new ArrayList<>(); public void addEmployee(Employee employee) { employees.add(employee); } public float getSalary() { float total = 0; for(Employee employee : employees) { total += employee.getSalary(); } return total; } }
使用方式如下
Employee employee1 = new Developer("John Doe",12000); Employee employee2 = new Designer("Jane Doe",15000); Orgnization orgnization = new Orgnization(); orgnization.addEmployee(employee1); orgnization.addEmployee(employee2); System.out.println(orgnization.getSalary());? 裝飾者模式
現實舉例
假設你經營一家提供多種服務的汽車服務商店。那么如何計算要收取的費用呢?您可以選擇一個服務并動態地將提供的服務的價格添加到最終成本。這里的每一種服務都是裝飾者。
簡而言之
裝飾者模式允許您通過將對象在一個裝飾者類的對象中進行包裝,從而在運行時動態地更改對象的行為。
維基百科說
在面向對象編程中,裝飾者模式是一種設計模式,它允許將行為添加到單個對象中,無論是靜態的還是動態的,都不會影響來自同一類的其他對象的行為。 裝飾者模式通常對堅持單一責任原則非常有用,因為它允許在具有獨特關注點的類之間劃分功能。
編程示例
我們以咖啡舉例,首先我們有一個簡單的實現了咖啡接口的咖啡。
public interface Coffee { float getCost(); String getDescription(); }
public class SimpleCoffee implements Coffee { @Override public float getCost() { return 10; } @Override public String getDescription() { return "simpleCoffee"; } @Override public String toString() { return "SimpleCoffee"; } }
我們希望使代碼可擴展,以便在需要時允許選項進行修改。讓我們做一些附加組件(decorator)
public class MilkCoffee implements Coffee { private Coffee coffee; public MilkCoffee(Coffee coffee) { this.coffee = coffee; } @Override public float getCost() { return coffee.getCost()+2; } @Override public String getDescription() { return coffee.getDescription()+",milk"; } }
public class VanillaCoffee implements Coffee{ private Coffee coffee; public VanillaCoffee(Coffee coffee) { this.coffee = coffee; } @Override public float getCost() { return coffee.getCost()+3; } @Override public String getDescription() { return coffee.getDescription()+",vanilla"; } }
public class WhipCoffee implements Coffee { private Coffee coffee; public WhipCoffee(Coffee coffee) { this.coffee = coffee; } @Override public float getCost() { return coffee.getCost()+5; } @Override public String getDescription() { return coffee.getDescription()+",whip"; } }
Lets make a coffee now
Coffee coffee = new SimpleCoffee(); System.out.println(coffee.getCost()); System.out.println(coffee.getDescription()); coffee = new MilkCoffee(coffee); System.out.println(coffee.getCost()); System.out.println(coffee.getDescription()); coffee = new VanillaCoffee(coffee); System.out.println(coffee.getCost()); System.out.println(coffee.getDescription()); coffee = new WhipCoffee(coffee); System.out.println(coffee.getCost()); System.out.println(coffee.getDescription());? 門面模式
現實舉例
你怎么打開電腦?“按下電源鍵”你說!這就是你所相信的,因為你使用的是一個簡單的界面,電腦在外部提供,在內部它需要做很多事情來實現它。這個復雜子系統的簡單接口是一個門面。
簡而言之
門面模式提供了一個復雜子系統的簡化接口。
維基百科說
門面模式是為更大的代碼體(如類庫)提供簡化接口的對象。
編程示例
以我們上邊的計算機為例。首先這是我們的計算機。
public class Computer { public void getElectricShock() { System.out.println("Ouch"); } public void makeSound() { System.out.println("Beep beep!"); } public void showLoadingScreen() { System.out.println("Loading.."); } public void bam() { System.out.println("Ready to be used!"); } public void closeEverything() { System.out.println("closeEverything"); } public void sooth() { System.out.println("Zzzzz"); } public void pullCurrent() { System.out.println("Haaah"); } }
下面是門面
public class ComputerFacade { private Computer computer; public ComputerFacade(Computer computer) { this.computer = computer; } public void turnOn() { computer.getElectricShock(); computer.makeSound(); computer.showLoadingScreen(); computer.bam(); } public void turnOff() { computer.closeEverything(); computer.pullCurrent(); computer.sooth(); } }
下面開始使用門面
Computer computer = new Computer(); ComputerFacade facade = new ComputerFacade(computer); facade.turnOn(); System.out.println("============================"); facade.turnOff();? 享元模式
現實舉例
你曾經在某個攤位上喝過新鮮的茶嗎?他們經常做的比你要求的多并把剩下的留給其他顧客,以節省資源,例如氣體等。Flyweight模式就是分享。
簡而言之
它通過盡可能多地與類似對象共享來最小化內存使用或計算開銷。
維基百科說
在計算機編程中,享元是一種軟件設計模式。享元是一個對象,它通過與其他類似對象共享盡可能多的數據來最小化內存使用;當一個簡單的重復表示使用不可接受的內存時,它是一種使用大量對象的方法。
編程示例
翻譯一下我們上邊茶水的例子。首先我們有茶的類型和茶具。
public class KarakTea { }
public class TeaMaker { private MapavailableTea = new HashMap<>(); public KarakTea make(String preference) { if(!availableTea.containsKey(preference)) { availableTea.put(preference,new KarakTea()); } return availableTea.get(preference); } }
然后我們有茶社來接單和提供服務。
public class TeaShop { private TeaMaker teaMaker; private Maporders = new HashMap<>(); public TeaShop(TeaMaker teaMaker) { this.teaMaker = teaMaker; } public void takeOrder(String teaType,int table) { orders.put(table,teaMaker.make(teaType)); } public void serve() { Set > entrySet = orders.entrySet(); for(Map.Entry entry : entrySet) { System.out.println("Serving tea to table#"+entry.getKey()); } } }
使用方式如下
TeaMaker teaMaker = new TeaMaker(); TeaShop shop = new TeaShop(teaMaker); shop.takeOrder("less sugar", 1); shop.takeOrder("more milk", 2); shop.takeOrder("without sugar", 3); shop.serve();? 代理模式
現實舉例
你曾經用過門禁卡嗎?打開這扇門有多種選擇,即可以使用門禁卡打開,也可以通過按一個繞過安全按鈕的按鈕打開。 門的主要功能是打開,但是在它上面添加了一個代理來添加一些功能。讓我用下面的代碼示例更好地解釋一下。
簡而言之
使用代理模式,一個類代表另一個類的功能。
維基百科說
代理,在其最一般的形式中,是一個類作為其他東西的接口。 代理是由客戶端調用的包裝器或代理對象,以訪問實際服務對象。代理的使用可以簡單地轉發到實際對象,或者提供額外的邏輯。 在代理的額外功能中可以提供,例如在實際對象上的操作是資源密集型的緩存,或者在調用實際對象的操作之前檢查先決條件。
編程示例
上邊安全門的例子。首先我們有一個門的接口和一個門的實現
public interface Door { void open(); void close(); }
public class LabDoor implements Door { @Override public void open() { System.out.println("Opening lab door"); } @Override public void close() { System.out.println("Closing lab door"); } }
我們有一個來歷來確保我們想要的門。
public class SecuredDoor { private Door door; public SecuredDoor(Door door) { this.door = door; } public void open(String pwd) { if(authenticate(pwd)) { door.open(); } else { System.out.println("Big no! It ain"t possible."); } } private boolean authenticate(String pwd) { return "$ecr@t".equals(pwd); } public void close() { this.door.close(); } }
使用方式如下
Door door = new LabDoor(); SecuredDoor securedDoor = new SecuredDoor(door); securedDoor.open("invalid"); //securedDoor.open("$ecr@t");
還有一個例子是某種形式的數據映射的實現。例如我最近編寫了一個MongoDB的ODM。在mongodb周圍利用魔術方法__call()我寫了一個代理,所有的方法調用都被代理到原生的mongo類。檢索的結果作為返回的數據,如果find或者findOne的數據映射到某個類,這類將會代替cursor返回。
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/71057.html
摘要:創建型模式主要有以下五種簡單工廠模式和工廠方法模式抽象工廠模式單例模式建造者模式原型模式在設計模式一書中將工廠模式分為兩類工廠方法模式與抽象工廠模式。 一、 設計模式(Design pattern)是什么 設計模式是一套被反復使用、多數人知曉、經過分類編目的代碼設計的經驗總結。使用設計模式是為了可重用代碼、讓代碼更容易被他人理解、保證代碼可靠性。 二、 為什么會有設計模式 在軟件開發過...
摘要:里氏代換原則里氏代換原則面向對象設計的基本原則之一。里氏代換原則中說,任何基類可以出現的地方,子類一定可以出現。里氏代換原則是對開閉原則的補充。而基類與子類的繼承關系就是抽象化的具體實現,所以里氏代換原則是對實現抽象化的具體步驟的規范。 一、設計模式的六大原則: 1、開閉原則(Open Close Principle) 開閉原則就是說對擴展開放,對修改關閉。在程序需要進行拓展的時候,不...
摘要:遵循特定規則,利用操作符,終止節點和其他非終止節點,構造新的字符串非終結符是表示字符串的樹的內部節點。語法中的生產具有這種形式非終結符終結,非終結符和運算符的表達式語法的非終結點之一被指定為根。 大綱 基于狀態的構建 基于自動機的編程 設計模式:Memento提供了將對象恢復到之前狀態的功能(撤消)。 設計模式:狀態允許對象在其內部狀態改變時改變其行為。 表驅動結構* 基于語法的構...
摘要:維基百科在軟件工程中,創建型設計模式是用于解決對象創建機制,嘗試在指定場景下使用合理的方式來創建對象的設計模式。維基百科說建造者模式是一種對象創建軟件設計模式,其目的是找到一種解決方案,以解決可伸縮構造函數的反模式。 1.創建型設計模式2.結構型設計模式3.行為型設計模式 創建型設計模式 簡而言之 創建型設計模式關注的是如何實例化一個或者一組相關的對象。 維基百科 在軟件工程中,創建型...
閱讀 1951·2021-09-07 10:24
閱讀 2086·2019-08-30 15:55
閱讀 2037·2019-08-30 15:43
閱讀 669·2019-08-29 15:25
閱讀 1044·2019-08-29 12:19
閱讀 1927·2019-08-23 18:32
閱讀 1515·2019-08-23 17:59
閱讀 946·2019-08-23 12:22