سلام رفیق! امروز ما به مطالعه الگوهای طراحی با شما ادامه خواهیم داد. در این سخنرانی در مورد کارخانه صحبت خواهیم کرد. ما با شما بحث خواهیم کرد که چه مشکلی با استفاده از این الگو حل می شود و به مثالی از نحوه کمک یک کارخانه به افتتاح یک کافی شاپ نگاه می کنیم. و همچنین 5 مرحله ساده برای ایجاد یک کارخانه به شما ارائه خواهم کرد. برای اینکه با همه یکسان باشید و به راحتی اصل مطلب را درک کنید، باید با موضوعات زیر آشنا باشید:
- وراثت در جاوا
- محدود کردن و گسترش انواع مرجع در جاوا
- تعامل بین کلاس ها و اشیاء مختلف
کارخانه چیست؟
الگوی طراحی کارخانه به شما امکان می دهد ایجاد اشیا را کنترل کنید. فرآیند ایجاد یک شی جدید به این سادگی نیست، اما خیلی هم پیچیده نیست. همه ما می دانیم که برای ایجاد یک شی جدید باید ازnew
. و ممکن است به نظر برسد که در اینجا چیزی برای مدیریت وجود ندارد، اما اینطور نیست. زمانی که برنامه ما دارای یک کلاس خاص است که دارای نسل های زیادی است، ممکن است مشکلات ایجاد شود و بنا به شرایطی لازم است نمونه ای از یک کلاس خاص ایجاد شود. Factory یک الگوی طراحی است که به حل مشکل ایجاد اشیاء مختلف بسته به برخی شرایط کمک می کند. چکیده، اینطور نیست؟ هنگامی که به مثال زیر نگاه می کنیم، جزئیات و وضوح بیشتری ظاهر می شود.
ما انواع مختلفی از قهوه را تولید می کنیم
فرض کنید می خواهیم یک کافی شاپ را خودکار کنیم. باید طرز تهیه انواع قهوه را یاد بگیریم. برای انجام این کار، در برنامه ما یک کلاس قهوه و مشتقات آن ایجاد می کنیم: آمریکایینو، کاپوچینو، اسپرسو، لاته - انواع قهوه ای که آماده خواهیم کرد. بیایید با کلاس قهوه عمومی شروع کنیم:public class Coffee {
public void grindCoffee(){
// перемалываем кофе
}
public void makeCoffee(){
// делаем кофе
}
public void pourIntoCup(){
// наливаем в чашку
}
}
بعد، بیایید وارثان آن را ایجاد کنیم:
public class Americano extends Coffee {}
public class Cappuccino extends Coffee {}
public class CaffeLatte extends Coffee {}
public class Espresso extends Coffee {}
مشتریان ما نوعی قهوه سفارش می دهند و این اطلاعات باید به برنامه منتقل شود. این را می توان به روش های مختلفی انجام داد، به عنوان مثال با استفاده از String
. اما بهترین گزینه برای این اهداف است enum
. بیایید enum
انواع قهوه ای را که برای آنها سفارش می پذیریم ایجاد و در آن تعریف کنیم:
public enum CoffeeType {
ESPRESSO,
AMERICANO,
CAFFE_LATTE,
CAPPUCCINO
}
عالی، حالا بیایید کد کافی شاپ خود را بنویسیم:
public class CoffeeShop {
public Coffee orderCoffee(CoffeeType type) {
Coffee coffee = null;
switch (type) {
case AMERICANO:
coffee = new Americano();
break;
case ESPRESSO:
coffee = new Espresso();
break;
case CAPPUCCINO:
coffee = new Cappucсino();
break;
case CAFFE_LATTE:
coffee = new CaffeLatte();
break;
}
coffee.grindCoffee();
coffee.makeCoffee();
coffee.pourIntoCup();
System.out.println("Вот ваш кофе! Спасибо, приходите еще!");
return coffee;
}
}
روش را orderCoffee
می توان به دو بخش تقسیم کرد:
- ایجاد یک نمونه قهوه خاص در یک بلوک
switch-case
. این جایی است که کاری که کارخانه انجام می دهد ایجاد یک نوع خاص بسته به شرایط است. - خود آماده سازی آسیاب، پختن و ریختن در فنجان است.
- خود الگوریتم آماده سازی (آسیاب کردن، پختن و ریختن در یک فنجان) بدون تغییر باقی می ماند (حداقل امیدواریم اینطور باشد).
- اما محدوده قهوه ممکن است تغییر کند. شاید شروع کنیم به درست کردن موکا.. موکا.. موکاچی... خدا رحمتش کنه یه نوع قهوه جدید.
switch-case
. همچنین ممکن است در کافی شاپ ما روش orderCoffee
تنها جایی نباشد که در آن انواع مختلف قهوه را ایجاد می کنیم. بنابراین، باید در چندین مکان تغییرات ایجاد شود. احتمالاً قبلاً متوجه شده اید که من در چه چیزی هستم. ما باید اصلاح کنیم. بلوک مسئول تولید قهوه را به دو دلیل به یک کلاس جداگانه منتقل کنید:
- ما قادر خواهیم بود از منطق ایجاد قهوه در مکان های دیگر استفاده مجدد کنیم.
- اگر محدوده تغییر کند، ما مجبور نخواهیم بود کد را در همه جاهایی که از ایجاد قهوه استفاده می شود، ویرایش کنیم. تغییر کد فقط در یک مکان کافی خواهد بود.
ما در حال اره کردن اولین کارخانه خود هستیم
برای انجام این کار، بیایید یک کلاس جدید ایجاد کنیم که تنها مسئول ایجاد نمونه های لازم از کلاس های قهوه است: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 Cappucino();
break;
case CAFFE_LATTE:
coffee = new CaffeLatte();
break;
}
return coffee;
}
}
تبریک می گویم! ما به تازگی الگوی طراحی کارخانه را در ساده ترین شکل آن پیاده سازی کرده ایم. اگرچه اگر روش createCoffee
ثابت ساخته می شد، همه چیز می توانست ساده تر باشد. اما در این صورت ما دو احتمال را از دست خواهیم داد:
- ارث بری
SimpleCoffeeFactory
و نادیده گرفتنcreateCoffee
. - پیاده سازی کارخانه ای مورد نیاز را در کلاس های ما اجرا کنید.
معرفی یک کارخانه به یک کافی شاپ
بیایید کلاس کافی شاپ خود را با استفاده از یک کارخانه بازنویسی کنیم: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;
}
}
عالی. اکنون بیایید سعی کنیم ساختار الگوی طراحی کارخانه را به صورت شماتیک و مختصر توصیف کنیم.
5 مرحله برای افتتاح کارخانه خود
مرحله 1. در برنامه خود یک کلاس با چندین فرزند دارید، مانند تصویر زیر: مرحله 2. شما یک کلاس ایجاد می کنیدenum
که در آن یک متغیر enum برای هر کلاس decendant تعریف می کنید:
enum CatType {
LION,
TIGER,
BARSIK
}
مرحله 3. شما کارخانه خود را می سازید. شما با آن تماس بگیرید MyClassFactory
، کد زیر است:
class CatFactory {}
مرحله 4. شما در کارخانه خود متدی ایجاد می کنید createMyClass
که متغیر - enum
MyClassType
. کد زیر:
class CatFactory {
public Cat createCat(CatType type) {
}
}
مرحله 5. یک بلوک در بدنه متد می نویسید switch-case
که در آن تمام مقادیر enum را تکرار می کنید و یک نمونه از کلاس مربوط به enum
مقدار ایجاد می کنید:
class CatFactory {
public Cat createCat(CatType type) {
Cat cat = null;
switch (type) {
case LION:
cat = new Barsik();
break;
case TIGER:
cat = new Tiger();
break;
case BARSIK:
cat = new Lion();
break;
}
return cat;
}
}
مثل یک رئیس.
GO TO FULL VERSION