JavaRush /จาวาบล็อก /Random-TH /รูปแบบมัณฑนากร Java

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

เผยแพร่ในกลุ่ม
ในหนังสือ “มุ่งหน้าก่อน. Design Patterns” โดย Eric Freeman และ Elizabeth Robson ให้คำจำกัดความดังนี้: รูปแบบมัณฑนากรมอบความสามารถใหม่แบบไดนามิกให้กับอ็อบเจ็กต์ และเป็นทางเลือกแทนคลาสย่อยสำหรับการขยายฟังก์ชันการทำงาน ลองพิจารณาคำจำกัดความนี้โดยละเอียดโดยใช้ตัวอย่าง สมมติว่าคุณได้สร้างศาสนาสมัยใหม่ขึ้นมาหนึ่งศาสนาและวางแผนที่จะให้บริการที่เกี่ยวข้องแก่ผู้คน เพราะ กระแสสมัยใหม่ไล่ตามการกินเจ นิเวศวิทยา การพัฒนามนุษย์ และด้วยเหตุผลบางอย่าง ผู้คนไม่พอใจกับศาสนา "ดั้งเดิม" (หรือลัทธิต่ำช้าในท้ายที่สุด) จากนั้นคุณตามกระแสหลักสร้างศาสนายุคใหม่ขึ้นมาใหม่ (เป็นการสังเคราะห์จากที่มีอยู่ ศาสนาโดยเอาสิ่งที่ชอบไปจากกัน) ในตอนแรกคุณให้บริการดังนี้ 1. ดูดวง 2. ดูดวง เช่น ทุกอย่างมีลักษณะดังนี้: มีอินเทอร์เฟซบริการพร้อมราคาแน่นอน :) และคำอธิบาย
public interface Service {
    public double getPrice();
    public String getLabel();
}
และบริการ
public class Divination implements Service {
    private String label;
    private double price;

    public Divination(String label, double price) {
        this.label = label;
        this.price = price;
    }

    public double getPrice() {
        return this.price;
    }

    public String getLabel() {
        return this.label;
    }
}
public class Horoscope implements Service {
    private String label;
    private double price;

    public Horoscope(String label, double price) {
        this.label = label;
        this.price = price;
    }

    public double getPrice() {
        return this.price;
    }

    public String getLabel() {
        return this.label;
    }
}
ดังนั้นจึงมี 2 คำสั่งปรากฏขึ้น (ดูดวงด้วยไพ่ทาโรต์และดูดวงส่วนตัวจากลูกค้า):
public static void main(String[] args) {
    double cost;
    // Гадание на Таро
    Service taro = new Divination("Таро", 1000);
    // И персональный гороскоп
    Service personalHoroscope = new Horoscope("Персональный гороскоп", 9000);
    cost = taro.getPrice() + personalHoroscope.getPrice();

    System.out.println(cost);
}
และผลลัพธ์ของโปรแกรม:
10000.0
ทุกอย่างคงจะดี แต่มีหลายร้อยหรือหลายพันคนเหมือนคุณ และเราจำเป็นต้องพัฒนาจิตวิญญาณของผู้คนต่อไป ไม่เช่นนั้นพวกเขาจะไม่สนใจอีกต่อไป ดังนั้นจึงมีการเสนอตัวเลือกเพิ่มเติมสำหรับบริการปัจจุบันเป็นตัวเลือก ตัวอย่างเช่นเมื่อเลือกบริการดูดวง (ไพ่ทาโรต์หรือกากกาแฟ) เป็นตัวเลือกเพิ่มเติมคุณสามารถสั่งซื้อลักษณะของจักระหรือออร่าได้ (โดยมีค่าใช้จ่ายเองสำหรับแต่ละรายการ) สิ่งนี้จะถูกนำไปใช้อย่างไรเพื่อไม่ให้ทำการเปลี่ยนแปลงคลาสบริการที่มีอยู่ซึ่งทุกอย่างได้รับการกำหนดค่าและคำนวณอย่างถูกต้องแล้ว คุณสามารถสร้างคลาสเพิ่มเติม Divination + Chakras หรือ Divination + Aura ให้กับ Divination ปัจจุบันได้:
public class Divination implements Service {
    // Здесь своя стоимость и другие методы
}
public class DivinationWithChakras implements Service {
    // Здесь своя стоимость и другие методы
}
public class DivinationWithAura implements Service {
    // Здесь своя стоимость и другие методы
}
หรือเพียงแค่ใช้คลาสย่อยเช่น ขยายคลาสผู้ปกครองไปยังคลาสย่อย
public class DivinationWithAura extends Divination {
    public DivinationWithAura(String label, double price) {
        super(label, price);
    }
    // Здесь своя стоимость и другие методы
}
public class DivinationWithChakras extends Divination {
    public DivinationWithChakras(String label, double price) {
        super(label, price);
    }
    // Здесь своя стоимость и другие методы
}
แต่ข้อเสียก็มองเห็นได้ทันที พัฒนาจิตวิญญาณของคนทั้งโลก เราอาจมีตัวเลือกใหม่เพิ่มเติม ซึ่งก็คือคลาสใหม่ๆ และหากเรายังต้องรวมคลาสปัจจุบันเข้าด้วยกัน คลาสก็จะเติบโตอย่างรวดเร็ว อย่างน้อยเราก็ไม่มีอีกต่อไป วิชาทำนายดวงพอมี 2 ทางเลือกด้วยกัน และไม่แยกกัน:
public class DivinationWithChakrasAndAura implements Service {
    // Здесь своя стоимость и другие методы
}
นี่คือที่ที่คุณสามารถใช้รูปแบบมัณฑนากรที่ "ประหยัด" ใน Java ได้ ในการดำเนินการนี้ เราจะสร้างคลาสสำหรับตัวเลือกเพิ่มเติม ซึ่งจะใช้บริการด้วย แต่ยังประกอบด้วยบริการด้วย และด้วยเหตุนี้เมื่อเราจำเป็นต้องสั่งการทำนายดวงและถึงแม้จะมี 2 ตัวเลือกรวมกันก็จะได้หน้าตาแบบนี้ครับ หน้าตา Interface เหมือนเดิมตั้งแต่แรกเริ่มเลย
public interface Service {
    public double getPrice();
    public String getLabel();
}
บริการ 2 ระดับเหมือนเดิม:
public class Divination implements Service {
    private String label;
    private double price;

    public Divination(String label, double price) {
        this.label = label;
        this.price = price;
    }

    public double getPrice() {
        return this.price;
    }

    public String getLabel() {
        return this.label;
    }
}
public class Horoscope implements Service {
    private String label;
    private double price;

    public Horoscope(String label, double price) {
        this.label = label;
        this.price = price;
    }

    public double getPrice() {
        return this.price;
    }

    public String getLabel() {
        return this.label;
    }
}
มัณฑนากรสำหรับตัวเลือกเพิ่มเติม
public class OptionDecorator implements Service {
    private Service service;
    private String label;
    private double price;

    public OptionDecorator(Service service, String label, double price) {
        this.service = service;
        this.label = label;
        this.price = price;
    }

    public double getPrice() {
        return this.price + service.getPrice();
    }

    public String getLabel() {
        return this.label + service.getLabel();
    }
}
และตัวเลือกของตัวเอง (2 จนถึงตอนนี้):
public class Aura extends OptionDecorator {
    public Aura(Service service) {
        super(service, "Характеристика ауры", 1500);
    }
}
public class Chakra extends OptionDecorator {
    public Chakra(Service service) {
        super(service, "Характеристика чакр", 500);
    }
}
เอ่อ..ออเดอร์เองนะ.
public static void main(String[] args) {
    // Гадание на Таро
    Service taro = new Divination("Таро", 1000);
    Service chakra = new Chakra(taro);
    Service aura = new Aura(chakra);

    // И общая стоимость
    System.out.println(aura.getPrice());
}
3000.0
ซึ่งให้ผลรวมของบริการหลักและตัวเลือกเพิ่มเติม 2 รายการ ซึ่งหมายความว่าไม่จำเป็นต้องมีการเพิ่มทุกครั้ง ตัวเลือก (หรือทั้งสองอย่างรวมกัน) เพื่อสร้างคลาสใหม่ นอกจากนี้ ตัวเลือกเหล่านี้สามารถใช้ได้ไม่เพียงแต่กับบริการทำนายดวงชะตาเท่านั้น แต่ยังรวมถึงบริการดูดวงด้วย ดังนั้นในอนาคตอันใกล้นี้เราจำเป็นต้องใช้ตัวเลือกเพิ่มเติมต่อไปนี้: - ความเข้ากันได้ของพันธมิตรอวาตาร์บนโซเชียลเน็ตเวิร์ก - ปรับปรุงกระแสเงินสดผ่านช่องทางระยะไกล เราจะต้องเขียนคลาสเพิ่มเติมเพียง 2 คลาสเท่านั้น:
public class Channeling extends OptionDecorator {
    public Channeling(Service service) {
        super(service, "Полет в Поле Чудес", 99999);
    }
}
public class Avatar extends OptionDecorator {
    public Avatar(Service service) {
        super(service, "Ваша любовь в соц сетях", 5555);
    }
}
และคุณสามารถเพิ่มลงในบริการใดก็ได้:
public static void main(String[] args) {
    // Гадание на Таро
    Service taro = new Divination("Таро", 1000);
    Service chakra = new Chakra(taro);
    Service aura = new Aura(chakra);

    // И общая стоимость
    System.out.println(aura.getPrice());

    // Гороскоп
    Service horoscope = new Horoscope("Персональный гороскоп", 1000);
    Service channenling = new Channeling(horoscope);
    Service avatar = new Avatar(channenling);

    // И общая стоимость
    System.out.println(avatar.getPrice());
}
และผลลัพธ์ของโปรแกรม (ซึ่งเราต้องการ):
3000.0
106554.0
ความคิดเห็น
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION