這是一系列關於設計模式的部落格的開始。在本部落格中,我們將討論第一種設計模式,即創建模式。這裡將透過一些現實世界的例子來討論屬於創建模式的類型。我將使用 Java 作為我的選擇語言。
設計模式在軟體開發中發揮著至關重要的作用,為常見問題提供經過驗證的解決方案並推廣最佳實踐。它們就像預製的藍圖,您可以自訂它們來解決程式碼中反覆出現的設計問題。
在物件導向程式設計中,創建設計模式發揮著重要作用,因為它們使物件實例化與其使用分離成為可能,從而提高了物件創建的靈活性和可擴展性。這篇部落格文章將重點放在五種主要類型的創建設計模式:工廠方法、抽象工廠、建構器、原型和單例。為了展示每個方法的工作原理,我們將使用 Java 中的實際範例。
1。工廠方法
工廠方法模式定義了一個用於創建物件的接口,但允許子類別更改將創建的物件的類型。此模式支援 Java 中的松耦合,無需將特定於應用程式的類別綁定到程式碼中。
現實場景:假設一家物流公司使用卡車和船舶等各種車輛運輸貨物。車輛類型取決於所需的運輸方式。
// Product Interface interface Transport { void deliver(); } // Concrete Products class Truck implements Transport { @Override public void deliver() { System.out.println("Deliver by land in a truck."); } } class Ship implements Transport { @Override public void deliver() { System.out.println("Deliver by sea in a ship."); } } // Creator abstract class Logistics { public abstract Transport createTransport(); public void planDelivery() { Transport transport = createTransport(); transport.deliver(); } } // Concrete Creators class RoadLogistics extends Logistics { @Override public Transport createTransport() { return new Truck(); } } class SeaLogistics extends Logistics { @Override public Transport createTransport() { return new Ship(); } } // let's call the main class public class Main { public static void main(String[] args) { Logistics logistics = new RoadLogistics(); logistics.planDelivery(); logistics = new SeaLogistics(); logistics.planDelivery(); } }
2。抽象工廠
抽象工廠模式提供了一個介面,用於建立相關或依賴物件系列,而無需指定它們的特定類別。當系統需要獨立於其物件的創建方式時,它非常有用。
現實生活場景:想像一家家具店,出售不同類型的家具套裝,例如維多利亞風格和現代風格。每套都包含椅子、沙發等產品。
// Abstract Products interface Chair { void sitOn(); } interface Sofa { void lieOn(); } // Concrete Products class VictorianChair implements Chair { @Override public void sitOn() { System.out.println("Sitting on a Victorian chair."); } } class ModernChair implements Chair { @Override public void sitOn() { System.out.println("Sitting on a Modern chair."); } } class VictorianSofa implements Sofa { @Override public void lieOn() { System.out.println("Lying on a Victorian sofa."); } } class ModernSofa implements Sofa { @Override public void lieOn() { System.out.println("Lying on a Modern sofa."); } } // Abstract Factory interface FurnitureFactory { Chair createChair(); Sofa createSofa(); } // Concrete Factories class VictorianFurnitureFactory implements FurnitureFactory { @Override public Chair createChair() { return new VictorianChair(); } @Override public Sofa createSofa() { return new VictorianSofa(); } } class ModernFurnitureFactory implements FurnitureFactory { @Override public Chair createChair() { return new ModernChair(); } @Override public Sofa createSofa() { return new ModernSofa(); } } // Client code public class Main { private static void createFurniture(FurnitureFactory factory) { Chair chair = factory.createChair(); Sofa sofa = factory.createSofa(); chair.sitOn(); sofa.lieOn(); } public static void main(String[] args) { FurnitureFactory victorianFactory = new VictorianFurnitureFactory(); createFurniture(victorianFactory); FurnitureFactory modernFactory = new ModernFurnitureFactory(); createFurniture(modernFactory); } }
3。建造者
Builder 模式將複雜物件的建構與其表示分離,允許相同的建構過程建立不同的表示。它對於創建具有許多可選屬性的物件特別有用。
現實場景:考慮一個線上披薩訂購系統,客戶可以使用各種配料、尺寸和外皮類型客製化披薩。
// Product class Pizza { private String dough = ""; private String sauce = ""; private String topping = ""; public void setDough(String dough) { this.dough = dough; } public void setSauce(String sauce) { this.sauce = sauce; } public void setTopping(String topping) { this.topping = topping; } @Override public String toString() { return "Pizza [dough=" + dough + ", sauce=" + sauce + ", topping=" + topping + "]"; } } // Builder Interface interface PizzaBuilder { void buildDough(); void buildSauce(); void buildTopping(); Pizza getPizza(); } // Concrete Builders class HawaiianPizzaBuilder implements PizzaBuilder { private Pizza pizza; public HawaiianPizzaBuilder() { this.pizza = new Pizza(); } @Override public void buildDough() { pizza.setDough("cross"); } @Override public void buildSauce() { pizza.setSauce("mild"); } @Override public void buildTopping() { pizza.setTopping("ham+pineapple"); } @Override public Pizza getPizza() { return this.pizza; } } class SpicyPizzaBuilder implements PizzaBuilder { private Pizza pizza; public SpicyPizzaBuilder() { this.pizza = new Pizza(); } @Override public void buildDough() { pizza.setDough("pan baked"); } @Override public void buildSauce() { pizza.setSauce("hot"); } @Override public void buildTopping() { pizza.setTopping("pepperoni+salami"); } @Override public Pizza getPizza() { return this.pizza; } } // Director class Waiter { private PizzaBuilder pizzaBuilder; public void setPizzaBuilder(PizzaBuilder pb) { pizzaBuilder = pb; } public Pizza getPizza() { return pizzaBuilder.getPizza(); } public void constructPizza() { pizzaBuilder.buildDough(); pizzaBuilder.buildSauce(); pizzaBuilder.buildTopping(); } } // Client code public class Main { public static void main(String[] args) { Waiter waiter = new Waiter(); PizzaBuilder hawaiianPizzaBuilder = new HawaiianPizzaBuilder(); PizzaBuilder spicyPizzaBuilder = new SpicyPizzaBuilder(); waiter.setPizzaBuilder(hawaiianPizzaBuilder); waiter.constructPizza(); Pizza pizza1 = waiter.getPizza(); System.out.println("Pizza built: " + pizza1); waiter.setPizzaBuilder(spicyPizzaBuilder); waiter.constructPizza(); Pizza pizza2 = waiter.getPizza(); System.out.println("Pizza built: " + pizza2); } }
4。原型
原型模式用於透過複製現有物件(稱為原型)來建立新物件。當建立新物件的成本昂貴時,此模式很有用。
現實場景:想像一個圖形編輯器,您可以在其中建立、複製和編輯形狀。
import java.util.HashMap; import java.util.Map; // Prototype abstract class Shape implements Cloneable { private String id; protected String type; abstract void draw(); public String getType() { return type; } public String getId() { return id; } public void setId(String id) { this.id = id; } public Object clone() { Object clone = null; try { clone = super.clone(); } catch (CloneNotSupportedException e) { e.printStackTrace(); } return clone; } } // Concrete Prototypes class Rectangle extends Shape { public Rectangle() { type = "Rectangle"; } @Override public void draw() { System.out.println("Drawing a Rectangle."); } } class Circle extends Shape { public Circle() { type = "Circle"; } @Override public void draw() { System.out.println("Drawing a Circle."); } } // Prototype Registry class ShapeCache { private static Map<String, Shape> shapeMap = new HashMap<>(); public static Shape getShape(String shapeId) { Shape cachedShape = shapeMap.get(shapeId); return (Shape) cachedShape.clone(); } public static void loadCache() { Rectangle rectangle = new Rectangle(); rectangle.setId("1"); shapeMap.put(rectangle.getId(), rectangle); Circle circle = new Circle(); circle.setId("2"); shapeMap.put(circle.getId(), circle); } } // Client code public class Main { public static void main(String[] args) { ShapeCache.loadCache(); Shape clonedShape1 = ShapeCache.getShape("1"); System.out.println("Shape: " + clonedShape1.getType()); Shape clonedShape2 = ShapeCache.getShape("2"); System.out.println("Shape: " + clonedShape2.getType()); } }
5。辛格頓
單例模式確保一個類別只有一個實例並提供對其的全域存取點。此模式通常用於日誌記錄、快取和執行緒池。
現實場景:想像一個印表機後台處理程序,其中只有一個實例應該管理所有列印作業。
class PrinterSpooler { private static PrinterSpooler instance; private PrinterSpooler() { // private constructor to prevent instantiation } public static PrinterSpooler getInstance() { if (instance == null) { instance = new PrinterSpooler(); } return instance; } public void print(String document) { System.out.println("Printing document: " + document); } } // Client code public class Main { public static void main(String[] args) { PrinterSpooler spooler1 = PrinterSpooler.getInstance(); PrinterSpooler spooler2 = PrinterSpooler.getInstance(); spooler1.print("Document 1"); spooler2.print("Document 2"); System.out.println("Are both spoolers the same instance? " + (spooler1 == spooler2)); } }
https://refactoring.guru/
https://www.javatpoint.com/design-patterns-in-java
https://www.digitalocean.com/community/tutorials/java-design-patterns-example-tutorial
以上是創建完美的程式碼:理解創建模式的詳細內容。更多資訊請關注PHP中文網其他相關文章!