JavaRush /Java blogi /Random-UZ /Zavod usuli va abstrakt zavod naqshlari

Zavod usuli va abstrakt zavod naqshlari

Guruhda nashr etilgan
Kitobda "Birinchi navbatda bosh. Dizayn naqshlari" ushbu naqshlarni quyidagicha belgilaydi: Zavod usuli namunasi ob'ektni yaratish uchun interfeysni belgilaydi, lekin pastki sinflarga yaratiladigan misol sinfini tanlash imkonini beradi. Shunday qilib, Factory usuli instantsiya operatsiyasini quyi sinflarga topshiradi. Abstrakt zavod namunasi o'zaro bog'liq yoki o'zaro bog'liq ob'ektlar oilalarini ularning aniq sinflarini ko'rsatmasdan yaratish uchun interfeysni ta'minlaydi. Keling, buni batafsilroq tushunishga harakat qilaylik. Aytaylik, siz rohib bo'lishga qaror qilgan odamlar haqida o'yin yozishga qaror qildingiz ... (bu erda sizga o'ziga xos va g'ayrioddiy narsa kerak) rohiblar. Biz quyidagilardan boshlashimiz mumkin. 1) Monk sinfini va bolalar sinflarini yarating (birinchi navbatda yarataylik):
public abstract class Monk {

    public abstract void description();
}
public class OrthodoxMonk extends Monk {
    @Override
    public void description() {
        System.out.println("Я православный монах");
    }
}
2) Va, albatta, monastir sinfini yarating, unda siz "monastir va'dalarini" amalga oshirishingiz mumkin:
public class Monastery {
    private Monk monk;

    public void createMonk(String typeName) {
        this.monk = switch (typeName) {
            case "ORTODOX" -> new OrthodoxMonk();
            default -> null;
        };
    }

    public Monk getMonk() {
        return monk;
    }
}
Keling, natijani tekshiramiz:
public class Main {
    public static void main(String[] args) {
        Monastery monastery = new Monastery();
        monastery.createMonk("ORTODOX");
        monastery.getMonk().description();
    }
}
Я православный монах
Agar siz katolik rohibini yaratishingiz kerak bo'lsa, sizga kerak bo'ladi A) Katolik rohib uchun yangi sinf yarating:
public class CatholicMonk extends Monk {
    @Override
    public void description() {
        System.out.println("Я католический монах");
    }
}
B) Monastir sinfiga o'zgartirishlar kiriting:
public class Monastery {
    private Monk monk;

    public void createMonk(String typeName) {
        this.monk = switch (typeName) {
            case "ORTODOX" -> new OrthodoxMonk();
            case "CATHOLIC" -> new CatholicMonk();
            default -> null;
        };
    }

    public Monk getMonk() {
        return monk;
    }
}
va shuning uchun har safar yangi turdagi rohiblar paydo bo'lganda, siz yangi sinf yaratishingiz va mavjudini tahrirlashingiz kerak bo'ladi. Bu holda qandaydir tarzda bizning monastir sinfini o'zgarishlardan "kapsulyatsiya qilish" uchun nima qilish kerak. Siz zavod usuli namunasidan foydalanib ko'rishingiz mumkin. Bu qanday ko'rinishga ega bo'ladi A) Keling, rohiblar sinfini shunday qoldiraylik, faqat anglikan rohibini qo'shishdan tashqari (nafaqat katoliklar va pravoslav nasroniylar monastizmga ega):
public abstract class Monk {

    public abstract void description();
}
public class OrthodoxMonk extends Monk {
    @Override
    public void description() {
        System.out.println("Я православный монах");
    }
}
public class CatholicMonk extends Monk {
    @Override
    public void description() {
        System.out.println("Я католический монах");
    }
}
public class AnglicanMonk extends Monk {
    @Override
    public void description() {
        System.out.println("Я англиканский монах");
    }
}
B) Monastir sinfini quyidagicha o'zgartiramiz (uni va uning usulini abstrakt qilaylik). Bu erda biz faqat zavod usulidan foydalanamiz :
public abstract class Monastery {
    protected abstract Monk createMonk();
}
va usulni amalga oshirish bilan bolalar sinflarini yarating:
public class OrthodoxMonastery extends Monastery {
    @Override
    protected Monk createMonk() {
        return new OrthodoxMonk();
    }
}
public class CatholicMonastery extends Monastery {
    @Override
    protected Monk createMonk() {
        return new CatholicMonk();
    }
}
public class AnglicanMonastery extends Monastery {
    @Override
    protected Monk createMonk() {
        return new AnglicanMonk();
    }
}
B) Keling, kodni tekshiramiz
public class Main {
    public static void main(String[] args) {
        Monastery monastery;

        monastery = new OrthodoxMonastery();
        monastery.createMonk().description();

        monastery = new CatholicMonastery();
        monastery.createMonk().description();

        monastery = new AnglicanMonastery();
        monastery.createMonk().description();
    }
}
Я православный монах
Я католический монах
Я англиканский монах
Bular. biz hozir ko'rib turganimizdek, rohiblarning yangi turlarini qo'shganda, mavjud sinflarni o'zgartirishga hojat qolmaydi, lekin agar kerak bo'lsa, yangilarini qo'shing (ma'lum bir monastir va rohib sinfi). Ehtimol, kimdir Monk sinfida boshidanoq bo'lgan tavsiflash usuli ham Fabrika ekanligini payqagandir :) Zavod usulining ta'rifida aytilishicha, bizning naqshimiz ob'ektni yaratish interfeysini belgilaydi, lekin biz hech qanday yaratmadik. interfeyslar, garchi biz Monastery sinfini interfeys sifatida yaratishimiz va uni maxsus dasturlarda amalga oshirishimiz mumkin edi. Bu kengroq ma'noda "interfeys" so'ziga ishora qiladi. Ta'rif, shuningdek, pastki sinflarga o'zlari yaratgan misol sinfini tanlash imkonini beradi . Bu erda biz faqat kichik sinflar (bolalar sinflari) ushbu usulni amalga oshirishini ko'ramiz (ya'ni, rohib ob'ektlarini yaratish uchun bu vakolatlar ularga berilgan). Keling, dasturimizni biroz kengaytiraylik, u yoki bu mazhabda turli xil rohiblar bo'lishi mumkinligini tanishtiramiz. Masalan, pravoslavlikda pravoslav cherkovining monastirlar va monastirlar haqidagi pozitsiyasiga asoslanib (Rus pravoslav cherkovi yepiskoplari kengashida 2017 yil 29 noyabr - 2 dekabrda qabul qilingan) 2 turdagi rohiblar mavjud degan xulosaga kelishimiz mumkin. : - Kichikroq sxema (mantiya). - Sxema (ajoyib sxema). Bundan tashqari, "tayyorgarlik bosqichlari" mavjud, ammo odamlar rohiblar (Trudnik, Ajam va Ryasofor yoki Monk) hisoblanmaydi, chunki ular monastir va'dalarini olmaydilar. Shuning uchun biz ularni hisobga olmaymiz. Bu holatda biz nimani olamiz: A) Fabrika usuli bilan monastir sinfi (soddalashtirish uchun hozircha pravoslav monastizmiga e'tibor qarataylik) :
public abstract class Monastery {
    protected abstract Monk createMonk(String type);
}
va ma'lum bir monastir
public class OrthodoxMonastery extends Monastery {

    @Override
    protected Monk createMonk(String type) {
        return new OrthodoxMonk(type);
    }
}
B) Rohiblar sinfini tuzatamiz:
public abstract class Monk {
    String kind;

    public Monk(String kind) {
        this.kind = kind;
    }

    public abstract void description();
}
va bolalar sinfi:
public class OrthodoxMonk extends Monk {
    public OrthodoxMonk(String kind) {
        super(kind);
    }

    @Override
    public void description() {
        System.out.println("Я православный монах - " + kind);
    }
}
C) Keling, kodimizni tekshiramiz:
public class Main {
    public static void main(String[] args) {
        Monastery monastery = new OrthodoxMonastery();
        monastery.createMonk("Мантийный монах").description();
        monastery.createMonk("Великосхимник").description();
    }
}
Я православный монах - Мантийный монах
Я православный монах — Великосхимник
Shunday qilib, Factory Method naqshidan foydalanib, biz ilgari yozilgan sinflarni o'zgartirishimiz shart emasligiga erishdik, ammo rohiblarning tasvirlarini (turlarini) kengaytirishda kodga minimal o'zgartirishlar kiritish talab etiladi. Keling, katolik rohiblarining barcha buyruqlari va jamoatlarini tekshirib ko'raylik va qo'shamiz :) Lekin eng mashhur 3 tasiga e'tibor qaratish yaxshidir, chunki ularning 100 dan ortiqlari bor: 1) Benediktin 2) Izezuit 3) Frantsisk Buning uchun avvalgidek pravoslav rohib, biz katolik rohibining ma'lum bir sinfini amalga oshirishimiz kerak:
public class CatholicMonk extends Monk {
    public CatholicMonk(String kind) {
        super(kind);
    }

    @Override
    public void description() {
        System.out.println("Я католический монах - " + kind);
    }
}
va monastir sinfi:
public class CatholicMonastery extends Monastery {

    @Override
    protected Monk createMonk(String type) {
        return new CatholicMonk(type);
    }
}
va kodni tekshiring:
public class Main {
    public static void main(String[] args) {
        Monastery monastery;

        monastery = new OrthodoxMonastery();
        monastery.createMonk("Мантийный монах").description();
        monastery.createMonk("Великосхимник").description();

        monastery = new CatholicMonastery();
        monastery.createMonk("Бенедиктинец").description();
        monastery.createMonk("Иезуит").description();
        monastery.createMonk("Францисканец").description();
    }
}
Я православный монах - Мантийный монах
Я православный монах - Великосхимник
Я католический монах - Бенедиктинец
Я католический монах - Иезуит
Я католический монах - Францисканец
Keling, ushbu naqsh bilan yakunlaylik. Ushbu turdagi rohiblarning barchasini E-num sinfiga oldindan qo'shish mumkin edi, ammo kodni soddalashtirish uchun biz buni qilmasdan qilamiz. Abstrakt fabrika naqshining vaqti keldi. Bizda rohiblar bor, endi biz ularga kiyim-kechak, tasbeh va hokazolarni yasashimiz mumkin edi. Keling, kiyim-kechakdan boshlaylik, ya'ni boshida ta'rifimizga qaytsak, kiyim bir-biriga bog'langan yoki bir-biriga bog'liq bo'lgan ob'ektlar oilasiga aylanadi . Keling, muammodan boshlaylik, rohiblarning har bir turi turli xil liboslarga ega. Agar biz buddistni ham qo'shsak, unda ular butunlay boshqacha bo'ladi :) Buning uchun biz zavod interfeysini yaratishimiz mumkin, uning amalga oshirilishi zarur kiyimlarni yaratadi. Shuning uchun A) Kiyim tikish zavodini yaratamiz
public interface MonkFactory {
    Clothing createClothing();
}
va uni amalga oshirish
public class OrthodoxMonkFactory implements MonkFactory {

        @Override
    public Clothing createClothing() {
        return new OrtodoxClothing();
    }
}
public class CatholicMonkFactory implements MonkFactory {

    @Override
    public Clothing createClothing() {
        return new CatholicClothing();
    }
}
public class AnglicanMonkFactory implements MonkFactory {

    @Override
    public Clothing createClothing() {
        return new AnglicanClothing();
    }
}
Keling, buddist rohiblarni unutmaylik :)
public class BuddhistMonkFactory implements MonkFactory {

    @Override
    public Clothing createClothing() {
        return new BuddhistClothing();
    }
}
B) Kiyim sinfini yarating (soddalashtirish uchun rohiblar kiyimining asosiy elementini olaylik, biz batafsil ma'lumot bermaymiz):
public abstract class Clothing {
    private String name;

    public Clothing(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }
}
va bolalar sinflari
public class OrtodoxClothing extends Clothing {
    public OrtodoxClothing() {
        super("Мантия");
    }
}
public class CatholicClothing extends Clothing {
    public CatholicClothing() {
        super("Ряса с капюшоном");
    }
}
public class AnglicanClothing extends Clothing {
    public AnglicanClothing() {
        super("Ряса");
    }
}
public class BuddhistClothing extends Clothing {
    public BuddhistClothing() {
        super("Кашая");
    }
}
C) Keyinchalik, biz rohiblarning sinflarini kiyimlari bo'lishi uchun o'zgartiramiz:
public abstract class Monk {
    String kind;
    Clothing clothing;

    public Monk(String kind) {
        this.kind = kind;
    }

    public void setClothing(Clothing clothing) {
        this.clothing = clothing;
    }

    public abstract void description();
}
public class OrthodoxMonk extends Monk {
    public OrthodoxMonk(String kind) {
        super(kind);
    }

    @Override
    public void description() {
        System.out.println("Я православный монах - " + kind);
        System.out.println("Моя одежда - " + clothing.getName());
    }
}
public class CatholicMonk extends Monk {
    public CatholicMonk(String kind) {
        super(kind);
    }

    @Override
    public void description() {
        System.out.println("Я католический монах - " + kind);
        System.out.println("Моя одежда - " + clothing.getName());
    }
}
public class AnglicanMonk extends Monk {
    public AnglicanMonk(String kind) {
        super(kind);
    }

    @Override
    public void description() {
        System.out.println("Я англиканский монах - " + kind);
        System.out.println("Моя одежда - " + clothing.getName());
    }
}
public class BuddhistMonk extends Monk {
    public BuddhistMonk(String kind) {
        super(kind);
    }

    @Override
    public void description() {
        System.out.println("Я буддийский монах - " + kind);
        System.out.println("Моя одежда - " + clothing.getName());
    }
}
D) Monastir sinfida bizning Fabrika usulimiz mavjud
public abstract class Monastery {

    public Monk create(MonkFactory monkFactory, String type) {
        Monk monk = createMonk(type);
        monk.setClothing(monkFactory.createClothing());
        return monk;
    }

    protected abstract Monk createMonk(String type);
}
bizning amaliyotlarimiz o'zgarmadi
public class OrthodoxMonastery extends Monastery {

    @Override
    protected Monk createMonk(String type) {
        return new OrthodoxMonk(type);
    }
}
public class CatholicMonastery extends Monastery {

    @Override
    protected Monk createMonk(String type) {
        return new CatholicMonk(type);
    }
}
public class AnglicanMonastery extends Monastery {

    @Override
    protected Monk createMonk(String type) {
        return new AnglicanMonk(type);
    }
}
public class BuddhistMonastery extends Monastery {

    @Override
    protected Monk createMonk(String type) {
        return new BuddhistMonk(type);
    }
}
D) Natijani tekshiring:
public class Main {
    public static void main(String[] args) {
        Monastery monastery;

        monastery = new OrthodoxMonastery();
        monastery.create(new OrthodoxMonkFactory(), "Мантийный монах").description();

        monastery = new CatholicMonastery();
        monastery.create(new CatholicMonkFactory(), "Иезуит").description();

        monastery = new AnglicanMonastery();
        monastery.create(new AnglicanMonkFactory(), "Бенедиктинец").description();

        monastery = new BuddhistMonastery();
        monastery.create(new BuddhistMonkFactory(), "Монах").description();
    }
}
Я православный монах - Мантийный монах
Моя одежда - Мантия
Я католический монах - Иезуит
Моя одежда - Ряса с капюшоном
Я англиканский монах - Бенедиктинец
Моя одежда - Ряса
Я буддийский монах - Монах
Моя одежда - Кашая
Kiyim-kechak ishlab chiqaradigan fabrika yaxshi ishlay boshladi. Endi siz fabrikaga muvaffaqiyatli namoz o'qish uchun rohiblar uchun uskunalar ishlab chiqarishni qo'shishingiz mumkin (tasbeh boncuklar va boshqalar). Ammo savol hali ham qolmoqda: ikkita naqshni birgalikda ishlatish mumkinmi? Albatta qila olasiz :) Keling, loyihamizning yakuniy versiyasini yaratishga harakat qilaylik va hind rohibini qo'shamiz: A) Hozirda fabrikalarda rohiblar yaratilishi "yulduzli fabrika" kabi eshitiladi :
public interface MonkFactory {
    Monk createMonk(String type);
    Clothing createClothing();
}
public class OrthodoxMonkFactory implements MonkFactory {

    @Override
    public Monk createMonk(String type){
        return new OrthodoxMonk(type);
    }

    @Override
    public Clothing createClothing() {
        return new OrtodoxClothing();
    }
}
public class CatholicMonkFactory implements MonkFactory {

    @Override
    public Monk createMonk(String type){
        return new CatholicMonk(type);
    }

    @Override
    public Clothing createClothing() {
        return new CatholicClothing();
    }
}
public class AnglicanMonkFactory implements MonkFactory {

    @Override
    public Monk createMonk(String type){
        return new AnglicanMonk(type);
    }

    @Override
    public Clothing createClothing() {
        return new AnglicanClothing();
    }
}
public class BuddhistMonkFactory implements MonkFactory {

    @Override
    public Monk createMonk(String type){
        return new BuddhistMonk(type);
    }

    @Override
    public Clothing createClothing() {
        return new BuddhistClothing();
    }
}
public class HinduMonkFactory implements MonkFactory {

    @Override
    public Monk createMonk(String type){
        return new HinduMonk(type);
    }

    @Override
    public Clothing createClothing() {
        return new HinduClothing();
    }
}
B) Monastir sinfi + monastir sinfining aniq ilovalari kerak emas, ular zavod tomonidan amalga oshiriladi (aksincha, biz ularni tark etib, zavodlarni olib tashlashimiz mumkin edi, lekin mohiyatiga ko'ra ular fabrikalar o'rnida bo'lar edi, faqat bu holda monastirni mavhum sinf emas, balki interfeys qilish kerak edi). Va dastur sinfini qo'shing:
public class Application {

    public Monk create(MonkFactory monkFactory, String type) {
        Monk monk = monkFactory.createMonk(type);
        monk.prepare(monkFactory);
        return monk;
    }
}
B) Endi rohiblar o'z ichiga oladi
public abstract class Monk {
    String kind;
    Clothing clothing;

    public Monk(String kind) {
        this.kind = kind;
    }

    public void setClothing(Clothing clothing) {
        this.clothing = clothing;
    }

    public abstract void description();

    public abstract void prepare(MonkFactory monkFactory);
}
Zavod yordamida amalga oshiriladigan amalga oshirishda zavod usulini o'z ichiga oladi:
public class OrthodoxMonk extends Monk {

    public OrthodoxMonk(String kind) {
        super(kind);
    }

    @Override
    public void description() {
        System.out.println("Я православный монах - " + kind);
        System.out.println("Моя одежда - " + clothing.getName());
    }

    @Override
    public void prepare(MonkFactory monkFactory) {
        setClothing(monkFactory.createClothing());
    }
}
public class CatholicMonk extends Monk {
    public CatholicMonk(String kind) {
        super(kind);
    }

    @Override
    public void description() {
        System.out.println("Я католический монах - " + kind);
        System.out.println("Моя одежда - " + clothing.getName());
    }

    @Override
    public void prepare(MonkFactory monkFactory) {
        setClothing(monkFactory.createClothing());
    }
}
public class AnglicanMonk extends Monk {
    public AnglicanMonk(String kind) {
        super(kind);
    }

    @Override
    public void description() {
        System.out.println("Я англиканский монах - " + kind);
        System.out.println("Моя одежда - " + clothing.getName());
    }

    @Override
    public void prepare(MonkFactory monkFactory) {
        setClothing(monkFactory.createClothing());
    }
}
public class BuddhistMonk extends Monk {
    public BuddhistMonk(String kind) {
        super(kind);
    }

    @Override
    public void description() {
        System.out.println("Я буддийский монах - " + kind);
        System.out.println("Моя одежда - " + clothing.getName());
    }

    @Override
    public void prepare(MonkFactory monkFactory) {
        setClothing(monkFactory.createClothing());
    }
}
public class HinduMonk extends Monk {
    public HinduMonk(String kind) {
        super(kind);
    }

    @Override
    public void description() {
        System.out.println("Я индуистский монах - " + kind);
        System.out.println("Моя одежда - " + clothing.getName());
    }

    @Override
    public void prepare(MonkFactory monkFactory) {
        setClothing(monkFactory.createClothing());
    }
}
D) Va keling, tekshiramiz:
public class Main {
    public static void main(String[] args) {
        Application application = new Application();

        application.create(new OrthodoxMonkFactory(), "Мантийный монах").description();
        application.create(new CatholicMonkFactory(), "Иезуит").description();
        application.create(new AnglicanMonkFactory(), "Бенедиктинец").description();
        application.create(new BuddhistMonkFactory(), "Монах").description();
        application.create(new HinduMonkFactory(), "Саньяси").description();
    }
}
Я православный монах - Мантийный монах
Моя одежда - Мантия
Я католический монах - Иезуит
Моя одежда - Ряса с капюшоном
Я англиканский монах - Бенедиктинец
Моя одежда - Ряса
Я буддийский монах - Монах
Моя одежда - Кашая
Я индуистский монах - Саньяси
Моя одежда - Почти ничего, тепло же :)
Xulosa qilib shuni ta'kidlash kerakki, Factory Method subklasslarda amalga oshirilmagan usul bilan mavhum sinfdan foydalangan va Abstract Factory interfeysdan foydalangan, bu erda amalga oshirish (bizning holatda, rohib yaratish) buni amalga oshirgan sinflarda sodir bo'lgan. interfeys.
Izohlar
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION