JavaRush /Java Blog /Random-TL /Paraan ng Pabrika at Mga Abstract na Pattern ng Pabrika

Paraan ng Pabrika at Mga Abstract na Pattern ng Pabrika

Nai-publish sa grupo
Sa aklat na “Una ang Ulo. Ang Mga Pattern ng Disenyo" ay tumutukoy sa mga pattern na ito bilang mga sumusunod: Ang pattern ng Factory Method ay tumutukoy sa interface para sa paglikha ng isang object, ngunit pinapayagan ang mga subclass na piliin ang klase ng instance na gagawin. Kaya, ang pamamaraan ng Pabrika ay nagtatalaga ng operasyon ng instantiation sa mga subclass. Ang pattern ng Abstract Factory ay nagbibigay ng interface para sa paglikha ng mga pamilya ng magkakaugnay o magkakaugnay na mga bagay nang hindi tinukoy ang kanilang mga kongkretong klase. Subukan nating maunawaan ito nang mas detalyado. Sabihin nating nagpasya kang magsulat ng isang laro tungkol sa mga taong nagpasiyang maging... (kailangan mo ng isang bagay na orihinal at hindi karaniwan dito) mga monghe. Maaari tayong magsimula sa mga sumusunod. 1) Gumawa ng klase ng Monk at mga child class (gumawa muna tayo ng isa):
public abstract class Monk {

    public abstract void description();
}
public class OrthodoxMonk extends Monk {
    @Override
    public void description() {
        System.out.println("Я православный монах");
    }
}
2) At siyempre, lumikha ng isang klase ng Monastery, kung saan maaari mong ipatupad ang "mga panata ng monasteryo":
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;
    }
}
Well, tingnan natin ang resulta:
public class Main {
    public static void main(String[] args) {
        Monastery monastery = new Monastery();
        monastery.createMonk("ORTODOX");
        monastery.getMonk().description();
    }
}
Я православный монах
Ngayon kung kailangan mong lumikha... isang Katolikong monghe, kakailanganin mong A) Gumawa ng bagong klase para sa isang Katolikong monghe:
public class CatholicMonk extends Monk {
    @Override
    public void description() {
        System.out.println("Я католический монах");
    }
}
B) Gumawa ng mga pagbabago sa klase ng monasteryo:
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;
    }
}
at kaya sa tuwing may mga bagong uri ng monghe, kailangan mong lumikha ng bagong klase at i-edit ang dati. Ano ang maaaring gawin sa kasong ito upang kahit papaano ay "i-encapsulate" ang aming klase ng monasteryo mula sa mga pagbabago. Maaari mong subukang gamitin ang pattern ng Factory Method. Ano ang magiging hitsura nito A) Iwanan na natin ang klase ng monghe, maliban sa marahil magdagdag ng isang Anglican na monghe (hindi lamang mga Katoliko at mga Kristiyanong Ortodokso ang may monasticism):
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) Baguhin natin ang klase ng monasteryo tulad ng sumusunod (gawin natin ito at ang pamamaraan nito na abstract). Dito ginagamit lang namin ang paraan ng Pabrika:
public abstract class Monastery {
    protected abstract Monk createMonk();
}
at lumikha ng mga klase ng bata na may pagpapatupad ng pamamaraan:
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) Suriin natin ang code
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();
    }
}
Я православный монах
Я католический монах
Я англиканский монах
Yung. tulad ng nakikita natin ngayon, kapag nagdaragdag ng mga bagong uri ng mga monghe, hindi na kailangang baguhin ang mga kasalukuyang klase, ngunit kung kinakailangan, magdagdag ng mga bago (ang klase ng isang partikular na monasteryo at monghe). Marahil ay napansin na ng isang tao na ang pamamaraan ng paglalarawan, na mula pa sa simula sa klase ng Monk, ay Pabrika din :) Ang kahulugan ng pamamaraan ng pabrika ay nagsabi na ang aming pattern ay tumutukoy sa interface para sa paglikha ng isang bagay, ngunit hindi kami lumikha ng anumang mga interface, bagama't maaari tayong lumikha ng klase ng Monastery bilang isang interface at ipatupad ito sa mga partikular na pagpapatupad. Ito ay tumutukoy sa salitang "interface" sa mas malawak na kahulugan. Sinabi rin ng kahulugan na pinapayagan nito ang mga subclass na piliin ang klase ng halimbawang nilikha nila . Dito lang natin nakikita na ang mga subclass (mga klase ng bata) ay nagpapatupad ng pamamaraang ito (iyon ay, ang mga kapangyarihang ito upang lumikha ng mga bagay na monghe ay itinalaga sa kanila). Ngayon palawakin natin ng kaunti ang ating programa, ipakilala ang posibilidad na mayroong iba't ibang mga monghe sa isang denominasyon o iba pa. Halimbawa, sa Orthodoxy, batay sa posisyon ng Orthodox Church sa mga monasteryo at monastics (pinagtibay sa Konseho ng mga Obispo ng Russian Orthodox Church noong Nobyembre 29 - Disyembre 2, 2017), maaari nating tapusin na mayroong 2 uri ng mga monghe. : - Mas maliit na schema (mantle). - Schema (mahusay na schema). Mayroon ding "mga yugto ng paghahanda", ngunit ang mga tao ay hindi itinuturing na mga monghe (Trudnik, Novice at Ryasophor o Monk), dahil hindi sila kumukuha ng mga panata ng monastic. Samakatuwid, hindi namin sila isinasaalang-alang. Ano ang makukuha natin sa kasong ito: A) Monastery Class (upang gawing simple, tumuon tayo sa Orthodox monasticism sa ngayon) gamit ang Factory method :
public abstract class Monastery {
    protected abstract Monk createMonk(String type);
}
at isang tiyak na monasteryo
public class OrthodoxMonastery extends Monastery {

    @Override
    protected Monk createMonk(String type) {
        return new OrthodoxMonk(type);
    }
}
B) Ayusin natin ang klase ng monghe:
public abstract class Monk {
    String kind;

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

    public abstract void description();
}
at klase ng bata:
public class OrthodoxMonk extends Monk {
    public OrthodoxMonk(String kind) {
        super(kind);
    }

    @Override
    public void description() {
        System.out.println("Я православный монах - " + kind);
    }
}
C) Suriin natin ang aming code:
public class Main {
    public static void main(String[] args) {
        Monastery monastery = new OrthodoxMonastery();
        monastery.createMonk("Мантийный монах").description();
        monastery.createMonk("Великосхимник").description();
    }
}
Я православный монах - Мантийный монах
Я православный монах — Великосхимник
Kaya, sa pamamagitan ng paggamit ng pattern ng Factory Method, nakamit namin na hindi namin kailangang baguhin ang mga naunang nakasulat na klase, ngunit din kapag pinalawak ang mga imahe (mga uri) ng mga monghe, kinakailangan ang isang minimum na pagbabago sa code. Suriin at idagdag natin ang lahat ng mga order at kongregasyon ng mga mongheng Katoliko :) Ngunit mas mahusay na tumuon sa 3 pinakasikat, dahil mayroong higit sa 100 sa kanila: 1) Benedictine 2) Jesuit 3) Franciscan Upang gawin ito, tulad ng dati na may ang Orthodox monghe, kailangan nating ipatupad ang isang partikular na klase ng Katolikong monghe:
public class CatholicMonk extends Monk {
    public CatholicMonk(String kind) {
        super(kind);
    }

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

    @Override
    protected Monk createMonk(String type) {
        return new CatholicMonk(type);
    }
}
at suriin ang code:
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();
    }
}
Я православный монах - Мантийный монах
Я православный монах - Великосхимник
Я католический монах - Бенедиктинец
Я католический монах - Иезуит
Я католический монах - Францисканец
Tapusin natin ang pattern na ito. Ang lahat ng mga uri ng monghe ay maaari ding idagdag sa E-num class nang maaga, ngunit para gawing simple ang code ay gagawin namin nang wala ito. Oras na para sa pattern ng Abstract Factory. Mayroon kaming mga monghe, maaari na naming gawin silang mga damit, rosaryo, atbp. Magsimula tayo sa pananamit, ibig sabihin, kung babalik tayo sa ating kahulugan sa simula, ang pananamit ay magiging isang pamilya ng magkakaugnay o magkakaugnay na mga bagay . Magsimula tayo sa problema na ang bawat uri ng monghe ay may iba't ibang damit. Kung idaragdag din natin ang Buddhist, kung gayon sila ay magiging ganap na naiiba :) Upang gawin ito, maaari tayong lumikha ng isang interface ng pabrika, ang mga pagpapatupad nito ay lilikha ng mga kinakailangang damit. Samakatuwid A) Lumilikha kami ng isang pabrika para sa paggawa ng mga damit
public interface MonkFactory {
    Clothing createClothing();
}
at pagpapatupad nito
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();
    }
}
Well, huwag nating kalimutan ang tungkol sa mga Buddhist monghe :)
public class BuddhistMonkFactory implements MonkFactory {

    @Override
    public Clothing createClothing() {
        return new BuddhistClothing();
    }
}
B) Gumawa ng klase ng pananamit (upang pasimplehin, kunin natin ang pangunahing elemento ng pananamit ng mga monghe, hindi na tayo magdedetalye):
public abstract class Clothing {
    private String name;

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

    public String getName() {
        return name;
    }
}
at mga klase ng bata
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) Susunod, pinapalitan namin ang mga klase ng mga monghe upang magkaroon sila ng mga damit:
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) Ang klase ng monasteryo ay naglalaman ng aming Factory method
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);
}
hindi nagbago ang ating mga pagpapatupad
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) Suriin ang resulta:
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();
    }
}
Я православный монах - Мантийный монах
Моя одежда - Мантия
Я католический монах - Иезуит
Моя одежда - Ряса с капюшоном
Я англиканский монах - Бенедиктинец
Моя одежда - Ряса
Я буддийский монах - Монах
Моя одежда - Кашая
Nagsimula nang gumana nang maayos ang pabrika na lumilikha ng mga damit. Ngayon ay maaari mong idagdag sa pabrika ang paggawa ng mga kagamitan para sa mga monghe para sa matagumpay na panalangin (rosaryo kuwintas, atbp.). Ngunit nananatili pa rin ang tanong, posible bang gumamit ng 2 pattern nang magkasama? Syempre kaya mo :) Subukan nating gawin ang panghuling bersyon ng ating proyekto at magdagdag ng Hindu monghe: A) Ang mga pabrika ngayon ay gumagawa ng mga monghe na parang "star factory" :
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) Ang klase ng monasteryo + kongkretong pagpapatupad ng klase ng Monastery ay hindi kailangan, ang mga ito ay ipinatupad ng pabrika (sa kabaligtaran, maaari nating iwanan ang mga ito at alisin ang mga pabrika, ngunit sa esensya ay magiging sila lamang sa halip na mga pabrika, lamang sa sa kasong ito, ang Monastery ay kailangang gawing interface, at hindi abstract class). At idagdag ang klase ng aplikasyon:
public class Application {

    public Monk create(MonkFactory monkFactory, String type) {
        Monk monk = monkFactory.createMonk(type);
        monk.prepare(monkFactory);
        return monk;
    }
}
B) Ang mga monghe ay naglalaman na ngayon
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);
}
naglalaman ng factory method sa mga pagpapatupad, na ipinapatupad gamit ang factory:
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) At suriin natin:
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();
    }
}
Я православный монах - Мантийный монах
Моя одежда - Мантия
Я католический монах - Иезуит
Моя одежда - Ряса с капюшоном
Я англиканский монах - Бенедиктинец
Моя одежда - Ряса
Я буддийский монах - Монах
Моя одежда - Кашая
Я индуистский монах - Саньяси
Моя одежда - Почти ничего, тепло же :)
Sa konklusyon, maaari mong tandaan na ang pamamaraan ng Pabrika ay gumamit ng isang abstract na klase na may hindi ipinatupad na pamamaraan, na ipinatupad sa mga subclass, at ang Abstract Factory ay gumamit ng isang interface, kung saan ang pagpapatupad (sa aming kaso, ang paglikha ng isang monghe) ay naganap sa mga klase na ipinatupad. interface na ito.
Mga komento
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION