简单工厂模式

简单工厂模式

模式定义

又称静态工厂模式,简单工厂模式专门定义一个类来负责创建其他类的实例,被创建的实例通常都具有共同的父类

模式结构

1.Factory(工厂角色)
提供了静态的工厂方法factoryMethod(),它返回一个抽象产品类Product
,所有的具体产品都是其子类对象
2. Product(抽象产品角色)
抽象产品角色是简单工厂模式所创建的所有的对象的父类,负责描述所有实例所共有的公共接口,它的引入提高了系统的灵活性,使得在工厂类里只需定义一个工厂方法,因为所有的具体产品对象都是其子类
3. ConcreteProduct(具体产品角色)
具体产品角色是简单工厂模式的创建目标,每一个具体产品角色都继承了抽象产品角色,需要实现定义在抽象产品类中的抽象方法
在这里插入图片描述
图片来源此处

实例与解析

1.实例说明
某电视机厂生产各类电视机,当需要海尔牌电视机时只需在调用该工厂的工厂方法时传入参数Haier,需要海信电视机…,工厂可以根据传入的不同参数返回不同品牌的电视机。现使用简单工厂模式模式该电视机工厂的生产过程。
2.类图
在这里插入图片描述
3.代码及解释
(1)抽象产品类TV

class TV(ABC):
	@abstractclassmethond
	def play(self):
		pass

TV作为抽象产品类,它可以是一个抽象类也可以是一个接口,其中包含了所有产品具有的业务方法play()

(2)具体产品类HaierTV

class HaierTV(TV):
	'''具体产品类'''
	def play(self):
		print('海尔电视播放中')

HaierTV是抽象产品TV的子类,它实现了父类的抽象方法play()

(3)具体产品类HisenseTV

class HisenseTV(TV):
	'''具体产品类'''
	def play(self):
		print('海信电视播放中')

与具体产品类HaierTV类似

(4)工厂类TVFactory

class TVFactory:
	'''工厂类'''
	@staticmethod
	def produceTV(band):
		if(band == 'Haier'):
			print('生产海尔电视机')
			return HaierTV()
		elif(brand == 'Hisense'):
			print('生产海信电视机')
			return HisenseTV()
		else:
			print('对不起,暂时不能生产该品牌的电视机')

TVFactory工厂类,是整个系统的核心,提供了静态工厂方法produceTV(),根据参数值band的不同值实例化不同的具体产品类,返回对应的对象
扩展
Python 使用装饰器@staticmethod来定义一个静态方法。转自文章
(5)测试

#测试
tv = TVFactory.produceTV('Haier')
tv.play()

结果如下
在这里插入图片描述
书上还有一个实例,在这不多分析

模式优缺点

1.优点
(1)工厂类含有必要的判断逻辑,可以决定在说明时候创建哪一个产品的实例,客户端可以免除直接创建产品对象的责任,实现了对责任的分割,提供专门的工厂类创建对象
(2)客户端无须知道所创建的具体产品类的类名,只需要知道具体产品对应的参数
2.缺点
(1)由于工厂类集中了所有产品的创建逻辑,一旦不能正常工作,整个系统都要受到影响
(2)使用简单工厂模式会增加系统中类的个数,增加了系统的复杂度
(3)系统扩展困难,一旦添加新产品就不得不修改工厂逻辑
(4)由于使用了静态工厂方法,造成工厂角色无法形成基于继承的等级结构,也就是说,虽然子类可以继承和覆盖父类的静态方法,但是如果在定义时使用的是父类,即使实例化的是子类也无法访问子类覆盖后的静态方法。

模式适用环境

  • 工厂类负责创建的对象比较少
  • 客户端只知道传入工厂类的参数(具体产品类对应的参数),对于如何创建对象不关心

模式应用

1.JDK类库中广泛使用简单工厂模式:
工具类java.text.DateFormat中的getDateInstance()方法是一个静态工厂方法
2.Java加密技术中密钥的生成的密码器的创建
javax.crypto.KeyGenerator和java.security.KeyPairGenerator类都有一个名为getInstance()的静态工厂方法,根据传入参数得到不同的密钥生成器,不同类型密码器的创建也是通过向静态工厂方法传入的参数决定

模式扩展

  • 在有些情况下工厂类可以由抽象产品类扮演,即一个抽象产品类同时也是子类的工厂,也就是说静态工厂方法写到了抽象产品类中
  • 一些情况下,工厂、抽象产品和具体产品三者可以合并,如密码器的创建
//创建密码器
Cipher cp = Cipher.getInstance("DESede");

小结

1.创建型模式对类的实例化过程进行了抽象,能够将对象的创建与对象的使用过程分离
2.简单工厂模式又称为静态工厂方法模式,它属于类创建型模式。在简单工厂模式中,可以根据参数的不同返回不同类的实例。简单工厂模式定义一个类专门负责创建其他类的实例,被创建的实例通常都具有共同的父类

  • 简单工厂模式包含的三个角色和各自的职责
  • 简单工厂模式的优点和缺点
  • 简单工厂模式的适用情况

实验

问题描述
现需要开发一个绘图程序,用来绘制简单的几何图形,这个软件能够处理以下几何对象:圆形(Circle)、矩形(Rectangle)、正方形(Square)。除了各自特有的属性和方法之外,所有的几何图形都可以抽象出绘制(draw)和擦除(erase)两个公共方法。
问题分析
UML图
在这里插入图片描述设计代码

  • 抽象产品类Shape
class Shape:
    '''定义所有几何图形都必须实现的公共方法'''
    def draw(self):
        '''绘制图形'''
        pass
    def erase(self):
        '''擦除图形'''
        pass
  • 具体产品类Rectangle
class Rectangle(Shape):
    '''矩形'''
    def __init__(self,height = 0,width = 0):
        '''初始化'''
        self.height = height
        self.width = width
    def draw(self):
        '''绘制矩形'''
        print("draw rectangle")
    def erase(self):
        '''擦除矩形'''
        print("erase rectangle")
    #矩形长宽的获取和设置方法
    def getWidth(self):
        return self.width   
    def getHeight(self):
        return self.height
    def setWidth(self,width):
        self.width = width
    def setHeight(self,height):
        self.height = height
  • 具体产品类Circle
class Circle(Shape):
    '''shape的具体形式circle'''
    
    def __init__(self,raidus = 0):
        self.radius = raidus
    
    def draw(self):
        '''绘制圆形'''
        print("draw circle")
    
    def erase(self):
        '''擦除圆形'''
        print("erase circle")
    
    def getRadius(self):
        '''获取圆的半径'''
        return self.radius

    def setRadius(self,radius):
        '''设置圆的半径'''
        self.radius = radius   
  • 具体产品类Square
class Square(Shape):
    '''正方形'''

    def __init__(self,side = 0):
        '''初始化,默认正方形边长为0'''
        self.side = side
    
    def draw(self):
        '''绘制正方形'''
        print('draw square')
    
    def erase(self):
        '''擦除正方形'''
        print('erase square')
    
    def getSide(self):
        return self.side
    
    def setSide(self,side):
        self.side = side
  • 工厂类ShapeFactory
class ShapeFactory:
    '''shape的工厂类,用于创建各种形状类的实例'''
    @staticmethod
    def create(which):
        '''根据which返回对应类'''
        if which == 'Circle':
            return Circle()
        elif which == 'Rectangle':
            return Rectangle()
        elif which == 'Square':
            return Square()
        else: return None
  • 测试代码
shape = ShapeFactory.create('Circle')
shape.draw()
shape.erase()
  • 结果如下
    在这里插入图片描述
  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值