รูปแบบการออกแบบมัณฑนากร

Dec 27 2022
ฉันสามารถให้ความสำคัญกับตัวเองก่อน แม้ว่าฉันจะต้องการในภายหลังก็ตาม เรามีอินเทอร์เฟซที่เรียกว่า การชำระเงิน มีวิธีการชำระเงิน และระดับที่เป็นรูปธรรม DefaultPayment เพื่อใช้วิธีการ วิธีการใช้ราคาอาร์กิวเมนต์เพื่อทำตรรกะการชำระเงิน

ฉันสามารถให้ความสำคัญกับตัวเองก่อน แม้ว่าฉันจะต้องการในภายหลังก็ตาม

คุณสามารถเติมน้ำตาลก่อนหรือแม้แต่เพิ่มช็อกโกแลตที่ด้านบนหลังจากทำถ้วยเนสกาแฟ

เรามีอินเทอร์เฟซที่เรียกว่าการชำระเงินมีวิธีการชำระเงิน

และ DefaultPaymentระดับคอนกรีตที่จะใช้วิธีการ วิธีการใช้ราคาอาร์กิวเมนต์ทำตรรกะการชำระเงิน

public interface Payment {
    void pay(BigDecimal price);
}
public class DefaultPayment implements Payment {
    @Override
    public void pay(BigDecimal price) {
        System.out.println("Payed: " + price);
    }
}

public class Client {
    public static void main(String[] args) {
        Payment defaultPayment = new DefaultPayment();
        defaultPayment.pay(BigDecimal.valueOf(100));
    }
}

สมมติว่ามีภาษีสำหรับสินค้าที่ฉันต้องการชำระ ฉันจะทำอย่างไร

เราสามารถใช้ประโยชน์จากการออกแบบของเรา เราออกแบบสำหรับส่วนต่อประสานไม่ใช่เพื่อการใช้งาน

ดังนั้น เราสามารถสร้างคลาสสำหรับPaymentและปล่อยให้เป็นประเภทของPaymentและในขณะเดียวกันก็ถือPaymentเป็นคุณสมบัติ และอาจรับการชำระเงินโดยใช้ตัวสร้าง และเราจะเรียกคลาสนี้ว่าTaxPaymentDecorator

public class TaxPaymentDecorator implements Payment {
    private Payment payment;
    private BigDecimal tax = BigDecimal.ZERO;

    public TaxPaymentDecorator(Payment payment) {
        this.payment = payment;
    }

    @Override
    public void pay(BigDecimal price) {
        price = price.add(this.tax);
        payment.pay(price);
    }

    public BigDecimal getTax() {
        return tax;
    }

    public void setTax(BigDecimal tax) {
        this.tax = tax;
    }
}

และลูกค้าสามารถใช้TaxPaymentDecoratorดังต่อไปนี้:

public class Client {
    public static void main(String[] args) {
        TaxPaymentDecorator taxPaymentDecorator = new TaxPaymentDecorator(new DefaultPayment());
        taxPaymentDecorator.setTax(BigDecimal.valueOf(50));
        taxPaymentDecorator.pay(BigDecimal.valueOf(100));
    }
}

public class DiscountPaymentDecorator implements Payment {
    private Payment payment;
    private BigDecimal discount = BigDecimal.ZERO;

    public DiscountPaymentDecorator(Payment payment) {
        this.payment = payment;
    }

    @Override
    public void pay(BigDecimal price) {
        price = price.subtract(discount);
        payment.pay(price);
    }

    public BigDecimal getDiscount() {
        return discount;
    }

    public void setDiscount(BigDecimal discount) {
        this.discount = discount;
    }
}

public class Client {
    public static void main(String[] args) {
        TaxPaymentDecorator taxPaymentDecorator = new TaxPaymentDecorator(new DefaultPayment());
        taxPaymentDecorator.setTax(BigDecimal.valueOf(50));
        DiscountPaymentDecorator discountPaymentDecorator = new DiscountPaymentDecorator(taxPaymentDecorator);
        discountPaymentDecorator.setDiscount(BigDecimal.valueOf(10));
        discountPaymentDecorator.pay(BigDecimal.valueOf(100));
    }
}

ไดอะแกรม UML

รูปแบบการออกแบบมัณฑนากร UML ไดอะแกรม

หลักการออกแบบ

ฉันจะพูดถึงหลักการออกแบบสามประการที่นี่:

  1. การออกแบบสำหรับอินเทอร์เฟซที่ไม่ได้ใช้งานจริง:อย่างที่คุณเห็น การใช้ อินเทอร์เฟซ การชำระเงินช่วยให้เราสามารถใช้พลังของ OOP โดยการเพิ่มลักษณะการทำงานแบบไดนามิกที่รันไทม์โดยไม่มีการแก้ไขใด ๆ สำหรับการใช้งานแบบเก่า
  2. ทำให้การออกแบบของคุณเปิดสำหรับส่วนขยาย ปิดเพื่อแก้ไข:ประเด็นนี้เกี่ยวข้องกับข้อก่อนหน้า การใช้งานแบบเก่าของเราไม่ได้บังคับให้เราแก้ไขใดๆ แต่เราขยายการใช้งานแบบเก่าเพื่อเพิ่มพฤติกรรมใหม่ และฉันหมายถึงที่นี่โดยใช้ส่วนต่อประสานแทน ของการออกแบบเพื่อการนำไปใช้งาน
  3. ชอบการจัดองค์ประกอบมากกว่าการสืบทอด:มัณฑนากรใช้การจัดองค์ประกอบที่นี่แทนที่จะพยายามใช้การสืบทอด โดยทั่วไป การใช้การสืบทอดอาจทำให้เกิดปัญหาโดยการเพิ่มการมีเพศสัมพันธ์ และเราสามารถหารือเกี่ยวกับเรื่องนี้ในบล็อกแยกต่างหาก

แนบความรับผิดชอบเพิ่มเติมกับวัตถุแบบไดนามิก มัณฑนากรมอบทางเลือกที่ยืดหยุ่นให้กับการจัดประเภทย่อยเพื่อขยายฟังก์ชันการทำงาน

ในตัวอย่างของเรา เราแนบสองความรับผิดชอบแบบไดนามิกที่รันไทม์ เราเพิ่มภาษีในราคาและลบส่วนลดออกจากราคา เราไม่ได้ทำการจัดประเภทย่อยสำหรับการชำระเงินเริ่มต้นเราใช้พลังของOOPเพื่อเพิ่มพฤติกรรมของเราด้วยวิธีที่ยืดหยุ่น และนั่นคือรูปแบบมัณฑนากร