JavaRush /Java Blog /Random-TL /Mga Pattern ng Disenyo: FactoryMethod

Mga Pattern ng Disenyo: FactoryMethod

Nai-publish sa grupo
Kamusta! Ngayon ay patuloy nating pag-aaralan ang mga pattern ng disenyo at pag-uusapan ang pamamaraan ng pabrika (FactoryMethod). Mga Pattern ng Disenyo: FactoryMethod - 1Malalaman mo kung ano ito at kung anong mga gawain ang angkop sa template na ito. Titingnan natin ang pattern ng disenyo na ito sa pagsasanay at tuklasin ang istraktura nito. Upang maging malinaw sa iyo ang lahat ng nasa itaas, 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?

Sa lahat ng mga pattern ng disenyo ng pabrika, mayroong dalawang grupo ng mga kalahok - mga tagalikha (ang mga pabrika mismo) at mga produkto (ang mga bagay na nilikha ng mga pabrika). Isipin ang sitwasyon: mayroon kaming pabrika na gumagawa ng mga kotse sa ilalim ng tatak ng AutoRush. Alam niya kung paano lumikha ng mga modelo ng kotse na may iba't ibang uri ng katawan:
  • mga sedan
  • mga bagon ng istasyon
  • coupe
Naging maayos ang lahat para sa amin kaya isang magandang araw ay naisip namin ang OneAuto concern. Bilang mga matitinong tagapamahala, hindi namin gustong mawalan ng mga customer ng OneAuto, at ang aming gawain ay muling ayusin ang produksyon sa paraang makakagawa kami ng:
  • Mga sedan ng AutoRush
  • AutoRush station wagon
  • coupe AutoRush
  • Mga sedan ng OneAuto
  • OneAuto station wagons
  • coupe OneAuto
Tulad ng nakikita mo, sa halip na isang pangkat ng mga derivative na produkto, dalawa ang lumitaw, na naiiba sa ilang mga detalye. Ang pattern ng disenyo ng pamamaraan ng pabrika ay nilulutas ang problema sa paglikha ng iba't ibang grupo ng mga produkto, bawat isa ay may ilang partikularidad. Isasaalang-alang namin ang prinsipyo ng template na ito sa pagsasanay, unti-unting lumilipat mula sa simple hanggang sa kumplikado, gamit ang halimbawa ng aming coffee shop, na aming nilikha sa isa sa mga nakaraang lektura .

Kaunti tungkol sa factory template

Paalalahanan kita: nagtayo kami ng isang maliit na virtual coffee shop kasama ka. Dito, sa tulong ng isang simpleng pabrika, natutunan namin kung paano gumawa ng iba't ibang uri ng kape. Ngayon ay aayusin natin ang halimbawang ito. Alalahanin natin kung ano ang hitsura ng ating coffee shop na may simpleng pabrika. Nagkaroon kami ng coffee class:
public class Coffee {
    public void grindCoffee(){
        // перемалываем кофе
    }
    public void makeCoffee(){
        // делаем кофе
    }
    public void pourIntoCup(){
        // наливаем в чашку
    }
}
At ilan din sa kanyang mga tagapagmana - 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 {}
Para sa kaginhawaan ng pagtanggap ng mga order, ipinakilala namin ang mga paglilipat:
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 coffee shop mismo:
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("Вот ваш кофе! Спасибо, приходите еще!");
        return coffee;
    }
}

Modernisasyon ng isang simpleng pabrika

Maganda ang takbo ng coffee shop namin. So much so that we are thinking about expanding. Gusto naming magbukas ng ilang bagong punto. Bilang masigasig na mga lalaki, hindi namin gagawa ng mga monotonous na coffee shop. Gusto kong may kanya-kanyang twist ang bawat isa. Samakatuwid, upang magsimula sa, magbubukas kami ng dalawang punto: sa mga istilong Italyano at Amerikano. Ang mga pagbabago ay makakaapekto hindi lamang sa interior, kundi pati na rin sa mga inumin:
  • sa isang Italian coffee shop ay gagamit kami ng mga eksklusibong Italian coffee brand, na may espesyal na paggiling at pag-ihaw.
  • Ang bahagi ng Amerikano ay magiging mas malaki ng kaunti, at sa bawat order ay maghahatid kami ng mga tinunaw na marshmallow - marshmallow.
Ang tanging bagay na mananatiling hindi magbabago ay ang aming modelo ng negosyo, na napatunayang mabuti. Kung nagsasalita tayo sa wikang code, ito ang mangyayari. Mayroon kaming 4 na klase ng mga produkto:
public class Americano extends Coffee {}
public class Cappuccino extends Coffee {}
public class CaffeLatte extends Coffee {}
public class Espresso extends Coffee {}
At ito ay nagiging 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 panatilihing hindi nagbabago ang kasalukuyang modelo ng negosyo, gusto naming orderCoffee(CoffeeType type)sumailalim ang pamamaraan sa isang minimum na bilang ng mga pagbabago. Tingnan natin ito:
public Coffee orderCoffee(CoffeeType type) {
    Coffee coffee = coffeeFactory.createCoffee(type);
    coffee.grindCoffee();
    coffee.makeCoffee();
    coffee.pourIntoCup();

    System.out.println("Вот ваш кофе! Спасибо, приходите еще!");
    return coffee;
}
Anong mga pagpipilian ang mayroon tayo? Alam na natin kung paano magsulat ng isang pabrika, di ba? Ang pinakasimpleng bagay na agad na nasa isip ay ang magsulat ng dalawang magkatulad na pabrika, at pagkatapos ay ipasa ang kinakailangang pagpapatupad sa aming coffee shop sa constructor. Tapos hindi na magbabago ang klase ng coffee shop. Una, kailangan naming gumawa ng bagong factory class, magmana mula sa aming simpleng factory at i-override ang createCoffee (CoffeeType type). Sumulat tayo ng mga pabrika para sa paglikha ng kape sa mga istilong Italyano at Amerikano:
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 maaari na nating ipasa ang kinakailangang pagpapatupad 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, ang cappuccino sa mga istilong Italyano at Amerikano:
public class Main {
    public static void main(String[] args) {
        /*
            Закажем капучино в итальянском стиле:
            1. Создадим фабрику для приготовления итальянского кофе
            2. Создадим новую кофейню, передав ей в конструкторе фабрику итальянского кофе
            3. Закажем наш кофе
         */
        SimpleItalianCoffeeFactory italianCoffeeFactory = new SimpleItalianCoffeeFactory();
        CoffeeShop italianCoffeeShop = new CoffeeShop(italianCoffeeFactory);
        italianCoffeeShop.orderCoffee(CoffeeType.CAPPUCCINO);


         /*
            Закажем капучино в американском стиле
            1. Создадим фабрику для приготовления американского кофе
            2. Создадим новую кофейню, передав ей в конструкторе фабрику американского кофе
            3. Закажем наш кофе
         */
        SimpleAmericanCoffeeFactory americanCoffeeFactory = new SimpleAmericanCoffeeFactory();
        CoffeeShop americanCoffeeShop = new CoffeeShop(americanCoffeeFactory);
        americanCoffeeShop.orderCoffee(CoffeeType.CAPPUCCINO);
    }
}
Gumawa kami ng dalawang magkaibang coffee shop, na inililipat ang bawat isa sa kinakailangang pabrika. Sa isang banda, nakamit na natin ang ating layunin, ngunit sa kabilang banda... May nangungulit sa hindi mapigilang kaluluwa ng negosyante... Alamin natin kung ano ang mali. Una, ang kasaganaan ng mga pabrika. Posible bang lumikha ng iyong sariling pabrika sa bawat oras para sa isang bagong punto at, bilang karagdagan, siguraduhin na kapag lumilikha ng isang coffee shop, ang kinakailangang pabrika ay inilipat sa tagabuo? Pangalawa, ito ay isang simpleng pabrika pa rin. Medyo modernized lang. Nag-aaral pa kami ng bagong pattern dito. Pangatlo, hindi ba posible na gawin ito nang iba? Magiging cool na kung maaari naming i-localize ang lahat ng mga tanong tungkol sa paggawa ng kape sa loob ng silid-aralan CoffeeShop, pag-uugnay sa mga proseso ng paggawa ng kape at pagseserbisyo sa order, ngunit sa parehong oras ay nagpapanatili ng sapat na kakayahang umangkop upang gumawa ng kape sa iba't ibang mga estilo. Ang sagot ay oo, kaya mo. 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 problema nang mahusay hangga't maaari, kami ay:
  1. Ibalik natin ang pamamaraan createCoffee(CoffeeType type)sa klase CoffeeShop.
  2. Gawin nating abstract ang paraang ito.
  3. Ang klase mismo CoffeeShopay magiging abstract.
  4. Ang klase CoffeeShopay magkakaroon ng mga tagapagmana.
Oo kaibigan. Ang isang Italian coffee shop ay hindi hihigit sa isang tagapagmana ng klase CoffeeShop, na nagpapatupad ng isang paraan createCoffee(CoffeeType type)alinsunod sa mga pinakamahusay na tradisyon ng mga Italian barista. Kaya, sa pagkakasunud-sunod. Hakbang 1. Gawin nating Coffeeabstract ang klase. Mayroon na kaming dalawang pamilya ng magkaibang produkto. Ang mga inuming kape ng Italyano at Amerikano ay nagbabahagi pa rin ng isang karaniwang ninuno: ang Coffee. Tamang gawin itong abstract:
public abstract class Coffee {
    public void makeCoffee(){
        // делаем кофе
    }
    public void pourIntoCup(){
        // наливаем в чашку
    }
}
Hakbang 2. Gawin itong CoffeeShopabstract, na may abstract na pamamaraancreateCoffee(CoffeeType type)
public abstract class CoffeeShop {

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

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

        System.out.println("Вот ваш кофе! Спасибо, приходите еще!");
        return coffee;
    }

    protected abstract Coffee createCoffee(CoffeeType type);
}
Hakbang 3. Gumawa ng Italian coffee shop, isang descendant class ng abstract coffee shop. Sa loob nito ipinatupad namin ang pamamaraan createCoffee(CoffeeType type)na isinasaalang-alang ang mga detalye ng Italyano.
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. Gawin din natin ang parehong para sa isang 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 natin kung ano ang magiging hitsura ng pag-order ng American at Italian style 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 sa aming coffee shop.

Paano gumagana ang pamamaraan ng pabrika

Ngayon tingnan natin nang mas malapit kung ano ang nakuha natin. Ang diagram sa ibaba ay nagpapakita ng mga resultang klase. Ang mga berdeng bloke ay mga klase ng tagalikha, ang mga asul na bloke ay mga klase ng produkto. Mga Pattern ng Disenyo: FactoryMethod - 2Anong mga konklusyon ang maaaring makuha?
  1. Ang lahat ng mga produkto ay mga pagpapatupad ng abstract class Coffee.
  2. Ang lahat ng mga tagalikha ay mga pagpapatupad ng abstract na klase CoffeeShop.
  3. Napansin namin 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 creator. Nakikita natin ang mga inapo ng Italyano at mga inapo ng Amerikano
  4. Ang superclass CoffeeShopay walang impormasyon tungkol sa kung aling partikular na pagpapatupad ng produkto ( Coffee) ang gagawin.
  5. Ang isang superclass CoffeeShopay nagtatalaga ng paglikha ng isang partikular na produkto sa mga inapo nito.
  6. Ang bawat descendant class CoffeeShopay nagpapatupad ng factory method createCoffee()alinsunod sa mga specifics nito. Sa madaling salita, sa loob ng mga pagpapatupad ng mga klase ng creator, isang desisyon ang ginawa upang maghanda ng isang partikular na produkto batay sa mga detalye ng klase ng creator.
Ngayon ay handa ka nang tukuyin ang pattern ng factory method . Tinutukoy ng pattern ng factory method ang 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. Sa pangkalahatan, ang pag-alala sa kahulugan ay hindi kasinghalaga ng pag-unawa kung paano gumagana ang mga bagay.

Istraktura ng pamamaraan ng pabrika

Mga Pattern ng Disenyo: FactoryMethod - 3Ang diagram sa itaas ay nagpapakita ng pangkalahatang istraktura ng pattern ng factory method. Ano pa ang mahalaga dito?
  1. Naglalaman ang klase ng Creator ng mga pagpapatupad ng lahat ng paraan na nakikipag-ugnayan sa mga produkto, maliban sa factory na paraan.
  2. Ang isang abstract na pamamaraan factoryMethod()ay dapat ipatupad ng lahat ng mga inapo ng klase Creator.
  3. Ang klase ConcreteCreatoray nagpapatupad ng isang paraan factoryMethod()na direktang gumagawa ng isang 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 - maging 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 sa antas ng mga abstraction kaysa sa mga konkretong pagpapatupad.

Takdang aralin

Kaya, ngayon marami kaming ginawa at pinag-aralan ang pattern ng disenyo ng pamamaraan ng pabrika. Oras na para pagsama-samahin ang materyal na iyong sakop! Gawain 1. Magtrabaho sa pagbubukas ng isa pang coffee shop. Maaari itong gawin sa istilong Ingles o Espanyol. O kahit na sa estilo ng isang sasakyang pangalangaang. Lagyan natin ng food coloring ang kape para lumiwanag ito, at sa pangkalahatan, magiging space lang ang kape! Gawain 2. Sa huling panayam, mayroon kang gawain na lumikha ng isang virtual na sushi bar o isang virtual na pizzeria. Ang iyong gawain ay hindi tumayo. Ngayon natutunan mo kung paano mo magagamit ang pattern ng factory method para makamit ang tagumpay. Panahon na upang samantalahin ang kaalamang ito at palawakin ang iyong sariling negosyo ;)
Mga komento
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION