工厂方法模式
理论
工厂方法模式:定义一个用于创建对象的接口,让子类决定实例化哪一个类。工厂方法使一个类的实例化延迟到起子类。
简单工厂 VS 工厂方法
相同点:它们都是集中封装了对象的创建,使得要更换对象时,不需要做大的改动就可以实现,降低了客户程序与产品对象的耦合。
简单工厂模式
优点:在于工厂类中包含了必要的逻辑判断,根据客户端的选择条件动态实例化相关的类,对于客户端来说,去除了与具体产品的依赖。
缺点:如果需要加一个新的功能,需要在工厂类的方法里添加Case的分支条件,违背了开放-封闭原则。
工厂方法模式
优点:是简单工厂模式的进一步抽象和推广,克服了简单工厂违背开放-封闭原则的缺点,又保持了封装对象创建过程的优点
缺点:每增加一个产品,需要加一个产品工厂的类,增加了额外的开发量。
工厂方法模式实现时,客户端需要决定实例化哪一个工厂来实现运算类,选择判断的问题还是存在。也就是说,工厂方法把简单工厂的内部逻辑判断移到了客户端代码来进行。
实例1
用任意一种面向对象语言实现一个计算器控制台程序
UML类图
简单工厂模式
工厂方法模式
实现代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 | #include <iostream> #include <string> using namespace std; //抽象运算类 class Operation{ public : void GetNumber( int num1, int num2) { number_A = num1; number_B = num2; } virtual int GetResult() = 0; protected : int number_A = 0; int number_B = 0; }; //具体运算类 class OperationAdd : public Operation{ public : int GetResult() { return number_A + number_B; } }; class OperationSub : public Operation{ public : int GetResult() { return number_A - number_B; } }; class OperationMul : public Operation{ public : int GetResult() { return number_A * number_B; } }; class OperationDiv : public Operation{ public : int GetResult() { if (number_B == 0) { cout << "除数不能为0" << endl; exit (0); } return number_A / number_B; } }; //简单工厂类 class OperationFactory { public : static Operation* cerateOperate( char operate) { switch (operate) { case ( '+' ): return new OperationAdd; case ( '-' ): return new OperationSub; case ( '*' ): return new OperationMul; case ( '/' ): return new OperationDiv; default : break ; } } }; //抽象运算工厂类-->开闭原则: 对扩展开发,对修改关闭!! class AbstractFactory { public : virtual Operation* cerateOperate() = 0; }; //加法类工厂 class AddFactory : public AbstractFactory { public : Operation* cerateOperate() { return new OperationAdd(); } }; //减法类工厂 class SubFactory : public AbstractFactory { public : Operation* cerateOperate() { return new OperationSub(); } }; //乘法类工厂 class MulFactory : public AbstractFactory { public : Operation* cerateOperate() { return new OperationMul(); } }; //除法类工厂 class DivFactory : public AbstractFactory { public : Operation* cerateOperate() { return new OperationDiv(); } }; //客户端 void test01() { int num1 = 5; int num2 = 2; int result = 0; OperationFactory factory; Operation* operate = factory.cerateOperate( '-' ); operate->GetNumber(num1, num2); result = operate->GetResult(); cout << "num1 - num2 = " << result << endl; delete operate; } void test02() { int num1 = 1; int num2 = 2; int result = 0; AbstractFactory* factory = new AddFactory(); Operation* operate = factory->cerateOperate(); operate->GetNumber(num1, num2); result = operate->GetResult(); cout << "num1 + num2 = " << result << endl; delete operate; delete factory; } int main() { test01(); test02(); system ( "pause" ); return 0; } |
实例2
学生/志愿者 以雷锋的名义做好事
实现代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 | #include <iostream> using namespace std; //“雷锋”类 class Leifeng { public : void Sweep() { cout << "扫地" << endl; } void Wash() { cout << "洗衣" << endl; } void BuyRice() { cout << "买米" << endl; } }; //“学雷锋的大学生”类 class Undergraduate : public Leifeng {}; //“学雷锋的志愿者”类 class Volunteer : public Leifeng {}; //简单工厂类 class SimpleFactory { public : static Leifeng* CreateLeifeng( int people) { Leifeng* result = NULL; switch (people) { case (1): result = new Undergraduate(); break ; case (2): result = new Volunteer(); break ; } return result; } }; /*工厂方法模式*/ //雷锋工厂 class IFactory { public : virtual Leifeng* CreatLeifeng() = 0; }; //学雷锋的大学生工厂 class UndergraduateFactory : public IFactory{ public : Leifeng* CreatLeifeng() { return new Undergraduate(); } }; //社区志愿者工厂 class VolunteerFactory : public IFactory { public : Leifeng* CreateLeifeng() { return new Volunteer(); } }; void test01() { //简单工厂模式 Leifeng* studentA = SimpleFactory::CreateLeifeng(1); //三句重复的代码 studentA->BuyRice(); Leifeng* studentB = SimpleFactory::CreateLeifeng(1); studentB->Sweep(); Leifeng* studentC = SimpleFactory::CreateLeifeng(1); studentC->Wash(); } void test02() { //工厂方法模式 IFactory* factory = new UndergraduateFactory(); //如果要换成社区志愿者类只需修改此处 Leifeng* studentA = factory->CreatLeifeng(); Leifeng* studentB = factory->CreatLeifeng(); Leifeng* studentC = factory->CreatLeifeng(); studentA->BuyRice(); studentB->Sweep(); studentC->Wash(); delete factory; delete studentA; delete studentB; delete studentC; } int main() { test01(); cout << "---------------------" << endl; test02(); system ( "pause" ); return 0; } |
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧