工厂方法模式

理论

工厂方法模式:定义一个用于创建对象的接口,让子类决定实例化哪一个类。工厂方法使一个类的实例化延迟到起子类。

简单工厂 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;
}

  

posted @   KYZH  阅读(25)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
点击右上角即可分享
微信分享提示

目录导航