نمایش نتایج 1 تا 2 از 2

نام تاپیک: الگوهای طراحی Design Patterns در ++C

  1. #1

    Thumbs up الگوهای طراحی Design Patterns در ++C

    در مهندسی نرم افزار یک الگوی طراحی یک راه حل تکراری برای یک مشکل معمول در طراحی نرم افزار است.
    الگوی طراحی یک طرح کامل نیست! که بتوان آن را به طور مستقیم به کد تبدیل کرد. یک توضیح یا الگویی برای حل مشکل است که می تواند در بسیاری از شرایط مختلف نرم افزار استفاده شود.

    استفاده از الگوهای طراحی
    الگوهای طراحی می تواند فرایند توسعه را با ارائه پارادایم های آزمایش شده و اثبات شده توسعه نرم افزارسریع تر کند.
    طراحی نرم افزار موثر، نیاز به در نظر گرفتن مسائلی دارد که ممکن است تا بعد از پیاده سازی قابل مشاهده نباشد.
    این تکنیک ها برای گستره وسیعی از مشکلات به کار می روند. الگوهای طراحی راه حل های جامع را ارائه می دهند، مستند سازی شده در یک فرمت که خاصیت خاصی را به یک مشکل خاص مرتبط نمی کند.

    Creational design patterns
    این دسته از الگوهای طراحی همه در مورد نمونه سازی کلاس ها کاربرد دارند.که شامل تکنیک های زیر می باشند...
    - Abstract Factory : یک نمونه از خانواده های مختلف کلاس ایجاد می کند.
    - Builder : ساختار شیء را از نمایندگی آن جدا می کند
    - Factory Method :یک نمونه از چندین کلاس مشتق شده ایجاد می کند
    - Object Pool: اجتناب از اتصالات پرهزینه و انتشار منابع با بازیافت اشیائی که دیگر در حال استفاده نیستند
    - Prototype: یک مثال کامل به صورت اولیه برای کپی یا کلون کردن از شی فراهم می کند
    - Singleton: یک کلاس که فقط یک نمونه می تواند وجود داشته باشد

    Structural design patterns
    این دسته از الگوهای طراحی همه مربوط به ترکیب کلاس و Object هستند.
    الگوهای شئ های ساختاری شیوه هایی را برای نوشتن اشیا، برای به دست آوردن قابلیت های جدید تعریف می کنند.که شامل قسمتهای زیر می باشند...
    - Adapter: مطابقت واسطهای کلاسهای مختلف
    - Bridge: رابط کاربری شیء را از پیاده سازی آن جدا می کند
    - Composite : ساختار درخت از اشیاء ساده و کامپوزیت
    - Decorator : مسئولیت ها به اشیا را به صورت پویا اضافه می کنید
    - Facade: یک کلاس واحد که یک زیر سیستم کامل را نشان می دهد
    - Flyweight: یک مثال خوب برای استفاده در اشتراک گذاری کارآمد ساخت اشیای سبک
    - Private Class Data: دسترسی / تعویض را محدود میکند
    - Proxy: شیئی که یک شی دیگر را نشان می دهد

    Behavioral design patterns
    این دسته از الگوهای طراحی همه مربوط به ارتباطات Object Class است. الگوهای رفتاری الگوهایی هستند که به طور خاص به ارتباط بین اشیاء مربوط می شوند.که به قسمتهای زیر تقسیم می شوند...
    - Chain of responsibility : راه ارسال یک درخواست بین زنجیره ای از اشیاء
    - Command : یک درخواست فرمان را به عنوان یک شیء محاسبه کنید
    - Interpreter : راهی برای افزودن عناصر زبان در برنامه
    - Iterator : به طور متوالی به عناصر یک مجموعه دسترسی پیدا کنید
    - Mediator : ارتباطات ساده بین کلاس ها را تعریف می کند
    - Memento : ضبط و بازگرداندن حالت داخلی شی (سریال سازی)
    - Null Object : طراحی شده به عنوان یک مقدار پیش فرض یک شی عمل می کند
    - Observer : راهی برای اعلان تغییر در تعدادی از کلاس ها
    - State :وقتی وضعیت شی اصلی تغییر می کند، رفتار شی را تغییر دهید
    - Strategy :یک الگوریتم را داخل یک کلاس محاسبه می کند(ارسال الگوریتم ها مختلف به یک کلاس)

    - Template method: مراحل دقیق یک الگوریتم را به یک زیر کلاس متوقف کنید
    - Visitor : یک عملیات جدید را به یک کلاس بدون تغییر تعریف می کند

    مثالهای کاربردی از الگوهای طراحی
    Abstract Factory
    در نمونه کد زیر مشتری به طور مستقیم شی محصول را ایجاد میکند.
    در زمان ساخت کنترلهای کلاسها باید چک شود که برای کدام نوع سیستم عامل (ویندوز/لینوکس) می باشد و اگر بعدها هم سیستم عامل جدید اضافه شود باید در همه کلاسها یک شرط جدید برای ایجاد کنترل کلاس جدید ایجاد کنیم. که در اینصورت برنامه پر می شود از switch های زننده که هم خواندن کد را سخت میکنند وهم از نظر بصری مفید نخواهند بود.

    #include <iostream>
    #define LINUX

    using namespace std;

    /**
    * Abstract base product.
    */
    class Widget {
    public:
    virtual void draw() = 0;
    };

    /**
    * Concrete product family 1.
    */
    class LinuxButton : public Widget {
    public:
    void draw() { cout << "LinuxButton\n"; }
    };
    class LinuxMenu : public Widget {
    public:
    void draw() { cout << "LinuxMenu\n"; }
    };

    /**
    * Concrete product family 2.
    */
    class WindowsButton : public Widget {
    public:
    void draw() { cout << "WindowsButton\n"; }
    };
    class WindowsMenu : public Widget {
    public:
    void draw() { cout << "WindowsMenu\n"; }
    };

    /**
    * Here's a client, which uses concrete products directly.
    * It's code filled up with nasty switch statements
    * which check the product type before its use.
    */
    class Client {
    public:
    void draw() {
    #ifdef LINUX
    Widget *w = new LinuxButton;
    #else // WINDOWS
    Widget *w = new WindowsButton;
    #endif
    w->draw();
    display_window_one();
    display_window_two();
    }

    void display_window_one() {
    #ifdef LINUX
    Widget *w[] = {
    new LinuxButton,
    new LinuxMenu
    };
    #else // WINDOWS
    Widget *w[] = {
    new WindowsButton,
    new WindowsMenu
    };
    #endif
    w[0]->draw();
    w[1]->draw();
    }

    void display_window_two() {
    #ifdef LINUX
    Widget *w[] = {
    new LinuxMenu,
    new LinuxButton
    };
    #else // WINDOWS
    Widget *w[] = {
    new WindowsMenu,
    new WindowsButton
    };
    #endif
    w[0]->draw();
    w[1]->draw();
    }
    };

    int main() {
    Client *c = new Client();
    c->draw();
    }

    ولی با استفاده از الگوی Abstract Factory فقط یکبار از switch استفاده می شود و اشیا ساخته می شوند. در آینده نیز به راحتی می توانید موارد جدید را به برنامه اضافه کنید بدون اینکه نگران سایر گیرنده ها باشید.

    #include <iostream>
    #define LINUX

    using namespace std;

    /**
    * Abstract base product. It should define an interface
    * which will be common to all products. Clients will
    * work with products through this interface, so it
    * should be sufficient to use all products.
    */
    class Widget {
    public:
    virtual void draw() = 0;
    };

    /**
    * Concrete product family 1.
    */
    class LinuxButton : public Widget {
    public:
    void draw() { cout << "LinuxButton\n"; }
    };
    class LinuxMenu : public Widget {
    public:
    void draw() { cout << "LinuxMenu\n"; }
    };

    /**
    * Concrete product family 2.
    */
    class WindowsButton : public Widget {
    public:
    void draw() { cout << "WindowsButton\n"; }
    };
    class WindowsMenu : public Widget {
    public:
    void draw() { cout << "WindowsMenu\n"; }
    };

    /**
    * Abstract factory defines methods to create all
    * related products.
    */
    class Factory {
    public:
    virtual Widget *create_button() = 0;
    virtual Widget *create_menu() = 0;
    };

    /**
    * Each concrete factory corresponds to one product
    * family. It creates all possible products of
    * one kind.
    */
    class LinuxFactory : public Factory {
    public:
    Widget *create_button() {
    return new LinuxButton;
    }
    Widget *create_menu() {
    return new LinuxMenu;
    }
    };

    /**
    * Concrete factory creates concrete products, but
    * returns them as abstract.
    */
    class WindowsFactory : public Factory {
    public:
    Widget *create_button() {
    return new WindowsButton;
    }
    Widget *create_menu() {
    return new WindowsMenu;
    }
    };

    /**
    * Client receives a factory object from its creator.
    *
    * All clients work with factories through abstract
    * interface. They don't know concrete classes of
    * factories. Because of this, you can interchange
    * concrete factories without breaking clients.
    *
    * Clients don't know the concrete classes of created
    * products either, since abstract factory methods
    * returns abstract products.
    */
    class Client {
    private:
    Factory *factory;

    public:
    Client(Factory *f) {
    factory = f;
    }

    void draw() {
    Widget *w = factory->create_button();
    w->draw();
    display_window_one();
    display_window_two();
    }

    void display_window_one() {
    Widget *w[] = {
    factory->create_button(),
    factory->create_menu()
    };
    w[0]->draw();
    w[1]->draw();
    }

    void display_window_two() {
    Widget *w[] = {
    factory->create_menu(),
    factory->create_button()
    };
    w[0]->draw();
    w[1]->draw();
    }
    };

    /**
    * Now the nasty switch statement is needed only once to
    * pick and create a proper factory. Usually that's
    * happening somewhere in program initialization code.
    */
    int main() {
    Factory *factory;
    #ifdef LINUX
    factory = new LinuxFactory;
    #else // WINDOWS
    factory = new WindowsFactory;
    #endif

    Client *c = new Client(factory);
    c->draw();
    }

    Builder design pattern
    الگوی سازنده، ساختن یک اجسام پیچیده را از نمایندگی آن جدا می کند، به طوری که همان فرآیند ساخت و ساز می تواند نماینده های مختلفی ایجاد کند.
    این الگو توسط رستوران های فست فود برای تهیه وعده های غذایی کودکان استفاده می شود. وعده های غذایی کودکان به طور معمول شامل یک آیتم اصلی، یک آیتم جانبی، یک نوشیدنی و یک اسباب بازی (به عنوان مثال یک همبرگر، سرخ کرده، کک و دایناسور اسباب بازی) است.
    توجه داشته باشید که محتوای غذا کودکان ممکن است متفاوت باشد اما روند ساخت یکسان است. این که مشتری یک همبرگر، چیزبرگر یا مرغ را سفارش می دهد، روند مشابه است. این موارد سپس در یک کیسه قرار می گیرند. نوشیدنی در یک فنجان قرار داده می شود و در خارج از کیسه قرار می گیرد.

    #include <iostream.h>
    #include <stdio.h>
    #include <string.h>

    enum PersistenceType{
    File, Queue, Pathway
    };

    struct PersistenceAttribute{
    PersistenceType type;
    char value[30];
    };

    class DistrWorkPackage{
    public:
    DistrWorkPackage(char *type)
    {
    sprintf(_desc, "Distributed Work Package for: %s", type);
    }
    void setFile(char *f, char *v)
    {
    sprintf(_temp, "\n File(%s): %s", f, v);
    strcat(_desc, _temp);
    }
    void setQueue(char *q, char *v)
    {
    sprintf(_temp, "\n Queue(%s): %s", q, v);
    strcat(_desc, _temp);
    }
    void setPathway(char *p, char *v)
    {
    sprintf(_temp, "\n Pathway(%s): %s", p, v);
    strcat(_desc, _temp);
    }
    const char *getState()
    {
    return _desc;
    }
    private:
    char _desc[200], _temp[80];
    };

    class Builder{
    public:
    virtual void configureFile(char*) = 0;
    virtual void configureQueue(char*) = 0;
    virtual void configurePathway(char*) = 0;
    DistrWorkPackage *getResult()
    {
    return _result;
    }
    protected:
    DistrWorkPackage *_result;
    };

    class UnixBuilder: public Builder{

    public:
    UnixBuilder()
    {
    _result = new DistrWorkPackage("Unix");
    }
    void configureFile(char *name)
    {
    _result->setFile("flatFile", name);
    }
    void configureQueue(char *queue)
    {
    _result->setQueue("FIFO", queue);
    }
    void configurePathway(char *type)
    {
    _result->setPathway("thread", type);
    }
    };

    class VmsBuilder: public Builder{

    public:
    VmsBuilder()
    {
    _result = new DistrWorkPackage("Vms");
    }
    void configureFile(char *name)
    {
    _result->setFile("ISAM", name);
    }
    void configureQueue(char *queue)
    {
    _result->setQueue("priority", queue);
    }
    void configurePathway(char *type)
    {
    _result->setPathway("LWP", type);
    }
    };

    class Reader{

    public:
    void setBuilder(Builder *b)
    {
    _builder = b;
    }
    void construct(PersistenceAttribute[], int);
    private:
    Builder *_builder;
    };

    void Reader::construct(PersistenceAttribute list[], int num)
    {
    for (int i = 0; i < num; i++)
    if (list[i].type == File)
    _builder->configureFile(list[i].value);
    else if (list[i].type == Queue)
    _builder->configureQueue(list[i].value);
    else if (list[i].type == Pathway)
    _builder->configurePathway(list[i].value);
    }

    const int NUM_ENTRIES = 6;
    PersistenceAttribute input[NUM_ENTRIES] =
    {
    {File, "state.dat"}, {File, "config.sys"},
    {Queue, "compute"}, {Queue, "log"}, {Pathway, "authentication"}, {Pathway, "error processing"}
    };

    int main()
    {
    UnixBuilder unixBuilder;
    VmsBuilder vmsBuilder;
    Reader reader;

    reader.setBuilder(&unixBuilder);
    reader.construct(input, NUM_ENTRIES);
    cout << unixBuilder.getResult()->getState() << endl;

    reader.setBuilder(&vmsBuilder);
    reader.construct(input, NUM_ENTRIES);
    cout << vmsBuilder.getResult()->getState() << endl;
    }


    Factory Method
    روش متدکارخانه به کلاس اجازه می دهد نمونه اولیه را به زیر کلاس ها منتقل کند.
    روند تولید کنندگان اسباب بازی های پلاستیکی، پودر قالب گیری پلاستیک، و تزریق پلاستیک به قالب از اشکال مورد نظر است. کلاس اسباب بازی (ماشین، شکل عمل، و غیره) توسط قالب تعیین می شود.

    class Stooge
    {
    public:
    virtual void slap_stick() = 0;
    };

    class Larry: public Stooge
    {
    public:
    void slap_stick()
    {
    cout << "Larry: poke eyes\n";
    }
    };
    class Moe: public Stooge
    {
    public:
    void slap_stick()
    {
    cout << "Moe: slap head\n";
    }
    };
    class Curly: public Stooge
    {
    public:
    void slap_stick()
    {
    cout << "Curly: suffer abuse\n";
    }
    };

    int main()
    {
    vector<Stooge*> roles;
    int choice;

    while (true)
    {
    cout << "Larry(1) Moe(2) Curly(3) Go(0): ";
    cin >> choice;
    if (choice == 0)
    break;
    else if (choice == 1)
    roles.push_back(new Larry);
    else if (choice == 2)
    roles.push_back(new Moe);
    else
    roles.push_back(new Curly);
    }
    for (int i = 0; i < roles.size(); i++)
    roles[i]->slap_stick();
    for (int i = 0; i < roles.size(); i++)
    delete roles[i];
    }

    یک متد کارخانه یک روش استاتیکی از یک کلاس است که یک شی از نوع کلاس را بازمیگرداند. اما بر خلاف یک سازنده، شیء واقعی که باز می شود ممکن است یک نمونه از زیر کلاس باشد. یکی دیگر از مزیت یک متد کارخانه این است که می تواند نمونه های موجود را چندین بار بازگرداند.

    class Stooge
    {
    public:
    // Factory Method
    static Stooge *make_stooge(int choice);
    virtual void slap_stick() = 0;
    };

    class Larry: public Stooge
    {
    public:
    void slap_stick()
    {
    cout << "Larry: poke eyes\n";
    }
    };
    class Moe: public Stooge
    {
    public:
    void slap_stick()
    {
    cout << "Moe: slap head\n";
    }
    };
    class Curly: public Stooge
    {
    public:
    void slap_stick()
    {
    cout << "Curly: suffer abuse\n";
    }
    };

    Stooge *Stooge::make_stooge(int choice)
    {
    if (choice == 1)
    return new Larry;
    else if (choice == 2)
    return new Moe;
    else
    return new Curly;
    }

    int main()
    {
    vector<Stooge*> roles;
    int choice;
    while (true)
    {
    cout << "Larry(1) Moe(2) Curly(3) Go(0): ";
    cin >> choice;
    if (choice == 0)
    break;
    roles.push_back(Stooge::make_stooge(choice));
    }
    for (int i = 0; i < roles.size(); i++)
    roles[i]->slap_stick();
    for (int i = 0; i < roles.size(); i++)
    delete roles[i];
    }

  2. #2

    نقل قول: الگوهای طراحی Design Patterns در ++C

    واقعا عالی بود اطلاعات کامل و خوبی ارائه کردید، ممنون

    پنجره دوجداره تعویض پنجره های قدیمی تعویض سرامیک سرویس بهداشتی

    نقل قول نوشته شده توسط farhad_shiri_ex مشاهده تاپیک
    در مهندسی نرم افزار یک الگوی طراحی یک راه حل تکراری برای یک مشکل معمول در طراحی نرم افزار است.
    الگوی طراحی یک طرح کامل نیست! که بتوان آن را به طور مستقیم به کد تبدیل کرد. یک توضیح یا الگویی برای حل مشکل است که می تواند در بسیاری از شرایط مختلف نرم افزار استفاده شود.

    استفاده از الگوهای طراحی
    الگوهای طراحی می تواند فرایند توسعه را با ارائه پارادایم های آزمایش شده و اثبات شده توسعه نرم افزارسریع تر کند.
    طراحی نرم افزار موثر، نیاز به در نظر گرفتن مسائلی دارد که ممکن است تا بعد از پیاده سازی قابل مشاهده نباشد.
    این تکنیک ها برای گستره وسیعی از مشکلات به کار می روند. الگوهای طراحی راه حل های جامع را ارائه می دهند، مستند سازی شده در یک فرمت که خاصیت خاصی را به یک مشکل خاص مرتبط نمی کند.

    Creational design patterns
    این دسته از الگوهای طراحی همه در مورد نمونه سازی کلاس ها کاربرد دارند.که شامل تکنیک های زیر می باشند...
    - Abstract Factory : یک نمونه از خانواده های مختلف کلاس ایجاد می کند.
    - Builder : ساختار شیء را از نمایندگی آن جدا می کند
    - Factory Method :یک نمونه از چندین کلاس مشتق شده ایجاد می کند
    - Object Pool: اجتناب از اتصالات پرهزینه و انتشار منابع با بازیافت اشیائی که دیگر در حال استفاده نیستند
    - Prototype: یک مثال کامل به صورت اولیه برای کپی یا کلون کردن از شی فراهم می کند
    - Singleton: یک کلاس که فقط یک نمونه می تواند وجود داشته باشد

    Structural design patterns
    این دسته از الگوهای طراحی همه مربوط به ترکیب کلاس و Object هستند.
    الگوهای شئ های ساختاری شیوه هایی را برای نوشتن اشیا، برای به دست آوردن قابلیت های جدید تعریف می کنند.که شامل قسمتهای زیر می باشند...
    - Adapter: مطابقت واسطهای کلاسهای مختلف
    - Bridge: رابط کاربری شیء را از پیاده سازی آن جدا می کند
    - Composite : ساختار درخت از اشیاء ساده و کامپوزیت
    - Decorator : مسئولیت ها به اشیا را به صورت پویا اضافه می کنید
    - Facade: یک کلاس واحد که یک زیر سیستم کامل را نشان می دهد
    - Flyweight: یک مثال خوب برای استفاده در اشتراک گذاری کارآمد ساخت اشیای سبک
    - Private Class Data: دسترسی / تعویض را محدود میکند
    - Proxy: شیئی که یک شی دیگر را نشان می دهد

    Behavioral design patterns
    این دسته از الگوهای طراحی همه مربوط به ارتباطات Object Class است. الگوهای رفتاری الگوهایی هستند که به طور خاص به ارتباط بین اشیاء مربوط می شوند.که به قسمتهای زیر تقسیم می شوند...
    - Chain of responsibility : راه ارسال یک درخواست بین زنجیره ای از اشیاء
    - Command : یک درخواست فرمان را به عنوان یک شیء محاسبه کنید
    - Interpreter : راهی برای افزودن عناصر زبان در برنامه
    - Iterator : به طور متوالی به عناصر یک مجموعه دسترسی پیدا کنید
    - Mediator : ارتباطات ساده بین کلاس ها را تعریف می کند
    - Memento : ضبط و بازگرداندن حالت داخلی شی (سریال سازی)
    - Null Object : طراحی شده به عنوان یک مقدار پیش فرض یک شی عمل می کند
    - Observer : راهی برای اعلان تغییر در تعدادی از کلاس ها
    - State :وقتی وضعیت شی اصلی تغییر می کند، رفتار شی را تغییر دهید
    - Strategy :یک الگوریتم را داخل یک کلاس محاسبه می کند(ارسال الگوریتم ها مختلف به یک کلاس)

    - Template method: مراحل دقیق یک الگوریتم را به یک زیر کلاس متوقف کنید
    - Visitor : یک عملیات جدید را به یک کلاس بدون تغییر تعریف می کند

    مثالهای کاربردی از الگوهای طراحی
    Abstract Factory
    در نمونه کد زیر مشتری به طور مستقیم شی محصول را ایجاد میکند.
    در زمان ساخت کنترلهای کلاسها باید چک شود که برای کدام نوع سیستم عامل (ویندوز/لینوکس) می باشد و اگر بعدها هم سیستم عامل جدید اضافه شود باید در همه کلاسها یک شرط جدید برای ایجاد کنترل کلاس جدید ایجاد کنیم. که در اینصورت برنامه پر می شود از switch های زننده که هم خواندن کد را سخت میکنند وهم از نظر بصری مفید نخواهند بود.

    #include <iostream>
    #define LINUX

    using namespace std;

    /**
    * Abstract base product.
    */
    class Widget {
    public:
    virtual void draw() = 0;
    };

    /**
    * Concrete product family 1.
    */
    class LinuxButton : public Widget {
    public:
    void draw() { cout << "LinuxButton\n"; }
    };
    class LinuxMenu : public Widget {
    public:
    void draw() { cout << "LinuxMenu\n"; }
    };

    /**
    * Concrete product family 2.
    */
    class WindowsButton : public Widget {
    public:
    void draw() { cout << "WindowsButton\n"; }
    };
    class WindowsMenu : public Widget {
    public:
    void draw() { cout << "WindowsMenu\n"; }
    };

    /**
    * Here's a client, which uses concrete products directly.
    * It's code filled up with nasty switch statements
    * which check the product type before its use.
    */
    class Client {
    public:
    void draw() {
    #ifdef LINUX
    Widget *w = new LinuxButton;
    #else // WINDOWS
    Widget *w = new WindowsButton;
    #endif
    w->draw();
    display_window_one();
    display_window_two();
    }

    void display_window_one() {
    #ifdef LINUX
    Widget *w[] = {
    new LinuxButton,
    new LinuxMenu
    };
    #else // WINDOWS
    Widget *w[] = {
    new WindowsButton,
    new WindowsMenu
    };
    #endif
    w[0]->draw();
    w[1]->draw();
    }

    void display_window_two() {
    #ifdef LINUX
    Widget *w[] = {
    new LinuxMenu,
    new LinuxButton
    };
    #else // WINDOWS
    Widget *w[] = {
    new WindowsMenu,
    new WindowsButton
    };
    #endif
    w[0]->draw();
    w[1]->draw();
    }
    };

    int main() {
    Client *c = new Client();
    c->draw();
    }

    ولی با استفاده از الگوی Abstract Factory فقط یکبار از switch استفاده می شود و اشیا ساخته می شوند. در آینده نیز به راحتی می توانید موارد جدید را به برنامه اضافه کنید بدون اینکه نگران سایر گیرنده ها باشید.

    #include <iostream>
    #define LINUX

    using namespace std;

    /**
    * Abstract base product. It should define an interface
    * which will be common to all products. Clients will
    * work with products through this interface, so it
    * should be sufficient to use all products.
    */
    class Widget {
    public:
    virtual void draw() = 0;
    };

    /**
    * Concrete product family 1.
    */
    class LinuxButton : public Widget {
    public:
    void draw() { cout << "LinuxButton\n"; }
    };
    class LinuxMenu : public Widget {
    public:
    void draw() { cout << "LinuxMenu\n"; }
    };

    /**
    * Concrete product family 2.
    */
    class WindowsButton : public Widget {
    public:
    void draw() { cout << "WindowsButton\n"; }
    };
    class WindowsMenu : public Widget {
    public:
    void draw() { cout << "WindowsMenu\n"; }
    };

    /**
    * Abstract factory defines methods to create all
    * related products.
    */
    class Factory {
    public:
    virtual Widget *create_button() = 0;
    virtual Widget *create_menu() = 0;
    };

    /**
    * Each concrete factory corresponds to one product
    * family. It creates all possible products of
    * one kind.
    */
    class LinuxFactory : public Factory {
    public:
    Widget *create_button() {
    return new LinuxButton;
    }
    Widget *create_menu() {
    return new LinuxMenu;
    }
    };

    /**
    * Concrete factory creates concrete products, but
    * returns them as abstract.
    */
    class WindowsFactory : public Factory {
    public:
    Widget *create_button() {
    return new WindowsButton;
    }
    Widget *create_menu() {
    return new WindowsMenu;
    }
    };

    /**
    * Client receives a factory object from its creator.
    *
    * All clients work with factories through abstract
    * interface. They don't know concrete classes of
    * factories. Because of this, you can interchange
    * concrete factories without breaking clients.
    *
    * Clients don't know the concrete classes of created
    * products either, since abstract factory methods
    * returns abstract products.
    */
    class Client {
    private:
    Factory *factory;

    public:
    Client(Factory *f) {
    factory = f;
    }

    void draw() {
    Widget *w = factory->create_button();
    w->draw();
    display_window_one();
    display_window_two();
    }

    void display_window_one() {
    Widget *w[] = {
    factory->create_button(),
    factory->create_menu()
    };
    w[0]->draw();
    w[1]->draw();
    }

    void display_window_two() {
    Widget *w[] = {
    factory->create_menu(),
    factory->create_button()
    };
    w[0]->draw();
    w[1]->draw();
    }
    };

    /**
    * Now the nasty switch statement is needed only once to
    * pick and create a proper factory. Usually that's
    * happening somewhere in program initialization code.
    */
    int main() {
    Factory *factory;
    #ifdef LINUX
    factory = new LinuxFactory;
    #else // WINDOWS
    factory = new WindowsFactory;
    #endif

    Client *c = new Client(factory);
    c->draw();
    }

    Builder design pattern
    الگوی سازنده، ساختن یک اجسام پیچیده را از نمایندگی آن جدا می کند، به طوری که همان فرآیند ساخت و ساز می تواند نماینده های مختلفی ایجاد کند.
    این الگو توسط رستوران های فست فود برای تهیه وعده های غذایی کودکان استفاده می شود. وعده های غذایی کودکان به طور معمول شامل یک آیتم اصلی، یک آیتم جانبی، یک نوشیدنی و یک اسباب بازی (به عنوان مثال یک همبرگر، سرخ کرده، کک و دایناسور اسباب بازی) است.
    توجه داشته باشید که محتوای غذا کودکان ممکن است متفاوت باشد اما روند ساخت یکسان است. این که مشتری یک همبرگر، چیزبرگر یا مرغ را سفارش می دهد، روند مشابه است. این موارد سپس در یک کیسه قرار می گیرند. نوشیدنی در یک فنجان قرار داده می شود و در خارج از کیسه قرار می گیرد.

    #include <iostream.h>
    #include <stdio.h>
    #include <string.h>

    enum PersistenceType{
    File, Queue, Pathway
    };

    struct PersistenceAttribute{
    PersistenceType type;
    char value[30];
    };

    class DistrWorkPackage{
    public:
    DistrWorkPackage(char *type)
    {
    sprintf(_desc, "Distributed Work Package for: %s", type);
    }
    void setFile(char *f, char *v)
    {
    sprintf(_temp, "\n File(%s): %s", f, v);
    strcat(_desc, _temp);
    }
    void setQueue(char *q, char *v)
    {
    sprintf(_temp, "\n Queue(%s): %s", q, v);
    strcat(_desc, _temp);
    }
    void setPathway(char *p, char *v)
    {
    sprintf(_temp, "\n Pathway(%s): %s", p, v);
    strcat(_desc, _temp);
    }
    const char *getState()
    {
    return _desc;
    }
    private:
    char _desc[200], _temp[80];
    };

    class Builder{
    public:
    virtual void configureFile(char*) = 0;
    virtual void configureQueue(char*) = 0;
    virtual void configurePathway(char*) = 0;
    DistrWorkPackage *getResult()
    {
    return _result;
    }
    protected:
    DistrWorkPackage *_result;
    };

    class UnixBuilder: public Builder{

    public:
    UnixBuilder()
    {
    _result = new DistrWorkPackage("Unix");
    }
    void configureFile(char *name)
    {
    _result->setFile("flatFile", name);
    }
    void configureQueue(char *queue)
    {
    _result->setQueue("FIFO", queue);
    }
    void configurePathway(char *type)
    {
    _result->setPathway("thread", type);
    }
    };

    class VmsBuilder: public Builder{

    public:
    VmsBuilder()
    {
    _result = new DistrWorkPackage("Vms");
    }
    void configureFile(char *name)
    {
    _result->setFile("ISAM", name);
    }
    void configureQueue(char *queue)
    {
    _result->setQueue("priority", queue);
    }
    void configurePathway(char *type)
    {
    _result->setPathway("LWP", type);
    }
    };

    class Reader{

    public:
    void setBuilder(Builder *b)
    {
    _builder = b;
    }
    void construct(PersistenceAttribute[], int);
    private:
    Builder *_builder;
    };

    void Reader::construct(PersistenceAttribute list[], int num)
    {
    for (int i = 0; i < num; i++)
    if (list[i].type == File)
    _builder->configureFile(list[i].value);
    else if (list[i].type == Queue)
    _builder->configureQueue(list[i].value);
    else if (list[i].type == Pathway)
    _builder->configurePathway(list[i].value);
    }

    const int NUM_ENTRIES = 6;
    PersistenceAttribute input[NUM_ENTRIES] =
    {
    {File, "state.dat"}, {File, "config.sys"},
    {Queue, "compute"}, {Queue, "log"}, {Pathway, "authentication"}, {Pathway, "error processing"}
    };

    int main()
    {
    UnixBuilder unixBuilder;
    VmsBuilder vmsBuilder;
    Reader reader;

    reader.setBuilder(&unixBuilder);
    reader.construct(input, NUM_ENTRIES);
    cout << unixBuilder.getResult()->getState() << endl;

    reader.setBuilder(&vmsBuilder);
    reader.construct(input, NUM_ENTRIES);
    cout << vmsBuilder.getResult()->getState() << endl;
    }


    Factory Method
    روش متدکارخانه به کلاس اجازه می دهد نمونه اولیه را به زیر کلاس ها منتقل کند.
    روند تولید کنندگان اسباب بازی های پلاستیکی، پودر قالب گیری پلاستیک، و تزریق پلاستیک به قالب از اشکال مورد نظر است. کلاس اسباب بازی (ماشین، شکل عمل، و غیره) توسط قالب تعیین می شود.

    class Stooge
    {
    public:
    virtual void slap_stick() = 0;
    };

    class Larry: public Stooge
    {
    public:
    void slap_stick()
    {
    cout << "Larry: poke eyes\n";
    }
    };
    class Moe: public Stooge
    {
    public:
    void slap_stick()
    {
    cout << "Moe: slap head\n";
    }
    };
    class Curly: public Stooge
    {
    public:
    void slap_stick()
    {
    cout << "Curly: suffer abuse\n";
    }
    };

    int main()
    {
    vector<Stooge*> roles;
    int choice;

    while (true)
    {
    cout << "Larry(1) Moe(2) Curly(3) Go(0): ";
    cin >> choice;
    if (choice == 0)
    break;
    else if (choice == 1)
    roles.push_back(new Larry);
    else if (choice == 2)
    roles.push_back(new Moe);
    else
    roles.push_back(new Curly);
    }
    for (int i = 0; i < roles.size(); i++)
    roles[i]->slap_stick();
    for (int i = 0; i < roles.size(); i++)
    delete roles[i];
    }

    یک متد کارخانه یک روش استاتیکی از یک کلاس است که یک شی از نوع کلاس را بازمیگرداند. اما بر خلاف یک سازنده، شیء واقعی که باز می شود ممکن است یک نمونه از زیر کلاس باشد. یکی دیگر از مزیت یک متد کارخانه این است که می تواند نمونه های موجود را چندین بار بازگرداند.

    class Stooge
    {
    public:
    // Factory Method
    static Stooge *make_stooge(int choice);
    virtual void slap_stick() = 0;
    };

    class Larry: public Stooge
    {
    public:
    void slap_stick()
    {
    cout << "Larry: poke eyes\n";
    }
    };
    class Moe: public Stooge
    {
    public:
    void slap_stick()
    {
    cout << "Moe: slap head\n";
    }
    };
    class Curly: public Stooge
    {
    public:
    void slap_stick()
    {
    cout << "Curly: suffer abuse\n";
    }
    };

    Stooge *Stooge::make_stooge(int choice)
    {
    if (choice == 1)
    return new Larry;
    else if (choice == 2)
    return new Moe;
    else
    return new Curly;
    }

    int main()
    {
    vector<Stooge*> roles;
    int choice;
    while (true)
    {
    cout << "Larry(1) Moe(2) Curly(3) Go(0): ";
    cin >> choice;
    if (choice == 0)
    break;
    roles.push_back(Stooge::make_stooge(choice));
    }
    for (int i = 0; i < roles.size(); i++)
    roles[i]->slap_stick();
    for (int i = 0; i < roles.size(); i++)
    delete roles[i];
    }

تاپیک های مشابه

  1. PHP Design Patterns
    نوشته شده توسط KouroshSharifi در بخش PHP
    پاسخ: 1
    آخرین پست: شنبه 17 خرداد 1393, 14:28 عصر
  2. design patterns AND mvc
    نوشته شده توسط مهدی هادیان2 در بخش ASP.NET MVC
    پاسخ: 0
    آخرین پست: جمعه 26 مهر 1392, 16:35 عصر
  3. الگوهای طراحی (ِDesign Patterns)
    نوشته شده توسط behrouzlo در بخش تحلیل و طراحی نرم افزار
    پاسخ: 0
    آخرین پست: دوشنبه 06 دی 1389, 15:53 عصر
  4. Design Patterns
    نوشته شده توسط b581102 در بخش تحلیل و طراحی نرم افزار
    پاسخ: 6
    آخرین پست: چهارشنبه 13 مرداد 1389, 19:04 عصر
  5. Design Patterns
    نوشته شده توسط b581102 در بخش ASP.NET Web Forms
    پاسخ: 3
    آخرین پست: شنبه 22 تیر 1387, 19:25 عصر

برچسب های این تاپیک

قوانین ایجاد تاپیک در تالار

  • شما نمی توانید تاپیک جدید ایجاد کنید
  • شما نمی توانید به تاپیک ها پاسخ دهید
  • شما نمی توانید ضمیمه ارسال کنید
  • شما نمی توانید پاسخ هایتان را ویرایش کنید
  •