سلام! امروز ما به مطالعه الگوهای طراحی و صحبت در مورد کارخانه انتزاعی ادامه خواهیم داد . آنچه در طول سخنرانی انجام خواهیم داد:
- بیایید بحث کنیم که یک کارخانه انتزاعی چیست و این الگو چه مشکلی را حل می کند.
- ما چارچوب یک برنامه کاربردی بین پلتفرمی را برای سفارش قهوه با رابط کاربری ایجاد خواهیم کرد.
- بیایید دستورالعمل استفاده از این الگو را با نمودار و کد مطالعه کنیم.
- به عنوان یک جایزه، یک تخم مرغ عید پاک در سخنرانی پنهان شده است که به لطف آن یاد خواهید گرفت که نام سیستم عامل را با استفاده از جاوا تعیین کنید و بسته به نتیجه، یک یا عمل دیگری را انجام دهید.
- وراثت در جاوا؛
- کلاس ها و متدهای انتزاعی در جاوا
الگوی انتزاعی کارخانه چه مشکلاتی را حل می کند؟
کارخانه انتزاعی، مانند تمام الگوهای کارخانه، به ما کمک می کند تا خلق اشیاء جدید را به درستی سازماندهی کنیم. با کمک آن، ما "آزادسازی" خانواده های مختلف اشیاء به هم پیوسته را مدیریت می کنیم. خانواده های مختلف اشیاء مرتبط با یکدیگر ... چیست؟ نگران نباشید: در عمل همه چیز ساده تر از چیزی است که به نظر می رسد. بیایید با خانواده ای از اشیاء مرتبط شروع کنیم؟ فرض کنید ما در حال توسعه یک استراتژی با شما هستیم و چندین واحد رزمی در آن وجود دارد:- پیاده نظام؛
- سواره نظام؛
- کمانداران
ما به اتوماسیون کافی شاپ ادامه می دهیم
در آخرین سخنرانی الگوی روش کارخانه را بررسی کردیم که با کمک آن توانستیم تجارت قهوه را گسترش دهیم و چندین نقطه جدید فروش قهوه را افتتاح کنیم. امروز ما به کار خود برای مدرن کردن تجارت خود ادامه خواهیم داد. با استفاده از الگوی کارخانه ای انتزاعی، پایه و اساس یک برنامه دسکتاپ جدید را برای سفارش آنلاین قهوه خواهیم گذاشت. وقتی برنامه ای را برای دسکتاپ می نویسیم، همیشه باید به فکر کراس پلتفرم باشیم. برنامه ما باید هم روی macOS و هم روی ویندوز کار کند (اسپویلر: لینوکس به عنوان تکلیف برای شما باقی خواهد ماند). برنامه ما چگونه خواهد بود؟ بسیار ساده: این فرمی است که از یک فیلد متنی، یک فیلد انتخابی و یک دکمه تشکیل شده است. اگر تجربه استفاده از سیستم عامل های مختلف را دارید، قطعا متوجه شده اید که در ویندوز دکمه ها متفاوت از مک رندر می شوند. مثل هر چیز دیگری... خب، بیایید شروع کنیم. همانطور که احتمالاً قبلاً متوجه شده اید، در نقش خانواده محصول، عناصر رابط گرافیکی خواهیم داشت:- دکمه ها؛
- فیلدهای متنی؛
- زمینه های انتخاب
onClick
، onValueChanged
یا را تعریف کنیم onInputChanged
. آن ها روش هایی که به ما امکان می دهند رویدادهای مختلف را مدیریت کنیم (کلیک کردن روی یک دکمه، وارد کردن متن، انتخاب یک مقدار در کادر انتخاب). همه اینها به عمد حذف شده است تا مثال اضافه نشود و برای مطالعه الگوی کارخانه بصری تر شود. بیایید رابط های انتزاعی را برای محصولات خود تعریف کنیم:
public interface Button {}
public interface Select {}
public interface TextField {}
برای هر سیستم عامل، باید عناصر رابط را به سبک آن سیستم عامل ایجاد کنیم. ما برای ویندوز و MacOS می نویسیم. بیایید پیاده سازی هایی برای ویندوز ایجاد کنیم:
public class WindowsButton implements Button {
}
public class WindowsSelect implements Select {
}
public class WindowsTextField implements TextField {
}
حالا برای MacOS هم همینطور:
public class MacButton implements Button {
}
public class MacSelect implements Select {
}
public class MacTextField implements TextField {
}
عالی. اکنون میتوانیم کارخانه انتزاعی خود را راهاندازی کنیم، که تمام انواع محصولات انتزاعی موجود را ایجاد میکند:
public interface GUIFactory {
Button createButton();
TextField createTextField();
Select createSelect();
}
کامل. همانطور که می بینید، تا کنون هیچ چیز پیچیده ای وجود ندارد. سپس همه چیز به همین سادگی است. بر اساس قیاس با محصولات، ما پیاده سازی های مختلفی از کارخانه خود را برای هر سیستم عامل ایجاد می کنیم. بیایید با ویندوز شروع کنیم:
public class WindowsGUIFactory implements GUIFactory {
public WindowsGUIFactory() {
System.out.println("Creating gui factory for Windows OS");
}
public Button createButton() {
System.out.println("Creating Button for Windows OS");
return new WindowsButton();
}
public TextField createTextField() {
System.out.println("Creating TextField for Windows OS");
return new WindowsTextField();
}
public Select createSelect() {
System.out.println("Creating Select for Windows OS");
return new WindowsSelect();
}
}
خروجی کنسول در داخل متدها و سازنده ها اضافه شده است تا نحوه عملکرد آن را بیشتر نشان دهد. اکنون برای macOS:
public class MacGUIFactory implements GUIFactory {
public MacGUIFactory() {
System.out.println("Creating gui factory for macOS");
}
@Override
public Button createButton() {
System.out.println("Creating Button for macOS");
return new MacButton();
}
@Override
public TextField createTextField() {
System.out.println("Creating TextField for macOS");
return new MacTextField();
}
@Override
public Select createSelect() {
System.out.println("Creating Select for macOS");
return new MacSelect();
}
}
نکته: هر متد با توجه به امضای خود، یک نوع انتزاعی را برمی گرداند. اما در داخل روش ما یک پیاده سازی ملموس از محصول ایجاد می کنیم. این تنها جایی است که ما ایجاد نمونه های خاص را کنترل می کنیم. حالا نوبت نوشتن کلاس فرم است. این یک کلاس جاوا است که فیلدهای آن عناصر رابط هستند:
public class OrderCoffeeForm {
private final TextField customerNameTextField;
private final Select coffeTypeSelect;
private final Button orderButton;
public OrderCoffeeForm(GUIFactory factory) {
System.out.println("Creating order coffee form");
customerNameTextField = factory.createTextField();
coffeTypeSelect = factory.createSelect();
orderButton = factory.createButton();
}
}
یک کارخانه انتزاعی به سازنده فرم منتقل می شود، که عناصر رابط را ایجاد می کند. پیاده سازی کارخانه مورد نیاز را به سازنده منتقل می کنیم تا بتوانیم عناصر رابط را برای یک سیستم عامل خاص ایجاد کنیم.
public class Application {
private OrderCoffeeForm orderCoffeeForm;
public void drawOrderCoffeeForm() {
// Определим Name операционной системы, получив meaning системной проперти через System.getProperty
String osName = System.getProperty("os.name").toLowerCase();
GUIFactory guiFactory;
if (osName.startsWith("win")) { // Для windows
guiFactory = new WindowsGUIFactory();
} else if (osName.startsWith("mac")) { // Для mac
guiFactory = new MacGUIFactory();
} else {
System.out.println("Unknown OS, can't draw form :( ");
return;
}
orderCoffeeForm = new OrderCoffeeForm(guiFactory);
}
public static void main(String[] args) {
Application application = new Application();
application.drawOrderCoffeeForm();
}
}
اگر برنامه را روی ویندوز اجرا کنیم، خروجی زیر را دریافت می کنیم:
Creating gui factory for Windows OS
Creating order coffee form
Creating TextField for Windows OS
Creating Select for Windows OS
Creating Button for Windows OS
در مک خروجی به صورت زیر خواهد بود:
Creating gui factory for macOS
Creating order coffee form
Creating TextField for macOS
Creating Select for macOS
Creating Button for macOS
در لینوکس:
Unknown OS, can't draw form :(
خوب، من و شما به این نتیجه می رسیم. ما یک چارچوب برای یک برنامه رابط کاربری گرافیکی نوشتیم که دقیقاً آن عناصر رابط را ایجاد می کند که برای یک سیستم عامل خاص مناسب است. بیایید به طور خلاصه آنچه را که ایجاد کردیم تکرار کنیم:
- خانواده محصول: فیلد ورودی، فیلد انتخاب و دکمه.
- پیاده سازی های مختلف این خانواده از محصولات، برای ویندوز و macOS.
- یک کارخانه انتزاعی، که در آن رابطی را برای ایجاد محصولات خود تعریف کردیم.
- دو پیاده سازی از کارخانه ما که هر کدام وظیفه ایجاد یک خانواده خاص از محصولات را بر عهده دارند.
- یک فرم، یک کلاس جاوا که فیلدهای آن عناصر واسط انتزاعی هستند که در سازنده با مقادیر مورد نیاز با استفاده از یک کارخانه انتزاعی مقداردهی اولیه می شوند.
- کلاس برنامه در داخل آن فرمی ایجاد می کنیم که با آن پیاده سازی مورد نیاز کارخانه خود را به سازنده منتقل می کنیم.
Abstract Factory: دستورالعمل استفاده
Abstract Factory یک الگوی طراحی برای مدیریت ایجاد خانواده های مختلف محصول بدون گره خوردن به کلاس های محصول خاص است. هنگام استفاده از این الگو باید:- خود خانواده های محصول را تعریف کنید. بیایید فرض کنیم دو تا از آنها داریم:
SpecificProductA1
،SpecificProductB1
SpecificProductA2
،SpecificProductB2
- برای هر محصول در خانواده، یک کلاس انتزاعی (رابط) تعریف کنید. در مورد ما این است:
ProductA
ProductB
- در هر خانواده محصول، هر محصول باید رابط تعریف شده در مرحله 2 را پیاده سازی کند.
- یک کارخانه انتزاعی ایجاد کنید، با متدهای ایجاد برای هر محصول که در مرحله 2 تعریف شده است. در مورد ما، این روش ها عبارتند از:
ProductA createProductA();
ProductB createProductB();
- پیاده سازی های کارخانه انتزاعی را ایجاد کنید تا هر پیاده سازی ایجاد محصولات یک خانواده را کنترل کند. برای این کار در داخل هر پیاده سازی کارخانه انتزاعی باید تمامی روش های ایجاد را پیاده سازی کرد تا پیاده سازی های انضمامی محصولات در داخل آنها ایجاد و برگردانده شود.
// Определим общие интерфейсы продуктов
public interface ProductA {}
public interface ProductB {}
// Создадим различные реализации (семейства) наших продуктов
public class SpecificProductA1 implements ProductA {}
public class SpecificProductB1 implements ProductB {}
public class SpecificProductA2 implements ProductA {}
public class SpecificProductB2 implements ProductB {}
// Создадим абстрактную фабрику
public interface AbstractFactory {
ProductA createProductA();
ProductB createProductB();
}
// Создадим реализацию абстрактной фабрики для создания продуктов семейства 1
public class SpecificFactory1 implements AbstractFactory {
@Override
public ProductA createProductA() {
return new SpecificProductA1();
}
@Override
public ProductB createProductB() {
return new SpecificProductB1();
}
}
// Создадим реализацию абстрактной фабрики для создания продуктов семейства 1
public class SpecificFactory2 implements AbstractFactory {
@Override
public ProductA createProductA() {
return new SpecificProductA2();
}
@Override
public ProductB createProductB() {
return new SpecificProductB2();
}
}
مشق شب
برای تثبیت مواد می توانید 2 کار انجام دهید:- برنامه سفارش قهوه را بهبود دهید تا در لینوکس کار کند.
- کارخانه انتزاعی خود را برای تولید واحدهای هر استراتژی ایجاد کنید. این می تواند یک استراتژی تاریخی با ارتش های واقعی باشد یا یک فانتزی با اورک ها، کوتوله ها و الف ها. نکته اصلی این است که برای شما جالب است. خلاق باشید، پینها را به کنسول پست کنید و از یادگیری الگوها لذت ببرید!
GO TO FULL VERSION