JavaRush /جاوا بلاگ /Random-UR /ڈیزائن پیٹرن: AbstractFactory

ڈیزائن پیٹرن: AbstractFactory

گروپ میں شائع ہوا۔
ہیلو! آج ہم ڈیزائن کے نمونوں کا مطالعہ جاری رکھیں گے اور تجریدی فیکٹری کے بارے میں بات کریں گے ۔ ڈیزائن پیٹرن: AbstractFactory - 1لیکچر کے دوران ہم کیا کریں گے:
  • آئیے اس بات پر بحث کرتے ہیں کہ ایک تجریدی کارخانہ کیا ہے اور یہ نمونہ کس مسئلے کو حل کرتا ہے۔
  • ہم صارف انٹرفیس کے ساتھ کافی آرڈر کرنے کے لیے کراس پلیٹ فارم ایپلی کیشن کا فریم ورک بنائیں گے۔
  • آئیے ڈایاگرام اور کوڈ کے ساتھ اس پیٹرن کو استعمال کرنے کے لیے ہدایات کا مطالعہ کریں۔
  • بونس کے طور پر، لیکچر میں ایک ایسٹر انڈے چھپا ہوا ہے، جس کی بدولت آپ جاوا کا استعمال کرتے ہوئے آپریٹنگ سسٹم کے نام کا تعین کرنا سیکھیں گے اور نتیجہ پر منحصر ہے، ایک یا دوسری کارروائی کریں۔
اس پیٹرن کو مکمل طور پر سمجھنے کے لیے، آپ کو درج ذیل عنوانات کی اچھی تفہیم کی ضرورت ہے:
  • جاوا میں وراثت؛
  • جاوا میں تجریدی کلاسز اور طریقے۔

تجریدی فیکٹری پیٹرن کن مسائل کو حل کرتا ہے؟

تجریدی فیکٹری، تمام فیکٹری پیٹرن کی طرح، ہمیں نئی ​​اشیاء کی تخلیق کو درست طریقے سے ترتیب دینے میں مدد کرتی ہے۔ اس کی مدد سے، ہم باہم جڑی ہوئی اشیاء کے مختلف خاندانوں کی "رہائی" کا انتظام کرتے ہیں۔ باہم منسلک اشیاء کے مختلف خاندان... یہ کیا ہے؟ پریشان نہ ہوں: عملی طور پر سب کچھ اس سے کہیں زیادہ آسان ہے جتنا کہ لگتا ہے۔ آئیے اس کے ساتھ شروع کریں کہ متعلقہ اشیاء کا خاندان کیا ہو سکتا ہے؟ فرض کریں کہ آپ اور میں ایک حکمت عملی تیار کر رہے ہیں، اور اس میں کئی جنگی یونٹ ہیں:
  • پیادہ فوج
  • رسالہ؛
  • تیر انداز
اس قسم کے جنگی یونٹس ایک دوسرے سے متعلق ہیں، کیونکہ وہ ایک ہی فوج میں خدمات انجام دیتے ہیں۔ ہم کہہ سکتے ہیں کہ اوپر درج زمرے آپس میں جڑی ہوئی اشیاء کا خاندان ہیں۔ یہ حل ہو گیا ہے۔ لیکن تجریدی فیکٹری پیٹرن کو ایک دوسرے سے منسلک اشیاء کے مختلف خاندانوں کی تخلیق کو منظم کرنے کے لئے استعمال کیا جاتا ہے. یہاں بھی کچھ بھی پیچیدہ نہیں ہے۔ آئیے حکمت عملی کے ساتھ مثال کو جاری رکھیں۔ ان کے عام طور پر کئی مختلف مخالف فریق ہوتے ہیں۔ مختلف فریقوں کی جنگی اکائیاں ظاہری شکل میں نمایاں طور پر مختلف ہو سکتی ہیں۔ رومن فوج کے پیدل سپاہی، گھڑ سوار اور تیر انداز وائکنگز کے پیدل سپاہیوں، گھڑ سواروں اور تیر اندازوں کی طرح نہیں ہیں۔ حکمت عملی کے فریم ورک کے اندر، مختلف فوجوں کے سپاہی ایک دوسرے سے جڑی ہوئی اشیاء کے مختلف خاندان ہیں۔ یہ مضحکہ خیز ہو گا، اگر کسی پروگرامر کی غلطی سے، نپولین کے زمانے کا ایک فرانسیسی یونیفارم میں ملبوس سپاہی، ایک مسکٹ کے ساتھ، رومن پیادہ فوج کے درمیان گھوم رہا ہو۔ یہ اس طرح کے مسئلے کو حل کرنے کے لیے ہے کہ تجریدی فیکٹری ڈیزائن پیٹرن کی ضرورت ہے۔ نہیں، وقتی سفر کی شرمندگی کے مسائل نہیں، بلکہ باہم مربوط اشیاء کے مختلف گروہوں کی تخلیق۔ ایک تجریدی فیکٹری تمام موجودہ مصنوعات (خاندانی اشیاء) بنانے کے لیے ایک انٹرفیس فراہم کرتی ہے۔ ایک تجریدی فیکٹری میں عام طور پر متعدد نفاذ ہوتے ہیں۔ ان میں سے ہر ایک مختلف حالتوں میں سے ایک کی مصنوعات بنانے کے لیے ذمہ دار ہے۔ حکمت عملی کے ایک حصے کے طور پر، ہمارے پاس ایک تجریدی کارخانہ ہوگا جو تجریدی پیادہ، تیر اندازوں اور گھڑ سواروں کے ساتھ ساتھ اس فیکٹری کے نفاذ کو بھی تیار کرے گا۔ ایک فیکٹری جو رومن لیجنیئرز تخلیق کرتی ہے اور مثال کے طور پر، کارتھیجینین جنگجو تخلیق کرنے والی فیکٹری۔ خلاصہ اس پیٹرن کا سب سے اہم اصول ہے۔ فیکٹری کلائنٹس اس کے ساتھ اور مصنوعات کے ساتھ صرف خلاصہ انٹرفیس کے ذریعے کام کرتے ہیں۔ اس لیے، ہمیں یہ نہیں سوچنا چاہیے کہ ہم اس وقت کس قسم کے جنگجو پیدا کر رہے ہیں، بلکہ اس ذمہ داری کو تجریدی کارخانے کے کچھ مخصوص نفاذ پر منتقل کریں۔

ہم کافی شاپ کو خودکار بنانا جاری رکھتے ہیں۔

آخری لیکچر میں ، ہم نے فیکٹری میتھڈ پیٹرن کا مطالعہ کیا، جس کی مدد سے ہم کافی کے کاروبار کو بڑھانے اور کافی کے کئی نئے سیلز پوائنٹس کھولنے میں کامیاب ہوئے۔ آج ہم اپنے کاروبار کو جدید بنانے کے لیے اپنا کام جاری رکھیں گے۔ تجریدی فیکٹری پیٹرن کا استعمال کرتے ہوئے، ہم آن لائن کافی آرڈر کرنے کے لیے ایک نئی ڈیسک ٹاپ ایپلیکیشن کی بنیاد رکھیں گے۔ جب ہم ڈیسک ٹاپ کے لیے درخواست لکھتے ہیں، تو ہمیں ہمیشہ کراس پلیٹ فارم کے بارے میں سوچنا چاہیے۔ ہماری ایپلی کیشن کو میک او ایس اور ونڈوز دونوں پر کام کرنا چاہیے (سپائلر: لینکس آپ کے لیے ہوم ورک کے طور پر چھوڑ دیا جائے گا)۔ ہماری درخواست کیسی نظر آئے گی؟ بالکل آسان: یہ ایک ایسا فارم ہو گا جس میں ٹیکسٹ فیلڈ، ایک سلیکٹ فیلڈ اور ایک بٹن ہوتا ہے۔ اگر آپ کو مختلف آپریٹنگ سسٹم استعمال کرنے کا تجربہ ہے، تو آپ نے یقینی طور پر محسوس کیا ہوگا کہ ونڈوز پر بٹن میک کے مقابلے مختلف طریقے سے پیش کیے جاتے ہیں۔ ہر چیز کی طرح... تو آئیے شروع کرتے ہیں۔ پروڈکٹ فیملیز کے کردار میں، جیسا کہ آپ شاید پہلے ہی سمجھ چکے ہوں گے، ہمارے پاس گرافیکل انٹرفیس عناصر ہوں گے:
  • بٹن
  • ٹیکسٹ فیلڈز؛
  • انتخاب کے لیے فیلڈز۔
ڈس کلیمر ہر انٹرفیس کے اندر ہم طریقوں کی وضاحت کر سکتے ہیں جیسے onClick، onValueChangedیا onInputChanged۔ وہ. وہ طریقے جو ہمیں مختلف واقعات کو ہینڈل کرنے کی اجازت دیں گے (بٹن پر کلک کرنا، ٹیکسٹ داخل کرنا، سلیکٹ باکس میں ویلیو منتخب کرنا)۔ یہ سب جان بوجھ کر چھوڑ دیا گیا ہے تاکہ مثال پر زیادہ بوجھ نہ پڑے اور فیکٹری پیٹرن کا مطالعہ کرنے کے لیے اسے مزید بصری بنایا جائے۔ آئیے اپنی مصنوعات کے لیے خلاصہ انٹرفیس کی وضاحت کریں:
public interface Button {}
public interface Select {}
public interface TextField {}
ہر آپریٹنگ سسٹم کے لیے، ہمیں اس آپریٹنگ سسٹم کے انداز میں انٹرفیس عناصر بنانا چاہیے۔ ہم ونڈوز اور میک او ایس کے لیے لکھتے ہیں۔ آئیے ونڈوز کے لیے نفاذات بنائیں:
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();

}
کامل جیسا کہ آپ دیکھ سکتے ہیں، اب تک کچھ بھی پیچیدہ نہیں ہے. پھر سب کچھ اتنا ہی آسان ہے۔ مصنوعات کے ساتھ مشابہت کے ساتھ، ہم ہر OS کے لیے اپنی فیکٹری کے مختلف نفاذات بناتے ہیں۔ آئیے ونڈوز کے ساتھ شروع کریں:
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();
    }
}
ایک تجریدی کارخانہ فارم کنسٹرکٹر کو منتقل کیا جاتا ہے، جو انٹرفیس عناصر تخلیق کرتا ہے۔ ہم مطلوبہ فیکٹری عمل درآمد کنسٹرکٹر کو دیں گے تاکہ ہم کسی خاص OS کے لیے انٹرفیس عناصر بنا سکیں۔
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 :( 
ٹھیک ہے، آپ اور میں مندرجہ ذیل نتیجہ اخذ کرتے ہیں۔ ہم نے ایک GUI ایپلیکیشن کے لیے ایک فریم ورک لکھا ہے جو بالکل وہی انٹرفیس عناصر تخلیق کرتا ہے جو دیے گئے OS کے لیے موزوں ہیں۔ آئیے مختصراً دہراتے ہیں کہ ہم نے کیا بنایا:
  • پروڈکٹ فیملی: ان پٹ فیلڈ، سلیکشن فیلڈ اور بٹن۔
  • ونڈوز اور میک او ایس کے لیے مصنوعات کے اس خاندان کے مختلف نفاذ۔
  • ایک تجریدی فیکٹری، جس کے اندر ہم نے اپنی مصنوعات بنانے کے لیے انٹرفیس کی وضاحت کی۔
  • ہماری فیکٹری کے دو نفاذ، جن میں سے ہر ایک مصنوعات کی ایک مخصوص فیملی بنانے کے لیے ذمہ دار ہے۔
  • ایک فارم، ایک جاوا کلاس جس کے فیلڈز خلاصہ انٹرفیس عناصر ہیں جو ایک تجریدی فیکٹری کا استعمال کرتے ہوئے مطلوبہ اقدار کے ساتھ کنسٹرکٹر میں شروع کیے جاتے ہیں۔
  • درخواست کی کلاس۔ اس کے اندر، ہم ایک فارم بناتے ہیں جس کے ساتھ ہم اپنی فیکٹری کے مطلوبہ عمل کو کنسٹرکٹر کو منتقل کرتے ہیں۔
کل: ہم نے تجریدی فیکٹری پیٹرن کو نافذ کیا ہے۔

خلاصہ فیکٹری: استعمال کے لیے ہدایات

خلاصہ فیکٹری مخصوص مصنوعات کی کلاسوں سے منسلک کیے بغیر مختلف پروڈکٹ فیملیز کی تخلیق کا انتظام کرنے کے لیے ایک ڈیزائن پیٹرن ہے۔ اس ٹیمپلیٹ کو استعمال کرتے وقت، آپ کو:
  1. مصنوعات کے خاندانوں کی خود وضاحت کریں۔ آئیے فرض کریں کہ ہمارے پاس ان میں سے دو ہیں:
    • SpecificProductA1,SpecificProductB1
    • SpecificProductA2,SpecificProductB2
  2. خاندان کے اندر ہر پروڈکٹ کے لیے، ایک خلاصہ کلاس (انٹرفیس) کی وضاحت کریں۔ ہمارے معاملے میں یہ ہے:
    • ProductA
    • ProductB
  3. ہر پروڈکٹ فیملی کے اندر، ہر پروڈکٹ کو مرحلہ 2 میں بیان کردہ انٹرفیس کو لاگو کرنا چاہیے۔
  4. مرحلہ 2 میں بیان کردہ ہر پروڈکٹ کے لیے تخلیق کے طریقوں کے ساتھ ایک تجریدی فیکٹری بنائیں۔ ہمارے معاملے میں، یہ طریقے ہوں گے:
    • ProductA createProductA();
    • ProductB createProductB();
  5. تجریدی فیکٹری کے نفاذ کو تخلیق کریں تاکہ ہر عمل درآمد ایک ہی خاندان کی مصنوعات کی تخلیق کو کنٹرول کرے۔ ایسا کرنے کے لیے، تجریدی فیکٹری کے ہر نفاذ کے اندر، تمام تخلیقی طریقوں کو نافذ کرنا ضروری ہے، تاکہ مصنوعات کے ٹھوس نفاذ کو ان کے اندر بنایا جائے اور واپس کیا جائے۔
ذیل میں ایک UML خاکہ ہے جو اوپر بیان کردہ ہدایات کی وضاحت کرتا ہے: ڈیزائن پیٹرن: AbstractFactory - 3اب آئیے اس ہدایت کے لیے کوڈ لکھتے ہیں:
// Определим общие интерфейсы продуктов
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 چیزیں کر سکتے ہیں:
  1. کافی آرڈرنگ ایپلیکیشن کو بہتر بنائیں تاکہ یہ لینکس پر کام کرے۔
  2. کسی بھی حکمت عملی کی اکائیاں تیار کرنے کے لیے اپنی تجریدی فیکٹری بنائیں۔ یہ یا تو حقیقی فوجوں کے ساتھ ایک تاریخی حکمت عملی ہو سکتی ہے یا orcs، بونے اور یلوس کے ساتھ ایک فنتاسی ہو سکتی ہے۔ اہم بات یہ ہے کہ آپ کو یہ دلچسپ لگتا ہے۔ تخلیقی بنیں، کنسول پر پن پوسٹ کریں، اور پیٹرن سیکھنے میں مزہ کریں!
تبصرے
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION