设计模式学习(二) 简单工厂模式

今天我学习了一下简单工厂模式,其实简单工厂模式并不被包含于GoF 23种设计模式中,但也是会被频繁的使用在开发中,而且也算是其它工厂模式学习的入门吧。

首先,我想通过一个例子,引入今天的主题。如果我要设计一个学校职工信息管理系统,我要向服务器请求老师、学生、和其他工作人员的基本信息,那我们应该会如何进行设计呢?在不了解各种面向对象设计模式的时候,我们很容易想到的一种方法就是,先定义三个类分别是Student类、Teacher类、Other类,这三个类中分别存放了不同的对应相应类的属性。然后定义一个People类用来继承前面定义的三个类,并在其中加入一个classType来帮助返回我要请求的类中的数据。于是我们很容易写出了如下代码:

class People: public Student,public Teacher,public Other
{
private:
	string type;
public:
	People(string myType)
	{
		this->type = myType;
		switch(this->type)
		{
		case "Student":{
		//初始化学生信息
		}break;
		case "Teacher":{
		//初始化教师信息
		}break;
		case "Other":{
		//初始化其他员工信息
		}break;
		default:break;
		}
	}
	
	void display()
	{
		if(this->type == "Student")
		{
			//输出学生信息
		}
		else if(this->type == "Teacher")
		{
			//输出教师信息
		}
		else if(this->type == "Other")
		{
			//输出其他员工信息
		}
	}
}

毫无疑问,这个类是可以达到我们所需要达到的目的的,但是我们对照面向对象的设计原则,我们还是发现了许多问题:

1、People类的职责太重了,同时要完成所有的初始化和打印两方面功能,违反了单一职责原则。

2、如果我今后要扩充功能,加入行政人员的资料查询,那么我还将要重新修改代码,将类中的if/else判断再加上一句,增加了添加模块的难度,违反了开闭原则。

3、客户只能用new关键字来创建对象,类和客户端的耦合程度太高。


OK!那就上面三点,我们可以使用简单工厂模式进行怎样的改进呢?

首先,我们要了解,简单工厂模式中的三个角色:

(1)工厂角色:这是该模式的核心部分,负责创建所有产品(对象),同时工厂可以被外界直接调用,创建所需产品的对象。

(2)抽象产品角色:工厂类所创建所有产品(对象)的父类,封装了所有产品的公有方法,用于提高系统的灵活性。

(3)具体产品角色:该模式的创建目标,由他创建对象都是某个具体类的实例(ps:结合上面的例子,就可以理解为Student类、Teacher类、Other类,他们都包含自己特有的属性)


那么,接下来我们就要开始实现了!!

第一步是抽象产品角色,我们要实现的功能是打印功能,因此,我们就需要一个只有display()功能的类,记住要是一个虚基类,因为作为一个接口类,我不需要在类中实现功能。

第二步要开始写我们的具体产品角色了,每个类中的属性有所不同,但是要记住的是:一定要公有继承,抽象产品类,并在自己类中写display()函数。

第三步,也是最重要的一步,我们要在工厂类中,做出逻辑判断,写一个静态函数,通过传进的参数来判断是要请求哪种产品(即Student\Teacher\Other)的参数。


下面给出我写的一个模板的代码(我并没有实现我之前举得例子,因为我学的时候,并没有用这个例子写代码)


/*
 * class.h
 *
 *  Created on: 2014-3-20
 *      Author: linux
 */

#ifndef CLASS_H_
#define CLASS_H_

#include <iostream>

class DisplayInterface
{
public:
	virtual void Display(){

	};
};

class ClassA :public DisplayInterface
{
public:
	ClassA(){
		std::cout<<"create class A"<<std::endl;
	}
	~ClassA(){

	}
	virtual void Display();
};

class ClassB :public DisplayInterface
{
public:
	ClassB(){
		std::cout<<"create class B"<<std::endl;
	}
	~ClassB(){

	}
	virtual void Display();
};

class ClassC :public DisplayInterface
{
public:
	ClassC(){
		std::cout<<"create class C"<<std::endl;
	}
	~ClassC(){

	}
	virtual void Display();
};

void ClassA::Display(){
	std::cout<<"display class A"<<std::endl;
}

void ClassB::Display(){
	std::cout<<"display class B"<<std::endl;
}

void ClassC::Display(){
	std::cout<<"display class C"<<std::endl;
}


class SimpleFactory
{
public:
	static DisplayInterface* getClass(int type) {
		DisplayInterface* classPtr = nullptr;
		switch(type)
		{
		case 1:classPtr = new ClassA;break;
		case 2:classPtr = new ClassB;break;
		case 3:classPtr = new ClassC;break;
		}
		return classPtr;
	}
};
#endif /* CLASS_H_ */

主函数的代码如下


#include <iostream>
#include "class.h"
using namespace std;

int main()
{
	DisplayInterface* ptr = SimpleFactory::getClass(1);
	ptr->Display();
	ptr = SimpleFactory::getClass(2);
	ptr->Display();
	ptr = SimpleFactory::getClass(3);
	ptr->Display();
}


当然简单工厂模式还是可以简化的,就是将抽象产品角色和工厂合并带一个类中。这个读者自己可以尝试一下。


最后介绍的是适用场景:

1、工厂类创建的对象比较少,以免工厂类太过于繁琐

2、客户端只需要知道往工厂传入参数,而并不需要关心对象时如何创建的。


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值