Kamusta! Ngayon ay patuloy nating pag-aaralan ang mga pattern ng disenyo at pag-uusapan ang pamamaraan ng pabrika (FactoryMethod). Malalaman 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:
- Mana sa Java.
- 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
- Mga sedan ng AutoRush
- AutoRush station wagon
- coupe AutoRush
- Mga sedan ng OneAuto
- OneAuto station wagons
- coupe OneAuto
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.
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:- Ibalik natin ang pamamaraan
createCoffee(CoffeeType type)
sa klaseCoffeeShop
. - Gawin nating abstract ang paraang ito.
- Ang klase mismo
CoffeeShop
ay magiging abstract. - Ang klase
CoffeeShop
ay magkakaroon ng mga tagapagmana.
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 Coffee
abstract 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 CoffeeShop
abstract, 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. Anong mga konklusyon ang maaaring makuha?- Ang lahat ng mga produkto ay mga pagpapatupad ng abstract class
Coffee
. - Ang lahat ng mga tagalikha ay mga pagpapatupad ng abstract na klase
CoffeeShop
. - 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
- Ang superclass
CoffeeShop
ay walang impormasyon tungkol sa kung aling partikular na pagpapatupad ng produkto (Coffee
) ang gagawin. - Ang isang superclass
CoffeeShop
ay nagtatalaga ng paglikha ng isang partikular na produkto sa mga inapo nito. - Ang bawat descendant class
CoffeeShop
ay nagpapatupad ng factory methodcreateCoffee()
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.
Istraktura ng pamamaraan ng pabrika
Ang diagram sa itaas ay nagpapakita ng pangkalahatang istraktura ng pattern ng factory method. Ano pa ang mahalaga dito?- Naglalaman ang klase ng Creator ng mga pagpapatupad ng lahat ng paraan na nakikipag-ugnayan sa mga produkto, maliban sa factory na paraan.
- Ang isang abstract na pamamaraan
factoryMethod()
ay dapat ipatupad ng lahat ng mga inapo ng klaseCreator
. - Ang klase
ConcreteCreator
ay nagpapatupad ng isang paraanfactoryMethod()
na direktang gumagawa ng isang produkto. - 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.
- 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.
GO TO FULL VERSION