1. 程式人生 > >Gof23種設計模式+簡單工廠設計模式總結(一)

Gof23種設計模式+簡單工廠設計模式總結(一)

一、軟體設計模式的種類

1.建立型模式

如何建立物件

2.結構型模式

如何實現類和物件的組合

3.行為型模式

類和物件怎麼樣互動以及怎麼樣分配職責

二、設計模式的原則

高內聚、低耦合

1.單一職責原則

類的職責比較單一,對外只提供一種功能,引起類變化的原因應該只有一個

2.開閉原則

新增新的功能時,是通過新增程式碼實現的,而不是去修改原始碼

3.里氏替換原則

任何抽象類出現的地方都可以用他的實現類來進行替換,實際就是虛擬機制,語言級別實現面向物件的功能

4.依賴倒轉原則

依賴於抽象介面,不要依賴具體的實現類,也就是針對介面程式設計

5.介面隔離原則

不要強迫使用者的程式依賴他們不需要的介面方法,一個介面只提供一種對外的功能,不應該把所有操作都封裝到一個介面中去

6.合成複用原則

如果使用繼承,會導致父類的任何變換都可能影響到子類的行為,如果使用物件組合,就降低了這種依賴關係,對於繼承和組合,優先使用組合

7.迪米特法則

一個物件應該對其他物件儘可能少地瞭解,從而降低各個物件之間的耦合,提高系統的可維護性

三、建立型模型

1.簡單工廠設計模式

簡單工廠設計模式並不屬於Gof23中設計模式之一。

1)簡單工廠設計模式的案例程式碼:

#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <string>
using namespace std;


class GameRole
{
public:
    virtual void roleMove() = 0;
};

//向左移動
class LeftMoveRole : public GameRole
{
public:
    virtual void roleMove()
    {
        cout << "向左移動" << endl;
    }
};


//向右移動
class RightMoveRole : public GameRole
{
public:
    virtual void roleMove()
    {
        cout << "向右移動" << endl;
    }
};

//向左快速移動
class LeftSpeedMoveRole : public GameRole
{
public:
    virtual void roleMove()
    {
        cout << "向左快速移動" << endl;
    }
};

//向右快速移動
class RightSpeedMoveRole : public GameRole
{
public:
    virtual void roleMove()
    {
        cout << "向右快速移動" << endl;
    }
};

//移動的動作工廠
class MoveFactory
{
public:
    static GameRole* CreateRoleMove(string name)
    {
        if (name.compare("left") == 0)
        {
            return new LeftMoveRole;
        }
        else if (name.compare("right") == 0)
        {
            return new RightMoveRole;
        }
        else if (name.compare("leftspeed") == 0)
        {
            return new LeftSpeedMoveRole;
        }
        else if (name.compare("rightspeed") == 0)
        {
            return new RightSpeedMoveRole;
        }
    }
};

int main()
{
    GameRole *role = NULL;
    role = MoveFactory::CreateRoleMove("left");
    role->roleMove();
    delete role;

    role = MoveFactory::CreateRoleMove("right");
    role->roleMove();
    delete role;

    role = MoveFactory::CreateRoleMove("leftspeed");
    role->roleMove();
    delete role;

    role = MoveFactory::CreateRoleMove("rightspeed");
    role->roleMove();
    delete role;

    system("pause");
    return 0;
}

2).簡單工廠設計模式的優缺點以及適用場景
優點:

物件建立和使用的分離
不需要記住類名,只需要記住引數就可以,可以減少開發者的記憶的使用

缺點:

工廠類負責的定西太多,一旦受到影響,系統會不能夠工作
增加了系統中類的個數,對開發產生一些複雜度和理解度的問題
違反了“開閉原則”,新增新產品需要修改程式碼邏輯,工廠類會變得更復雜

適用場景:

工廠類建立物件比較少的情況
客戶端只知道傳入引數,具體怎麼實現並不關心的情況

2.工廠方法設計模式

工廠方法模式 = 簡單工廠模式 + 開閉原則

1).工廠方法模式案例程式碼

#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <string>
using namespace std;


class GameRole
{
public:
    virtual void roleMove() = 0;
};

//向左移動
class LeftMoveRole : public GameRole
{
public:
    virtual void roleMove()
    {
        cout << "向左移動" << endl;
    }
};


//向右移動
class RightMoveRole : public GameRole
{
public:
    virtual void roleMove()
    {
        cout << "向右移動" << endl;
    }
};

//向左快速移動
class LeftSpeedMoveRole : public GameRole
{
public:
    virtual void roleMove()
    {
        cout << "向左快速移動" << endl;
    }
};

//向右快速移動
class RightSpeedMoveRole : public GameRole
{
public:
    virtual void roleMove()
    {
        cout << "向右快速移動" << endl;
    }
};
class AbstractFactory
{
public:
    virtual GameRole* CreateGameRole() = 0;
};

class LeftRoleFactory : public AbstractFactory
{
public:
    virtual GameRole* CreateGameRole()
    {
        return new LeftMoveRole;
    }
};

class RightRoleFactory : public AbstractFactory
{
public:
    virtual GameRole* CreateGameRole()
    {
        return new RightMoveRole;
    }
};

class LeftSpeedRoleFactory : public AbstractFactory
{
public:
    virtual GameRole* CreateGameRole()
    {
        return new LeftSpeedMoveRole;
    }
};

class RightSpeedRoleFactory : public AbstractFactory
{
public:
    virtual GameRole* CreateGameRole()
    {
        return new RightSpeedMoveRole;
    }
};

int main()
{
    GameRole *role = NULL;
    AbstractFactory *factory = NULL;

    factory = new LeftRoleFactory;
    role = factory->CreateGameRole();
    role->roleMove();

    factory = new RightRoleFactory;
    role = factory->CreateGameRole();
    role->roleMove();

    factory = new LeftSpeedRoleFactory;
    role = factory->CreateGameRole();
    role->roleMove();

    factory = new RightSpeedRoleFactory;
    role = factory->CreateGameRole();
    role->roleMove();

    system("pause");
    return 0;
}

2).工廠方法模式的優缺點以及適用場景
優點:

不需要記住具體的類名和具體的引數
物件建立和使用的分離
新增新功能時,無需修改原始碼,只需要新增新的程式碼即可實現

缺點:

類的個數比較多,對開發者的理解度要求高
系統的複雜度比較高
增加了系統的抽象性和理解度

適用場景:

客戶端不需要知道它所需要的物件和類
抽象工廠類通過其子類來指定建立那個物件

2.抽象工廠模式

抽象工廠角色:它聲明瞭一組用於建立一族產品的方法,每個方法對應一種產品。
具體工廠角色:實現了在抽象工廠中宣告的建立產品的方法,生成一組具體的產品,這些產品構成了一個產品族,每一個產品都位於某個產品等級結構中。

1).抽象工廠模式案例程式碼
#define _CRT_SECURE_NO_WARNINGS
#include
#include
using namespace std;

//抽象的王者榮耀程咬金角色
class AbstractRoleCYJ
{
public:
    virtual void RoleName() = 0;
};

//抽象的王者榮耀后羿角色
class AbstractRoleHY
{
public:
    virtual void RoleName() = 0;
};

//抽象的王者榮耀曹操角色
class AbstractRoleCC
{
public:
    virtual void RoleName() = 0;
};

//我方的程咬金
class MyCYJ : public AbstractRoleCYJ
{
public:
    virtual void RoleName()
    {
        cout << "我方的程咬金" << endl;
    }
};

//敵方的程咬金
class AnotherCYJ : public AbstractRoleCYJ
{
public:
    virtual void RoleName()
    {
        cout << "敵方的程咬金" << endl;
    }
};


//我方的后羿
class MyHY : public AbstractRoleHY
{
public:
    virtual void RoleName()
    {
        cout << "我方的后羿" << endl;
    }
};

//敵方的后羿
class AnotherHY : public AbstractRoleHY
{
public:
    virtual void RoleName()
    {
        cout << "敵方的后羿" << endl;
    }
};

//我方的曹操
class MyCC : public AbstractRoleCC
{
public:
    virtual void RoleName()
    {
        cout << "我方的曹操" << endl;
    }
};

//敵方的曹操
class AnotherCC : public AbstractRoleCC
{
public:
    virtual void RoleName()
    {
        cout << "敵方的曹操" << endl;
    }
};

//抽象工廠
class AbstractFactory
{
public:
    virtual AbstractRoleCYJ* CreateCYJ() = 0;
    virtual AbstractRoleHY* CreateHY() = 0;
    virtual AbstractRoleCC* CreateCC() = 0;
};

//我方的工廠
class MYFactory : public AbstractFactory
{
public:
    virtual AbstractRoleCYJ* CreateCYJ()
    {
        return new MyCYJ;
    }

    virtual AbstractRoleHY* CreateHY()
    {
        return new MyHY;
    }

    virtual AbstractRoleCC* CreateCC()
    {
        return new MyCC;
    }
};

//敵方的工廠
class AnotherFactory : public AbstractFactory
{
public:
    virtual AbstractRoleCYJ* CreateCYJ()
    {
        return new AnotherCYJ;
    }

    virtual AbstractRoleHY* CreateHY()
    {
        return new AnotherHY;
    }

    virtual AbstractRoleCC* CreateCC()
    {
        return new AnotherCC;
    }
};

int main()
{
    AbstractFactory *f = NULL;
    AbstractRoleCYJ *cyj = NULL;
    AbstractRoleHY *hy = NULL;
    AbstractRoleCC *cc = NULL;

    f = new MYFactory();
    cyj = f->CreateCYJ();
    hy = f->CreateHY();
    cc = f->CreateCC();

    cyj->RoleName();
    hy->RoleName();
    cc->RoleName();

    delete cyj;
    delete hy;
    delete cc;

    f = new AnotherFactory();
    cyj = f->CreateCYJ();
    hy = f->CreateHY();
    cc = f->CreateCC();

    cyj->RoleName();
    hy->RoleName();
    cc->RoleName();

    delete cyj;
    delete hy;
    delete cc;
    delete f;

    system("pause");
    return 0;
}

2).抽象工廠模式的優缺點以及適用場景

優點:

擁有工廠模式方法的優點
當一個產品族中的多個物件被設計成一起工作的時候,能夠保證客戶端始終只使用一個產品族中的物件
符合開閉原則 

缺點:

增加新產品等級結構時,需要改原始碼,違反開閉原則

適用場景:

擁有等級結構設計的系統