JavaRush /وبلاگ جاوا /Random-FA /الگوی دکوراتور جاوا

الگوی دکوراتور جاوا

در گروه منتشر شد
در کتاب «اول سر. الگوهای طراحی» توسط اریک فریمن و الیزابت رابسون آن را به صورت زیر تعریف می کند: الگوی Decorator به صورت پویا قابلیت های جدیدی را برای یک شی فراهم می کند و جایگزینی برای زیر کلاس برای گسترش عملکرد است. بیایید سعی کنیم با استفاده از یک مثال به این تعریف با جزئیات بیشتری نگاه کنیم. فرض کنید یک دین مدرن دیگر ایجاد کرده اید و قصد دارید خدمات مربوطه را به مردم ارائه دهید. زیرا روندهای مدرن گیاهخواری، بوم شناسی، توسعه انسانی را دنبال می کنند، و به دلایلی مردم از ادیان «سنتی» (یا در نهایت بی خدایی) راضی نیستند، سپس شما، پیرو جریان اصلی، دین عصر جدید دیگری را ایجاد می کنید (نوعی سنتز از موجود). ادیان، از هر یک از آنها چیزی شبیه). در ابتدا خدمات زیر را ارائه می دهید: 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 {
    // Здесь своя стоимость и другие методы
}
یا فقط از subclassing استفاده کنید، یعنی. گسترش کلاس والدین به کلاس فرزند
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);
    }
    // Здесь своя стоимость и другие методы
}
اما معایب بلافاصله قابل مشاهده است، معنویت کل جهان را توسعه می دهد، ممکن است گزینه های اضافی جدیدی داشته باشیم، که به معنای کلاس های جدید است، و اگر هنوز نیاز به ترکیب کلاس های فعلی داشته باشیم، کلاس ها به سرعت رشد خواهند کرد، حداقل ما دیگر نداریم. به اندازه کافی از کلاس Fortunelling با دو گزینه با هم، و نه جدا از هم:
public class DivinationWithChakrasAndAura implements Service {
    // Здесь своя стоимость и другие методы
}
اینجاست که می توانید از الگوی Decorator بسیار "ذخیره کننده" در جاوا استفاده کنید. برای انجام این کار، یک کلاس برای گزینه های اضافی ایجاد می کنیم که سرویس را نیز پیاده سازی می کند، اما شامل Service نیز می شود. و بر این اساس، هنگامی که ما نیاز به سفارش برای فال و حتی با 2 گزینه با هم داریم، به این صورت خواهد بود: رابط کاربری همان است که از ابتدا بود.
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