设计模式学习笔记(三)—抽象工厂模式
-
概念
抽象工厂模式是所有形态的工厂模式中最为抽象和最具一般性的一种形态。抽象工厂模式是指当有多个抽象角色时,使用的一种工厂模式。抽象工厂模式可以向客户端提供一个接口,使客户端在不必指定产品的具体的情况下,创建多个产品族中的产品对象。根据里氏替换原则,任何接受父类型的地方,都应当能够接受子类型。因此,实际上系统所需要的,仅仅是类型与这些抽象产品角色相同的一些实例,而不是这些抽象产品的实例。换言之,也就是这些抽象产品的具体子类的实例。工厂类负责创建抽象产品的具体子类的实例。
-
优缺点
优点:
1、抽象工厂模式隔离了具体类的生产,客户不需要知道什么被创建。
2、当一个产品族中的多个对象被设计成一起工作时,它能保证客户端始终只使用同一个产品族中的对象,不会造成混淆和混乱。
3、增加新的具体工厂和具体产品的时候会十分方便,不需要修改现有的代码,符合“开闭原则”。
缺点:
增加新的产品等级结构很复杂,需要修改抽象工厂和所有的具体工厂类,对“开闭原则”的支持呈现倾斜性。
-
实现
下面我们通过一个例子来说明抽象工厂模式。
说明:
很多游戏里面都有符文系统,像我们经常玩的英雄联盟里面,就是红色,蓝色和黄色的三种符文,然后每种符文又有一级、二级、三级三个等级。我们现在就针对这个来写抽象工厂模式的例子的代码。这里我们只对应红色符文和蓝色符文两种。首先是两个接口类:IRedMark,IBlueMark。然后是具体实现类,实现一级二级三级符文各自的属性,分别为FirstLevelRed,SecondLevelRed,ThirdLevelRed,FirstLevelBlue,SecondLevelBlue,ThirdLevelBlue。然后我们建立一个抽象工厂的接口类IMarkFactory,再然后就是具体的抽象工厂类,FirstLevelFactory,SecondLevelFactory,ThirdLevelFactory。
类图:
实现代码:
// IRedMark.h #pragma once class IRedMark { public: IRedMark(void); virtual ~IRedMark(void); virtual void AddPhysicalDamage() = 0; }; // IRedMark.cpp #include "StdAfx.h" #include "IRedMark.h" IRedMark::IRedMark(void) { } IRedMark::~IRedMark(void) { } // FirstLevelRed.h #pragma once #include "IRedMark.h" class CFirstLevelRed : public IRedMark { public: CFirstLevelRed(void); virtual ~CFirstLevelRed(void); virtual void AddPhysicalDamage(); }; // FirstLevelRed.cpp #include "StdAfx.h" #include "FirstLevelRed.h" CFirstLevelRed::CFirstLevelRed(void) { } CFirstLevelRed::~CFirstLevelRed(void) { } void CFirstLevelRed::AddPhysicalDamage() { printf("Physical Damage +10\n"); } // SecondLevelRed.h #pragma once #include "IRedMark.h" class CSecondLevelRed : public IRedMark { public: CSecondLevelRed(void); virtual ~CSecondLevelRed(void); virtual void AddPhysicalDamage(); }; // SecondLevelRed.cpp #include "StdAfx.h" #include "SecondLevelRed.h" CSecondLevelRed::CSecondLevelRed(void) { } CSecondLevelRed::~CSecondLevelRed(void) { } void CSecondLevelRed::AddPhysicalDamage() { printf("Physical Damage +20\n"); } // ThirdLevelRed.h #pragma once #include "IRedMark.h" class CThirdLevelRed : public IRedMark { public: CThirdLevelRed(void); virtual ~CThirdLevelRed(void); virtual void AddPhysicalDamage(); }; // ThirdLevelRed.cpp #include "StdAfx.h" #include "ThirdLevelRed.h" CThirdLevelRed::CThirdLevelRed(void) { } CThirdLevelRed::~CThirdLevelRed(void) { } void CThirdLevelRed::AddPhysicalDamage() { printf("Physical Damage +30\n"); } // IBlueMark.h #pragma once class IBlueMark { public: IBlueMark(void); virtual ~IBlueMark(void); virtual void AddSpellDamage() = 0; }; // IBlueMark.cpp #include "StdAfx.h" #include "IBlueMark.h" IBlueMark::IBlueMark(void) { } IBlueMark::~IBlueMark(void) { } // FirstLevelBlue.h #pragma once #include "IBlueMark.h" class CFirstLevelBlue : public IBlueMark { public: CFirstLevelBlue(void); virtual ~CFirstLevelBlue(void); virtual void AddSpellDamage(); }; // FirstLevelBlue.cpp #include "StdAfx.h" #include "FirstLevelBlue.h" CFirstLevelBlue::CFirstLevelBlue(void) { } CFirstLevelBlue::~CFirstLevelBlue(void) { } void CFirstLevelBlue::AddSpellDamage() { printf("Spell Damage +10\n"); } // SecondLevelBlue.h #pragma once #include "IBlueMark.h" class CSecondLevelBlue : public IBlueMark { public: CSecondLevelBlue(void); virtual ~CSecondLevelBlue(void); virtual void AddSpellDamage(); }; // SecondLevelBlue.cpp #include "StdAfx.h" #include "SecondLevelBlue.h" CSecondLevelBlue::CSecondLevelBlue(void) { } CSecondLevelBlue::~CSecondLevelBlue(void) { } void CSecondLevelBlue::AddSpellDamage() { printf("Spell Damage +20\n"); } // ThirdLevelBlue.h #pragma once #include "IBlueMark.h" class CThirdLevelBlue : public IBlueMark { public: CThirdLevelBlue(void); virtual ~CThirdLevelBlue(void); virtual void AddSpellDamage(); }; // ThirdLevelBlue.cpp #include "StdAfx.h" #include "ThirdLevelBlue.h" CThirdLevelBlue::CThirdLevelBlue(void) { } CThirdLevelBlue::~CThirdLevelBlue(void) { } void CThirdLevelBlue::AddSpellDamage() { printf("Spell Damage +30\n"); } // IMarkFactory.h #pragma once #include "IRedMark.h" #include "IBlueMark.h" class IMarkFactory { public: IMarkFactory(void); virtual ~IMarkFactory(void); virtual IRedMark* CreateRedMark() = 0; virtual IBlueMark* CreateBlueMark() = 0; }; // IMarkFactory.cpp #include "StdAfx.h" #include "IMarkFactory.h" IMarkFactory::IMarkFactory(void) { } IMarkFactory::~IMarkFactory(void) { } // FirstLevelFactory.h #pragma once #include "IMarkFactory.h" class CFirstLevelFactory : public IMarkFactory { public: CFirstLevelFactory(void); virtual ~CFirstLevelFactory(void); virtual IRedMark* CreateRedMark(); virtual IBlueMark* CreateBlueMark(); }; // FirstLevelFactory.cpp #include "StdAfx.h" #include "FirstLevelFactory.h" #include "FirstLevelRed.h" #include "FirstLevelBlue.h" CFirstLevelFactory::CFirstLevelFactory(void) { } CFirstLevelFactory::~CFirstLevelFactory(void) { } IRedMark* CFirstLevelFactory::CreateRedMark() { return new CFirstLevelRed(); } IBlueMark* CFirstLevelFactory::CreateBlueMark() { return new CFirstLevelBlue(); } // SecondLevelFactory.h #pragma once #include "IMarkFactory.h" class CSecondLevelFactory : public IMarkFactory { public: CSecondLevelFactory(void); ~CSecondLevelFactory(void); virtual IRedMark* CreateRedMark(); virtual IBlueMark* CreateBlueMark(); }; // SecondLevelFactory.cpp #include "StdAfx.h" #include "SecondLevelFactory.h" #include "SecondLevelRed.h" #include "SecondLevelBlue.h" CSecondLevelFactory::CSecondLevelFactory(void) { } CSecondLevelFactory::~CSecondLevelFactory(void) { } IRedMark* CSecondLevelFactory::CreateRedMark() { return new CSecondLevelRed(); } IBlueMark* CSecondLevelFactory::CreateBlueMark() { return new CSecondLevelBlue(); } // ThirdLevelFactory.h #pragma once #include "IMarkFactory.h" class CThirdLevelFactory : public IMarkFactory { public: CThirdLevelFactory(void); virtual ~CThirdLevelFactory(void); virtual IRedMark* CreateRedMark(); virtual IBlueMark* CreateBlueMark(); }; // ThirdLevelFactory.cpp #include "StdAfx.h" #include "ThirdLevelFactory.h" #include "ThirdLevelRed.h" #include "ThirdLevelBlue.h" CThirdLevelFactory::CThirdLevelFactory(void) { } CThirdLevelFactory::~CThirdLevelFactory(void) { } IRedMark* CThirdLevelFactory::CreateRedMark() { return new CThirdLevelRed(); } IBlueMark* CThirdLevelFactory::CreateBlueMark() { return new CThirdLevelBlue(); } // main #include "stdafx.h" #include "stdlib.h" #include "IMarkFactory.h" #include "IRedMark.h" #include "IBlueMark.h" #include "FirstLevelFactory.h" #include "FirstLevelRed.h" #include "FirstLevelBlue.h" #include "SecondLevelFactory.h" #include "SecondLevelRed.h" #include "SecondLevelBlue.h" #include "ThirdLevelFactory.h" #include "ThirdLevelRed.h" #include "ThirdLevelBlue.h" void TestFirstLevel() { IMarkFactory *markFactory = new CFirstLevelFactory(); IRedMark *redMark = markFactory->CreateRedMark(); IBlueMark *blueMark = markFactory->CreateBlueMark(); redMark->AddPhysicalDamage(); blueMark->AddSpellDamage(); delete blueMark; delete redMark; delete markFactory; } void TestSecondLevel() { IMarkFactory *markFactory = new CSecondLevelFactory(); IRedMark *redMark = markFactory->CreateRedMark(); IBlueMark *blueMark = markFactory->CreateBlueMark(); redMark->AddPhysicalDamage(); blueMark->AddSpellDamage(); delete blueMark; delete redMark; delete markFactory; } void TestThirdLevel() { IMarkFactory *markFactory = new CThirdLevelFactory(); IRedMark *redMark = markFactory->CreateRedMark(); IBlueMark *blueMark = markFactory->CreateBlueMark(); redMark->AddPhysicalDamage(); blueMark->AddSpellDamage(); delete blueMark; delete redMark; delete markFactory; } int _tmain(int argc, _TCHAR* argv[]) { printf("----------------\n"); TestFirstLevel(); printf("----------------\n"); TestSecondLevel(); printf("----------------\n"); TestThirdLevel(); printf("----------------\n"); system("pause"); return 0; }
下面是运行的结果: