CodeGym /Java Blog /Random /Mga pattern ng disenyo: Paraan ng pabrika
John Squirrels
Antas
San Francisco

Mga pattern ng disenyo: Paraan ng pabrika

Nai-publish sa grupo
Hi! Ngayon ay patuloy nating pag-aaralan ang mga pattern ng disenyo at tatalakayin natin ang pattern ng factory method. Mga pattern ng disenyo: Paraan ng pabrika - 1 Malalaman mo kung ano ito at kung anong mga gawain ang angkop para sa pattern na ito. Isasaalang-alang namin ang pattern ng disenyo na ito sa pagsasanay at pag-aralan ang istraktura nito. Upang matiyak na malinaw ang lahat, kailangan mong maunawaan ang mga sumusunod na paksa:
  1. Mana sa Java.
  2. Mga abstract na pamamaraan at klase sa Java

Anong problema ang nalulutas ng factory method?

Ang lahat ng mga pattern ng disenyo ng pabrika ay may dalawang uri ng mga kalahok: mga tagalikha (ang mga pabrika mismo) at mga produkto (ang mga bagay na nilikha ng mga pabrika). Isipin ang sumusunod na sitwasyon: mayroon kaming pabrika na gumagawa ng mga sasakyang may tatak ng CodeGym. Alam nito kung paano lumikha ng mga modelo ng mga kotse na may iba't ibang uri ng katawan:
  • mga sedan
  • mga bagon ng istasyon
  • mga coupe
Umunlad nang husto ang aming negosyo kaya isang magandang araw ay nakakuha kami ng isa pang carmaker — OneAuto. Bilang mga matitinong may-ari ng negosyo, hindi namin gustong mawalan ng sinumang customer ng OneAuto, kaya nahaharap kami sa gawain ng muling pagsasaayos ng produksyon upang makagawa kami ng:
  • Mga sedan ng CodeGym
  • Mga bagon ng istasyon ng CodeGym
  • Mga coupe ng CodeGym
  • Mga sedan ng OneAuto
  • OneAuto station wagons
  • OneAuto coupes
Tulad ng nakikita mo, sa halip na isang pangkat ng mga produkto, mayroon na kaming dalawa, at naiiba ang mga ito sa ilang partikular na detalye. Ang pattern ng disenyo ng factory method ay para sa kapag kailangan nating gumawa ng iba't ibang grupo ng mga produkto, na bawat isa ay may ilang partikular na katangian. Isasaalang-alang namin ang gabay na prinsipyo ng pattern na ito sa pagsasanay, unti-unting lumilipat mula sa simple tungo sa kumplikado, gamit ang halimbawa ng aming coffee shop, na ginawa namin sa isa sa mga nakaraang aralin .

Medyo tungkol sa pattern ng pabrika

Hayaan mong ipaalala ko sa iyo na dati tayong nagtayo ng isang maliit na virtual coffee shop. Sa tulong ng isang simpleng pabrika, natutunan namin kung paano gumawa ng iba't ibang uri ng kape. Ngayon ay gagawin nating muli ang halimbawang ito. Alalahanin natin ang hitsura ng aming coffee shop, kasama ang simpleng pabrika nito. Nagkaroon kami ng coffee class:

public class Coffee {
    public void grindCoffee(){
        // Grind the coffee
    }
    public void makeCoffee(){
        // Brew the coffee
    }
    public void pourIntoCup(){
        // Pour into a cup
    }
}
At ilang klase ng bata na tumutugma sa mga partikular na uri ng kape na maaaring gawin ng aming pabrika:

public class Americano extends Coffee {}
public class Cappuccino extends Coffee {}
public class CaffeLatte extends Coffee {}
public class Espresso extends Coffee {}
Gumawa kami ng enum para gawing madali ang paglalagay ng mga order:

public enum CoffeeType {
    ESPRESSO,
    AMERICANO,
    CAFFE_LATTE,
    CAPPUCCINO
}
Ang mismong pabrika ng kape ay ganito ang hitsura:

public class SimpleCoffeeFactory {
    public Coffee createCoffee(CoffeeType type) {
        Coffee coffee = null;

        switch (type) {
            case AMERICANO:
                coffee = new Americano();
                break;
            case ESPRESSO:
                coffee = new Espresso();
                break;
            case CAPPUCCINO:
                coffee = new Cappuccino();
                break;
            case CAFFE_LATTE:
                coffee = new CaffeLatte();
                break;
        }
        
        return coffee;
    }
}
At sa wakas, ang mismong coffee shop ay ganito ang hitsura:

public class CoffeeShop {

    private final SimpleCoffeeFactory coffeeFactory;

    public CoffeeShop(SimpleCoffeeFactory coffeeFactory) {
        this.coffeeFactory = coffeeFactory;
    }

    public Coffee orderCoffee(CoffeeType type) {
        Coffee coffee = coffeeFactory.createCoffee(type);
        coffee.grindCoffee();
        coffee.makeCoffee();
        coffee.pourIntoCup();

        System.out.println("Here's your coffee! Thanks! Come again!");
        return coffee;
    }
}

Pag-modernize ng isang simpleng pabrika

Ang aming coffee shop ay tumatakbo nang maayos. So much so that we are considering expanding. Gusto naming magbukas ng ilang bagong lokasyon. Kami ay matapang at masigasig, kaya't hindi kami magpapakabagot sa mga tindahan ng kape. Nais naming magkaroon ng espesyal na twist ang bawat tindahan. Alinsunod dito, upang magsimula, magbubukas kami ng dalawang lokasyon: isang Italyano at isang Amerikano. Ang mga pagbabagong ito ay makakaapekto hindi lamang sa panloob na disenyo, kundi pati na rin sa mga inuming inaalok:
  • sa Italian coffee shop, gagamit kami ng mga eksklusibong Italian coffee brand, na may espesyal na paggiling at pag-ihaw.
  • ang lokasyon sa Amerika ay magkakaroon ng mas malaking bahagi, at maghahain kami ng mga marshmallow sa bawat order.
Ang tanging bagay na nananatiling hindi nagbabago ay ang aming modelo ng negosyo, na napatunayang napakahusay. Sa mga tuntunin ng code, ito ang nangyayari. Mayroon kaming 4 na klase na naaayon sa aming mga produkto:

public class Americano extends Coffee {}
public class Cappuccino extends Coffee {}
public class CaffeLatte extends Coffee {}
public class Espresso extends Coffee {}
Ngunit ngayon magkakaroon tayo ng 8:

public class ItalianStyleAmericano extends Coffee {}
public class ItalianStyleCappucino extends Coffee {}
public class ItalianStyleCaffeLatte extends Coffee {}
public class ItalianStyleEspresso extends Coffee {}

public class AmericanStyleAmericano extends Coffee {}
public class AmericanStyleCappucino extends Coffee {}
public class AmericanStyleCaffeLatte extends Coffee {}
public class AmericanStyleEspresso extends Coffee {}
Dahil gusto naming panatilihin ang kasalukuyang modelo ng negosyo, gusto naming orderCoffee(CoffeeType type)sumailalim ang pamamaraan sa kaunting pagbabago hangga't maaari. Tingnan ito:

public Coffee orderCoffee(CoffeeType type) {
    Coffee coffee = coffeeFactory.createCoffee(type);
    coffee.grindCoffee();
    coffee.makeCoffee();
    coffee.pourIntoCup();

    System.out.println("Here's your coffee! Thanks! Come again!");
    return coffee;
}
Anong mga pagpipilian ang mayroon tayo? Well, alam na natin kung paano magsulat ng isang pabrika, di ba? Ang pinakasimpleng bagay na agad na naiisip ay ang sumulat ng dalawang magkatulad na pabrika, at pagkatapos ay ipasa ang nais na pagpapatupad sa tagabuo ng aming coffee shop. Sa paggawa nito, hindi magbabago ang klase ng coffee shop. Una, kailangan naming gumawa ng bagong factory class, gawin itong magmana ng aming simpleng factory, at pagkatapos ay i-override ang createCoffee(CoffeeType type)paraan. Sumulat tayo ng mga pabrika para sa paggawa ng Italian-style na kape at American-style na kape:

public class SimpleItalianCoffeeFactory extends SimpleCoffeeFactory {

    @Override
    public Coffee createCoffee(CoffeeType type) {
        Coffee coffee = null;
        switch (type) {
            case AMERICANO:
                coffee = new ItalianStyleAmericano();
                break;
            case ESPRESSO:
                coffee = new ItalianStyleEspresso();
                break;
            case CAPPUCCINO:
                coffee = new ItalianStyleCappuccino();
                break;
            case CAFFE_LATTE:
                coffee = new ItalianStyleCaffeLatte();
                break;
        }
        return coffee;
    }
}

public class SimpleAmericanCoffeeFactory extends SimpleCoffeeFactory{

    @Override
    public Coffee createCoffee (CoffeeType type) {
        Coffee coffee = null;

        switch (type) {
            case AMERICANO:
                coffee = new AmericanStyleAmericano();
                break;
            case ESPRESSO:
                coffee = new AmericanStyleEspresso();
                break;
            case CAPPUCCINO:
                coffee = new AmericanStyleCappuccino();
                break;
            case CAFFE_LATTE:
                coffee = new AmericanStyleCaffeLatte();
                break;
        }

        return coffee;
    }

}
Ngayon ay maipapasa na natin ang gustong implementasyon ng pabrika sa CoffeeShop. Tingnan natin kung ano ang magiging hitsura ng code para sa pag-order ng kape mula sa iba't ibang coffee shop. Halimbawa, Italian-style at American-style cappuccino:

public class Main {
    public static void main(String[] args) {
        /*
            Order an Italian-style cappuccino:
            1. Create a factory for making Italian coffee
            2. Create a new coffee shop, passing the Italian coffee factory to it through the constructor
            3. Order our coffee
         */
        SimpleItalianCoffeeFactory italianCoffeeFactory = new SimpleItalianCoffeeFactory();
        CoffeeShop italianCoffeeShop = new CoffeeShop(italianCoffeeFactory);
        italianCoffeeShop.orderCoffee(CoffeeType.CAPPUCCINO);
        
        
         /*
            Order an American-style cappuccino
            1. Create a factory for making American coffee
            2. Create a new coffee shop, passing the American coffee factory to it through the constructor
            3. Order our coffee
         */
        SimpleAmericanCoffeeFactory americanCoffeeFactory = new SimpleAmericanCoffeeFactory();
        CoffeeShop americanCoffeeShop = new CoffeeShop(americanCoffeeFactory);
        americanCoffeeShop.orderCoffee(CoffeeType.CAPPUCCINO);
    }
}
Gumawa kami ng dalawang magkaibang coffee shop, na ipinapasa ang nais na pabrika sa bawat isa. Sa isang banda, naisakatuparan na natin ang ating layunin, ngunit sa kabilang banda... Kahit papaano ay hindi ito angkop sa mga negosyante... Alamin natin kung ano ang mali. Una, ang kasaganaan ng mga pabrika. Ano? Ngayon para sa bawat bagong lokasyon, dapat tayong lumikha ng sarili nitong pabrika at, bilang karagdagan doon, siguraduhin na ang nauugnay na pabrika ay ipapasa sa tagabuo kapag gumagawa ng coffee shop? Pangalawa, ito ay isang simpleng pabrika pa rin. Medyo modernized lang. Ngunit narito kami upang matuto ng bagong pattern. Pangatlo, hindi ba posible ang ibang diskarte? Magiging mahusay kung mailalagay natin ang lahat ng mga isyu na may kaugnayan sa paghahanda ng kape saCoffeeShopklase sa pamamagitan ng pag-uugnay sa mga proseso ng paglikha ng kape at pagseserbisyo ng mga order, habang sabay na pinapanatili ang sapat na kakayahang umangkop upang makagawa ng iba't ibang istilo ng kape. Ang sagot ay oo, kaya natin. Ito ay tinatawag na pattern ng disenyo ng pamamaraan ng pabrika.

Mula sa isang simpleng pabrika hanggang sa isang paraan ng pabrika

Upang malutas ang gawain nang mahusay hangga't maaari:
  1. Ibinabalik namin ang createCoffee(CoffeeType type)pamamaraan sa CoffeeShopklase.
  2. Gagawin nating abstract ang pamamaraang ito.
  3. Ang CoffeeShopklase mismo ay magiging abstract.
  4. Ang CoffeeShopklase ay magkakaroon ng mga klase ng bata.
Oo kaibigan. Ang Italian coffee shop ay hindi hihigit sa isang inapo ng CoffeeShopklase, na nagpapatupad ng createCoffee(CoffeeType type)pamamaraan alinsunod sa mga pinakamahusay na tradisyon ng mga Italian barista. Ngayon, isang hakbang sa isang pagkakataon. Hakbang 1. Gawing Coffeeabstract ang klase. Mayroon kaming dalawang buong pamilya ng magkaibang produkto. Gayunpaman, ang mga kape ng Italyano at Amerikano ay may isang karaniwang ninuno - ang Coffeeklase. Tamang gawin itong abstract:

public abstract class Coffee {
    public void makeCoffee(){
        // Brew the coffee
    }
    public void pourIntoCup(){
        // Pour into a cup
    }
}
Hakbang 2. Gumawa CoffeeShopng abstract, na may abstract createCoffee(CoffeeType type)na pamamaraan

public abstract class CoffeeShop {

    public Coffee orderCoffee(CoffeeType type) {
        Coffee coffee = createCoffee(type);

        coffee.makeCoffee();
        coffee.pourIntoCup();

        System.out.println("Here's your coffee! Thanks! Come again!");
        return coffee;
    }

    protected abstract Coffee createCoffee(CoffeeType type);
}
Hakbang 3. Lumikha ng isang Italian coffee shop, na isang inapo ng abstract coffee shop. Ipinapatupad namin ang createCoffee(CoffeeType type)pamamaraan sa loob nito, na isinasaalang-alang ang mga detalye ng mga Italian recipies.

public class ItalianCoffeeShop extends CoffeeShop {

    @Override
    public Coffee createCoffee (CoffeeType type) {
        Coffee coffee = null;
        switch (type) {
            case AMERICANO:
                coffee = new ItalianStyleAmericano();
                break;
            case ESPRESSO:
                coffee = new ItalianStyleEspresso();
                break;
            case CAPPUCCINO:
                coffee = new ItalianStyleCappuccino();
                break;
            case CAFFE_LATTE:
                coffee = new ItalianStyleCaffeLatte();
                break;
        }
        return coffee;
    }
}
Hakbang 4. Gayon din ang ginagawa namin para sa American-style coffee shop

public class AmericanCoffeeShop extends CoffeeShop {
    @Override
    public Coffee createCoffee(CoffeeType type) {
        Coffee coffee = null;

        switch (type) {
            case AMERICANO:
                coffee = new AmericanStyleAmericano();
                break;
            case ESPRESSO:
                coffee = new AmericanStyleEspresso();
                break;
            case CAPPUCCINO:
                coffee = new AmericanStyleCappuccino();
                break;
            case CAFFE_LATTE:
                coffee = new AmericanStyleCaffeLatte();
                break;
        }

        return coffee;
    }
}
Hakbang 5. Tingnan kung ano ang magiging hitsura ng American at Italian latte:

public class Main {
    public static void main(String[] args) {
        CoffeeShop italianCoffeeShop = new ItalianCoffeeShop();
        italianCoffeeShop.orderCoffee(CoffeeType.CAFFE_LATTE);

        CoffeeShop americanCoffeeShop = new AmericanCoffeeShop();
        americanCoffeeShop.orderCoffee(CoffeeType.CAFFE_LATTE);
    }
}
Binabati kita. Ipinatupad lang namin ang pattern ng disenyo ng factory method gamit ang aming coffee shop bilang isang halimbawa.

Ang prinsipyo sa likod ng mga pamamaraan ng pabrika

Ngayon isaalang-alang natin nang mas detalyado kung ano ang nakuha natin. Ang diagram sa ibaba ay nagpapakita ng mga resultang klase. Ang mga berdeng bloke ay mga klase ng tagalikha, at ang mga asul na bloke ay mga klase ng produkto. Mga pattern ng disenyo: Paraan ng pabrika - 2Anong mga konklusyon ang maaari nating gawin?
  1. Ang lahat ng mga produkto ay mga pagpapatupad ng abstract Coffeena klase.
  2. Ang lahat ng creator ay mga pagpapatupad ng abstract CoffeeShopclass.
  3. Nakikita natin ang dalawang magkatulad na hierarchy ng klase:
    • Hierarchy ng mga produkto. Nakikita natin ang mga inapo ng Italyano at mga inapo ng Amerikano
    • Hierarchy ng mga tagalikha. Nakikita natin ang mga inapo ng Italyano at mga inapo ng Amerikano
  4. Ang CoffeeShopsuperclass ay walang impormasyon tungkol sa kung aling partikular na produkto ( Coffee) ang gagawin.
  5. Ang CoffeeShopsuperclass ay nagtatalaga ng paglikha ng isang partikular na produkto sa mga inapo nito.
  6. Ang bawat inapo ng CoffeeShopklase ay nagpapatupad ng createCoffee()paraan ng pabrika alinsunod sa sarili nitong mga partikular na tampok. Sa madaling salita, ang mga pagpapatupad ng mga klase ng producer ay naghahanda ng mga partikular na produkto batay sa mga detalye ng klase ng producer.
Handa ka na ngayon para sa kahulugan ng pattern ng factory method . Tinutukoy ng pattern ng factory method ang isang interface para sa paglikha ng isang object, ngunit pinapayagan ang mga subclass na piliin ang klase ng nilikhang object. Kaya, ang isang factory method ay nagdedelegate ng paglikha ng isang instance sa mga subclass. Sa pangkalahatan, ang pag-alala sa kahulugan ay hindi kasinghalaga ng pag-unawa kung paano gumagana ang lahat.

Istraktura ng isang pamamaraan ng pabrika

Mga pattern ng disenyo: Paraan ng pabrika - 3Ang diagram sa itaas ay nagpapakita ng pangkalahatang istraktura ng pattern ng factory method. Ano pa ang mahalaga dito?
  1. Ipinapatupad ng klase ng Creator ang lahat ng paraan na nakikipag-ugnayan sa mga produkto, maliban sa factory na paraan.
  2. Ang abstract factoryMethod()na pamamaraan ay dapat ipatupad ng lahat ng mga inapo ng Creatorklase.
  3. ConcreteCreatorIpinapatupad ng klase ang factoryMethod()pamamaraan, na direktang lumilikha ng produkto.
  4. Ang klase na ito ay responsable para sa paglikha ng mga partikular na produkto. Ito ang tanging klase na may impormasyon tungkol sa paggawa ng mga produktong ito.
  5. Ang lahat ng mga produkto ay dapat magpatupad ng isang karaniwang interface, ibig sabihin, sila ay dapat na mga inapo ng isang karaniwang klase ng produkto. Ito ay kinakailangan upang ang mga klase na gumagamit ng mga produkto ay maaaring gumana sa kanila bilang mga abstraction, sa halip na mga partikular na pagpapatupad.

Takdang aralin

Ngayon, marami na kaming nagawa at pinag-aralan ang pattern ng disenyo ng pamamaraan ng pabrika. Panahon na upang palakasin ang materyal! Pagsasanay 1. Gawin ang gawain sa pagbubukas ng panibagong coffee shop. Maaaring ito ay isang English-style o Spanish-style na coffee shop. O kahit na spaceship-style. Magdagdag ng food coloring sa kape para maging glow ito, at ang iyong kape ay mawawala sa mundong ito! Pagsasanay 2. Sa huling aralin , nagkaroon ka ng ehersisyo kung saan gumawa ka ng virtual sushi bar o virtual pizzeria. Ngayon ang iyong ehersisyo ay hindi tumayo. Ngayon natutunan mo kung paano gamitin ang pattern ng factory method para sa iyong kalamangan. Oras na para gamitin ang kaalamang ito at palawakin ang sarili mong negosyo ;)
Mga komento
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION