在工厂模式的基础上,通过为工厂类增加接口,实现其他产品的生产,而不用一类产品就增加一个工厂。
依然以《真菌世界》游戏故事类比,树作为工厂,如果现在有两类树,一类生产快速弄真菌飞机和20毫米炮,一类生产慢速弄真菌飞机和10毫米炮。
产品类:
真菌飞机接口
IFungus.h
1 #pragma once 2 class IFungus 3 { 4 public: 5 IFungus(void); 6 virtual ~IFungus(void); 7 public: 8 virtual void Fight()=0; 9 };
IFungus.cpp
1 #include "IFungus.h" 2 3 4 IFungus::IFungus(void) 5 { 6 } 7 8 9 IFungus::~IFungus(void) 10 { 11 }
真菌飞机A
FungusA.h
1 #pragma once 2 #include "ifungus.h" 3 class CFungusA : 4 public IFungus 5 { 6 public: 7 CFungusA(void); 8 ~CFungusA(void); 9 public: 10 void Fight(); 11 };
FungusA.cpp
1 #include "FungusA.h" 2 #include <iostream> 3 4 CFungusA::CFungusA(void) 5 { 6 } 7 8 9 CFungusA::~CFungusA(void) 10 { 11 } 12 13 void CFungusA::Fight() 14 { 15 std::cout<<"快速攻击型"<<std::endl; 16 }
真菌飞机B
FungusB.h
1 #pragma once 2 #include "ifungus.h" 3 class CFungusB : 4 public IFungus 5 { 6 public: 7 CFungusB(void); 8 ~CFungusB(void); 9 public: 10 void Fight(); 11 };
FungusB.cpp
1 #include "FungusB.h" 2 #include <iostream> 3 4 CFungusB::CFungusB(void) 5 { 6 } 7 8 9 CFungusB::~CFungusB(void) 10 { 11 } 12 13 void CFungusB::Fight() 14 { 15 std::cout<<"慢慢攻击型"<<std::endl; 16 }
炮接口
ICannon.h
1 #pragma once 2 class ICannon 3 { 4 public: 5 ICannon(void); 6 virtual ~ICannon(void); 7 public: 8 virtual void Fire() = 0; 9 };
ICannon.cpp
1 #include "ICannon.h" 2 3 4 ICannon::ICannon(void) 5 { 6 } 7 8 9 ICannon::~ICannon(void) 10 { 11 }
炮A
CannonA.h
1 #pragma once 2 #include "icannon.h" 3 class CCannonA : 4 public ICannon 5 { 6 public: 7 CCannonA(void); 8 ~CCannonA(void); 9 public: 10 void Fire(); 11 };
CannonA.cpp
1 #include "CannonA.h" 2 #include <iostream> 3 4 CCannonA::CCannonA(void) 5 { 6 } 7 8 9 CCannonA::~CCannonA(void) 10 { 11 } 12 13 void CCannonA::Fire() 14 { 15 std::cout<<"使用10毫米弹"<<std::endl; 16 }
炮B
CannonB.h
1 #pragma once 2 #include "icannon.h" 3 class CCannonB : 4 public ICannon 5 { 6 public: 7 CCannonB(void); 8 ~CCannonB(void); 9 public: 10 void Fire(); 11 };
CannonB.cpp
1 #include "CannonB.h" 2 #include <iostream> 3 4 CCannonB::CCannonB(void) 5 { 6 } 7 8 9 CCannonB::~CCannonB(void) 10 { 11 } 12 13 void CCannonB::Fire() 14 { 15 std::cout<<"使用20毫米弹"<<std::endl; 16 }
工厂类:
树接口
ITree.h
1 #pragma once 2 #include "IFungus.h" 3 #include "ICannon.h" 4 5 class ITree 6 { 7 public: 8 ITree(void); 9 virtual ~ITree(void); 10 public: 11 virtual IFungus* GetFungus() = 0; 12 virtual ICannon* GetCannon() = 0; 13 };
ITree.cpp
1 #include "ITree.h" 2 3 4 ITree::ITree(void) 5 { 6 } 7 8 9 ITree::~ITree(void) 10 { 11 }
树A
TreeA.h
1 #pragma once 2 #include "itree.h" 3 class CTreeA : 4 public ITree 5 { 6 public: 7 CTreeA(void); 8 ~CTreeA(void); 9 public: 10 IFungus* GetFungus(); 11 ICannon* GetCannon(); 12 };
TreeB.cpp
1 #include "TreeA.h" 2 #include "FungusA.h" 3 #include "CannonB.h"; 4 5 CTreeA::CTreeA(void) 6 { 7 } 8 9 10 CTreeA::~CTreeA(void) 11 { 12 } 13 14 IFungus* CTreeA::GetFungus() 15 { 16 return new CFungusA(); 17 } 18 19 ICannon* CTreeA::GetCannon() 20 { 21 return new CCannonB(); 22 }
树B
TreeB.h
1 #pragma once 2 #include "itree.h" 3 class CTreeB : 4 public ITree 5 { 6 public: 7 CTreeB(void); 8 ~CTreeB(void); 9 public: 10 IFungus* GetFungus(); 11 ICannon* GetCannon(); 12 };
TreeB.cpp
1 #include "TreeB.h" 2 #include "FungusB.h" 3 #include "CannonA.h" 4 5 CTreeB::CTreeB(void) 6 { 7 } 8 9 10 CTreeB::~CTreeB(void) 11 { 12 } 13 14 IFungus* CTreeB::GetFungus() 15 { 16 return new CFungusB(); 17 } 18 19 ICannon* CTreeB::GetCannon() 20 { 21 return new CCannonA(); 22 }
场景
main.cpp
1 #include "ITree.h" 2 #include "TreeA.h" 3 #include "TreeB.h" 4 5 int main() 6 { 7 ITree* pTreeA = new CTreeA(); 8 ITree* pTreeB = new CTreeB(); 9 10 pTreeA->GetFungus()->Fight(); 11 pTreeA->GetCannon()->Fire(); 12 13 pTreeB->GetFungus()->Fight(); 14 pTreeB->GetCannon()->Fire(); 15 16 delete pTreeB; 17 delete pTreeA; 18 19 return 0; 20 }
如果又有了其他类型的真菌飞机和炮,我们扩展相应的类型,然后创立相应的工厂(树)进行组合生产就行了。
其实很想通过构造函数传参数,通过参数来决定生产的是什么,但是这样的话,总觉得侵入式方法破坏了工厂类的自主权,干涉了这种设计模式的目的:不用关心具体产品,只要知道哪个工厂生产什么就行。