詳解Java中的五種設(shè)計(jì)模式

設(shè)計(jì)模式是一種可重用的解決方案,用于解決軟件設(shè)計(jì)中常見的問(wèn)題。不同類型的設(shè)計(jì)模式針對(duì)解決不同的特定問(wèn)題或問(wèn)題組合。
如下圖所示,一些常見的設(shè)計(jì)模式類型包括處理對(duì)象創(chuàng)建的創(chuàng)建型模式;處理對(duì)象組合和組織的結(jié)構(gòu)型模式;以及處理對(duì)象和類之間通信的行為型模式。

本文分享幾種與Java中常用的創(chuàng)建型設(shè)計(jì)模式相關(guān)的代碼示例。
創(chuàng)建型設(shè)計(jì)模式
創(chuàng)建型設(shè)計(jì)模式提供了各種對(duì)象創(chuàng)建機(jī)制,從而增加了現(xiàn)有代碼的靈活性和重用性。
其主要功能是以最佳方式提供非常具體的解決方案。它們可以進(jìn)一步分為以下類別。
1. 單例
單例是一種創(chuàng)建型設(shè)計(jì)模式,它確保一個(gè)類只有一個(gè)實(shí)例,并提供對(duì)該實(shí)例的全局訪問(wèn)點(diǎn)。

單例模式基于對(duì)象只有一個(gè)實(shí)例的概念,從而實(shí)現(xiàn)對(duì)資源的全局控制。簡(jiǎn)而言之,單例設(shè)計(jì)模式確保只創(chuàng)建一個(gè)類的實(shí)例,并且該實(shí)例在應(yīng)用程序內(nèi)可以全局訪問(wèn)。
public class SingletonClass {
    private static SingletonClass instance;
    private SingletonClass() {
        // 私有構(gòu)造函數(shù),防止外部實(shí)例化
    }
    public static SingletonClass getInstance() {
        if (instance == null) {
            instance = new SingletonClass();
        }
        return instance;
    }
}如下所示,當(dāng)我們發(fā)送Postman請(qǐng)求時(shí),控制器類和結(jié)果將是同一個(gè)實(shí)例:
@RestController
@RequestMapping("/api")
public class SingletonController  {
    private SingletonClass singletonClass;
    public SingletonController(SingletonClass singletonClass) {
        this.singletonClass = singletonClass;
    }
    @GetMapping("/singleton")
    public String getSingleton() {
        return "This is a singleton instance: " + singletonClass.toString();
    }
}
當(dāng)您想要確保類僅存在一個(gè)實(shí)例時(shí)(例如,由程序的不同部分共享的單個(gè)數(shù)據(jù)庫(kù)對(duì)象),您應(yīng)該使用單例設(shè)計(jì)模式。
2. 工廠
工廠方法是一種創(chuàng)建型設(shè)計(jì)模式,它提供了一種在創(chuàng)建過(guò)程中無(wú)需指定其具體類即可創(chuàng)建產(chǎn)品對(duì)象的解決方案。

以下是Java代碼示例,PaymentProcessor是定義處理付款的合同的接口。
public interface PaymentProcessor {
    void processPayment();
}CreditCardPaymentProcessor和PaypalPaymentProcessor是實(shí)現(xiàn)PaymentProcessor接口的具體類。這些類為CreditCard和PayPal付款特定的processPayment()方法提供了實(shí)現(xiàn)。
@Service
public class CreditCardPaymentProcessor implements PaymentProcessor {
    @Override
    public void processPayment() {
        // 信用卡支付交易
    }
}
@Service
public class PaypalPaymentProcessor implements PaymentProcessor {
    @Override
    public void processPayment() {
        //  PayPal支付交易
    }
}PaymentProcessorFactory是實(shí)現(xiàn)工廠設(shè)計(jì)模式的工廠類。該類負(fù)責(zé)根據(jù)給定的付款方式創(chuàng)建不同PaymentProcessor實(shí)現(xiàn)的實(shí)例。
@Component
public class PaymentProcessorFactory {
    private final CreditCardPaymentProcessor creditCardPaymentProcessor;
    private final PaypalPaymentProcessor paypalPaymentProcessor;
    public PaymentProcessorFactory(CreditCardPaymentProcessor creditCardPaymentProcessor,
                                   PaypalPaymentProcessor paypalPaymentProcessor) {
        this.creditCardPaymentProcessor = creditCardPaymentProcessor;
        this.paypalPaymentProcessor = paypalPaymentProcessor;
    }
    public PaymentProcessor createPaymentProcessor(String paymentMethod) {
        if (paymentMethod.equalsIgnoreCase("creditcard")) {
           return creditCardPaymentProcessor;
        } else if (paymentMethod.equalsIgnoreCase("paypal")) {
            return paypalPaymentProcessor;
        }
        throw new IllegalArgumentException("Invalid payment method: " + paymentMethod);
    }
}入口點(diǎn)處理對(duì)/processPayment/{paymentMethod}的請(qǐng)求,并使用PaymentProcessorFactory根據(jù)提供的paymentMethod創(chuàng)建適當(dāng)?shù)母犊钐幚砥?。這簡(jiǎn)化了代碼并使添加新付款處理器變得容易。

工廠方法是一種用于節(jié)省系統(tǒng)資源的設(shè)計(jì)模式,它通過(guò)重復(fù)使用現(xiàn)有對(duì)象而不是重復(fù)構(gòu)建它們來(lái)實(shí)現(xiàn)這一目的。
3. 抽象工廠
抽象工廠是一種創(chuàng)建型設(shè)計(jì)模式,它允許您生成相關(guān)對(duì)象系列,無(wú)需指定其具體類。

以下是Java代碼示例:
//工廠類
public interface ProductFactory {
    Product createProduct();
}
public class ProductAFactory implements ProductFactory{
    @Override
    public Product createProduct() {
        return new ProductA();
    }
}
public class ProductBFactory implements ProductFactory{
    @Override
    public Product createProduct() {
        return new ProductB();
    }
}//產(chǎn)品類
public interface Product {
    String getName();
}
public class ProductA implements Product {
    @Override
    public String getName() {
        return "Product A";
    }
}
public class ProductB implements Product {
    @Override
    public String getName() {
        return "Product B";
    }
}
// 使用 ProductAFactory 創(chuàng)建產(chǎn)品 A
ProductFactory productAFactory = new ProductAFactory();
Product productA = productAFactory.createProduct();
System.out.println("Product A: " + productA.getName());
// 使用 ProductBFactory 創(chuàng)建產(chǎn)品 B
ProductFactory productBFactory = new ProductBFactory();
Product productB = productBFactory.createProduct();
System.out.println("Product B: " + productB.getName());抽象工廠模式在處理不同組相關(guān)項(xiàng)目時(shí)非常有用,它可以避免代碼依賴于這些項(xiàng)目的特定類型。您可能事先不知道這些類型,或者希望為將來(lái)添加更多類型留出空間。這樣,您的代碼可以更加靈活和可擴(kuò)展。
4. Builder
Builder是一種創(chuàng)建型設(shè)計(jì)模式,它允許您以逐步構(gòu)建的方式創(chuàng)建復(fù)雜的對(duì)象。通過(guò)使用Builder模式,您可以使用相同的構(gòu)建代碼來(lái)生成不同類型和表示形式的對(duì)象。這種靈活性使得對(duì)象的構(gòu)建過(guò)程更加可控和可定制。

以下是Java代碼示例::
@Builder
@Getter
@Setter
public class Beer {
    //必填屬性
    private String name;
    private double drinkSize;
    private double alcoholPercentage;
    private double price;
    // 其他屬性
    private String brewery;            // 生產(chǎn)啤酒的釀酒廠
    private String countryOfOrigin;    // 啤酒原產(chǎn)國(guó)
    private String description;        // 對(duì)啤酒特點(diǎn)的簡(jiǎn)要描述
    private String packaging;          // 包裝類型(瓶裝、罐裝、生啤等)
    private String servingTemperature; // 推薦的飲用溫度
    private String foodPairing;        // 適合搭配該啤酒的食物
}@RestController
@RequestMapping("/api/beers")
public class BeerController {
    @GetMapping("/basic")
    public String createStandardBeer() {
        Beer beer = Beer.builder()
                .name("Standard Beer")
                .drinkSize(500)
                .alcoholPercentage(5.0)
                .price(5.99)
                .build();
        return "Created beer: " + beer.getName() + 
                ", Drink Size: " + beer.getDrinkSize() +
                ", Alcohol Percentage: " + beer.getAlcoholPercentage() +
                ", Price: " + beer.getPrice();
    }
    @GetMapping("/premium")
    public String createPremiumBeer() {
        Beer beer = Beer.builder()
                .name("Sample Beer")
                .drinkSize(330)
                .alcoholPercentage(5.0)
                .price(10.99)
                .brewery("Crafty Brews")
                .countryOfOrigin("United States")
                .description("A refreshing lager with a smooth taste.")
                .packaging("Bottle")
                .servingTemperature("4-6°C")
                .foodPairing("Pairs well with grilled chicken and salads.")
                .build();
        return "Created beer: " + beer.getName() + 
                ", Drink Size: " + beer.getDrinkSize() +
                ", Alcohol Percentage: " + beer.getAlcoholPercentage() +
                ", Price: " + beer.getPrice() +
                ", Brewery: " + beer.getBrewery() +
                ", Country of Origin: " + beer.getCountryOfOrigin() +
                ", Description: " + beer.getDescription() +
                ", Packaging: " + beer.getPackaging() +
                ", Serving Temperature: " + beer.getServingTemperature() +
                ", Food Pairing: " + beer.getFoodPairing();
    }
}

優(yōu)點(diǎn):
- 減少構(gòu)造函數(shù)中的參數(shù)數(shù)量并提供可讀的方法調(diào)用。
 - 允許在完整狀態(tài)下實(shí)例化對(duì)象。
 - 簡(jiǎn)化了不可變對(duì)象的構(gòu)建過(guò)程。
 
缺點(diǎn):
- 它會(huì)增加代碼行數(shù),但提供了設(shè)計(jì)靈活性和改進(jìn)的代碼可讀性。
 - 需要為每種產(chǎn)品類型創(chuàng)建單獨(dú)的ConcreteBuilder類。
 
5. 原型
原型是一種創(chuàng)建型設(shè)計(jì)模式,它允許您復(fù)制現(xiàn)有對(duì)象,而不依賴于它們的具體類。

以下是Java代碼示例:
designpatterns
└── creational
    └── prototype
        ├── controller
        │   └── TreeController.java
        ├── model
        │   ├── Tree.java
        │   ├── PlasticTree.java
        │   └── PineTree.java
        └── PrototypeDemoApplication.java//抽象類
@Getter
@Setter
public abstract class Tree implements Cloneable {
    private String type;
    public abstract void copy();
    @Override
    protected Object clone() throws CloneNotSupportedException {
        return super.clone();
    }
}
//具體類-松樹
public class PineTree extends Tree {
    public PineTree() {
        setType("Pine Tree");
    }
    @Override
    public void copy() {
        //實(shí)現(xiàn)
    }
}
//具體類-塑料樹
  public PlasticTree() {
        setType("Plastic Tree");
    }
    @Override
    public void copy() {
        //實(shí)現(xiàn)
    }@RestController
@RequestMapping("/api/trees")
public class TreeController {
    @GetMapping("/plastic")
    public String createPlasticTree() {
        Tree plasticTree = new PlasticTree();
        return "Created: " + plasticTree.getType();
    }
    @GetMapping("/pine")
    public String createPineTree() {
        Tree pineTree = new PineTree();
        return "Created: " + pineTree.getType();
    }
}

當(dāng)需要?jiǎng)?chuàng)建的新對(duì)象與現(xiàn)有對(duì)象僅存在輕微差異時(shí),原型模式非常有用。通過(guò)提前設(shè)置具有正確設(shè)置的實(shí)例,我們可以在需要更多相似對(duì)象時(shí)進(jìn)行復(fù)制,從而節(jié)省了創(chuàng)建對(duì)象的時(shí)間和資源。















 
 
 









 
 
 
 