比较全面的单例模式和工厂模式

栏目: 后端 · 发布时间: 5年前

内容简介:概念工厂模式:工厂模式就是不管如何实现的,只需要调用抽象话的接口就可以创建出特定类型的实例对象简单工厂模式:

概念

工厂模式:工厂模式就是不管如何实现的,只需要调用抽象话的接口就可以创建出特定类型的实例对象

简单工厂模式:

eg:一个例子更能很好的理解以上的内容:

我们有一个基类Person ,包涵获取名字,性别的方法 。有两个子类male 和female,可以打招呼。还有一个工厂类。

工厂类有一个方法名getPerson有两个输入参数,名字和性别。

用户使用工厂类,通过调用getPerson方法。

在程序运行期间,用户传递性别给工厂,工厂创建一个与性别有关的对象。因此工厂类在运行期,决定了哪个对象应该被创建。

class Person:

def __init__(self):
    self.name = None
    self.gender = None

def getName(self):
    return self.name

def getGender(self):
    return self.gender

class Male(Person):

def __init__(self, name):
    print "Hello Mr." + name

class Female(Person):

def __init__(self, name):
    print "Hello Miss." + name

class Factory:

def getPerson(self, name, gender):
    if gender == ‘M':
            return Male(name)
        if gender == 'F':
        return Female(name)

if name == '__main__':

factory = Factory()
person = factory.getPerson("Chetan", "M")

抽象工厂模式:

提供一个创建一系列相关或相互依赖对象的接口,而无须指定它们具体的类。

class Burger():

"""
汉堡
"""
name=""
price=0.0
type='BURGER'
def getPrice(self):
    return self.price
def setPrice(self,price):
    self.price=price
def getName(self):
    return self.name

class CheeseBurger(Burger):

def __init__(self):
    self.name="cheese burger"
    self.price=10.0

class SpicyChickenBurger(Burger):

def __init__(self):
    self.name="spicy chicken burger"
    self.price=15.0

class Snack():

"""
小食类
"""
name = ""
price = 0.0
type = "SNACK"
def getPrice(self):
    return self.price
def setPrice(self, price):
    self.price = price
def getName(self):
    return self.name

class Chips(Snack):

def __init__(self):
    self.name = "chips"
    self.price = 6.0

class ChickenWings(Snack):

def __init__(self):
    self.name = "chicken wings"
    self.price = 12.0

class Beverage():

"""
饮料
"""
name = ""
price = 0.0
type = "BEVERAGE"
def getPrice(self):
    return self.price
def setPrice(self, price):
    self.price = price
def getName(self):
    return self.name

class Coke(Beverage):

def __init__(self):
    self.name = "coke"
    self.price = 4.0

class Milk(Beverage):

def __init__(self):
    self.name = "milk"
    self.price = 5.0

以上的Burger,Snack,Beverage,都可以认为是该快餐店的产品,由于只提供了抽象方法,我们把它们叫抽象产品类,而cheese burger等6个由抽象产品类衍生出的子类,叫作具体产品类。

class FoodFactory():

"""
抽象工厂foodFactory为抽象的工厂类,而burgerFactory,snackFactory,beverageFactory为具体的工厂类。
"""
type=""
def createFood(self,foodClass):
    print(self.type," factory produce a instance.")
    foodIns=foodClass()
    return foodIns

class BurgerFactory(foodFactory):

def __init__(self):
    self.type="BURGER"

class SnackFactory(foodFactory):

def __init__(self):
    self.type="SNACK"

class BeverageFactory(foodFactory):

def __init__(self):
    self.type="BEVERAGE"

if __name__=="__main__":

burger_factory=burgerFactory()
snack_factory=snackFactory()
beverage_factory=beverageFactory()
cheese_burger=burger_factory.createFood(cheeseBurger)
print(cheese_burger.getName(),cheese_burger.getPrice())
chicken_wings=snack_factory.createFood(chickenWings)
print(chicken_wings.getName(),chicken_wings.getPrice())
coke_drink=beverage_factory.createFood(coke)
print(coke_drink.getName(),coke_drink.getPrice())

工厂模式优点

工厂方法用来创建客户所需要的产品,同时还向客户隐藏了哪种具体产品类将被实例化这一细节 能够让工厂自主确定创建何种产品对象,而如何创建这个对象的细节则完全封装在具体工厂内部 在系统中加入新产品时,完全符合开闭原则

工厂模式缺点

系统中类的个数将成对增加,在一定程度上增加了系统的复杂度,会给系统带来一些额外的开销 增加了系统的抽象性和理解难度

工厂模式适用环境

客户端不知道它所需要的对象的类(客户端不需要知道具体产品类的类名,只需要知道所对应的工厂即可,具体产品对象由具体工厂类创建) 抽象工厂类通过其子类来指定创建哪个对象

抽象工厂模式:

模式优点

隔离了具体类的生成,使得客户端并不需要知道什么被创建 当一个产品族中的多个对象被设计成一起工作时,它能够保证客户端始终只使用同一个产品族中的对象 增加新的产品族很方便,无须修改已有系统,符合开闭原则

模式缺点

增加新的产品等级结构麻烦,需要对原有系统进行较大的修改,甚至需要修改抽象层代码,这显然会带来较大的不便,违背了开闭原则

模式适用环境

一个系统不应当依赖于产品类实例如何被创建、组合和表达的细节 系统中有多于一个的产品族,但每次只使用其中某一产品族 属于同一个产品族的产品将在一起使用,这一约束必须在系统的设计中体现出来 产品等级结构稳定,设计完成之后,不会向系统中增加新的产品等级结构或者删除已有的产品等级结构

单例模式

单例模式(Singleton Pattern)是一种常用的软件设计模式,该模式的主要目的是确保某一个类只有一个实例存在。当你希望在整个系统中,某个类只能出现一个实例时,单例对象就能派上用场。 eg:系统中的打印机

实现方式:

使用模块:

在mysingleton.py模块文件中:(因为模块在第一次导入时生成了.pyc文件,下次会直接从这个里面加载,不需要重新生成)

class Singleton:(object):

def foo(self):
   pass

singleton = Singeton()

在其他文件中调用:

from mysingleton import singleton

使用装饰器:

def Singleton(cls):

_instance = {}

def _singleton(*args, **kargs):

此处是核心代码

if cls not in _instance:
        _instance[cls] = cls(*args, **kargs)
    return _instance[cls]

此处是核心代码

return _singleton

@Singleton

class A(object):

a = 1

def __init__(self, x=0):
    self.x = x

a1 = A(2)

a2 = A(3)

print(id(a1))

print(id(a2))

使用类

import time

import threading

class Singleton(object):

_instance_lock = threading.Lock()

def __init__(self):
    time.sleep(1)

@classmethod
def instance(cls, *args, **kwargs):
    if not hasattr(Singleton, "_instance"):
        with Singleton._instance_lock:
            if not hasattr(Singleton, "_instance"):
                Singleton._instance = Singleton(*args, **kwargs)
    return Singleton._instance

def task(arg):

obj = Singleton.instance()
print(obj)

for i in range(10):

t = threading.Thread(target=task,args=[i,])
t.start()

time.sleep(20)

obj = Singleton.instance()

print(obj)

考虑了多线程问题,进行加锁,避免运行太快,如果在__init__中有IO操作,造成创建单例失败,,最后优化必须通过obj= Singleton.instance()来实现单例,如果是obj = Singleton()创建的不是单例

基于__new__方法创建单例

import threading

class Singleton(object):

_instance_lock = threading.Lock()

def __init__(self):
    pass


def __new__(cls, *args, **kwargs):
    if not hasattr(Singleton, "_instance"):
        with Singleton._instance_lock:
            if not hasattr(Singleton, "_instance"):
                Singleton._instance = object.__new__(cls)  
    return Singleton._instance

obj1 = Singleton()

obj2 = Singleton()

print(obj1,obj2)

def task(arg):

obj = Singleton()
print(obj)

for i in range(10):

t = threading.Thread(target=task,args=[i,])
t.start()

基于metaclass方式来实现

import threading

class SingletonType(type):

_instance_lock = threading.Lock()
def __call__(cls, *args, **kwargs):
    if not hasattr(cls, "_instance"):
        with SingletonType._instance_lock:
            if not hasattr(cls, "_instance"):
                cls._instance = super(SingletonType,cls).__call__(*args, **kwargs)
    return cls._instance

class Foo(metaclass=SingletonType):

def __init__(self,name):
    self.name = name

obj1 = Foo('name')

obj2 = Foo('name')

print(obj1,obj2)


以上所述就是小编给大家介绍的《比较全面的单例模式和工厂模式》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

数学拾遗

数学拾遗

加黑蒂 / 清华大学出版社 / 2004-8 / 49.00元

Beginning graduate students in mathematics and other quantitative subjects are expected to have a daunting breadth of mathematical knowledge ,but few have such a backgroud .This book will help stedent......一起来看看 《数学拾遗》 这本书的介绍吧!

URL 编码/解码
URL 编码/解码

URL 编码/解码

MD5 加密
MD5 加密

MD5 加密工具

XML 在线格式化
XML 在线格式化

在线 XML 格式化压缩工具