赞
踩
在之前文章(Python从菜鸟到高手,这些功能强大的技巧要掌握)中,我们已介绍过Python作为一门编程类语言,会有一些功能强大但不易理解、不易掌握的用法。本篇文章将介绍两种在学Python过程有点懵逼、却必须理解和掌握的,同时也是在面试过程中经常被问及的设计模式,在阅读过程中如果感觉不易理解,建议先收藏,慢慢体会,有疑问请留言区留言。
很多初学者喜欢用全局变量,因为这比函数的参数传来传去更容易让人理解。确实在很多场景下用全局变量很方便。不过如果代码规模增大,并且有多个文件的时候,全局变量就会变得比较混乱,你可能不知道在哪个文件中定义了相同类型甚至重名的全局变量,对于这种情况,有种更好的实现方式:单例(Singleton)
单例模式
单例是一种设计模式,应用该模式的类只会生成一个实例。单例模式保证了在程序的不同位置都可以且仅可以取到同一个对象实例:如果实例不存在,会创建一个实例;如果已存在就会返回这个实例。
我们在使用class创建类的时候, 只会创建一个类对象, 但是, 当我们实例化这个类对象的时候, 一个类对象, 可以实例化出很多不同的对象, 而我们每次实例化出来一个对象, 就会在内存中重新分配一块空间, 而今天介绍的单例模式, 就是为了解决上述问题, 使得由一个类对象所实例化出来的全部对象都指向同一块内存空间。那么这有什么好处呢?
单例模式的优点:
单例模式的应用场景:
代码示例
- class python_learning(object):
- instant = None
- flag = True
-
- def __new__(cls, *args, **kwargs):
- if cls.instant is None:
- cls.instant = super().__new__(cls)
- return cls.instant
-
- def __init__(self):
- if not B.flag:
- return
- self.name = 'Python学习与数据挖掘'
- B.flag = False
- print('已经被初始化了')
-
- d = python_learning()
- print('d对象所在的内存地址是 %d, B类所在的内存地址是 %d' % (id(d), id(python_learning)))
- e = python_learning()
- print('e对象所在的内存地址是 %d, B类所在的内存地址是 %d' % (id(e), id(python_learning)))
- f = python_learning()
- print('f对象所在的内存地址是 %d, B类所在的内存地址是 %d' % (id(f), id(python_learning)))

结果输出
- d对象所在的内存地址是 4434814456, python_learning类所在的内存地址是 140483145268616
- e对象所在的内存地址是 4434814456, python_learning类所在的内存地址是 140483145268616
- f对象所在的内存地址是 4434814456, python_learning类所在的内存地址是 140483145268616
上述是基于__new__方法实现的单例模式,一个对象的实例化过程是先执行类的__new__方法,如果我们没有写,默认会调用object的__new__方法,返回一个实例化对象,然后再调用__init__方法,对这个对象进行初始化。
工厂模式
想必大家一定见过类似于麦当劳自助点餐台一类的点餐系统吧。在一个大的触摸显示屏上,有三类可以选择的上餐品:汉堡等主餐、小食、饮料。当我们选择好自己需要的食物,支付完成后,订单就生成了。下面我们用今天的主角--工厂模式--来生成这些食物的逻辑主体。
首先,来看主餐的生成(仅以两种汉堡为例)。
- class Burger():
- name=""
- price=0.0
- 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():
- 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"
同样,foodFactory为抽象的工厂类,而burgerFactory,snackFactory,beverageFactory为具体的工厂类。在业务场景中,工厂模式是如何“生产”产品的呢?
- if __name__=="__main__":
- burger_factory=burgerFactory()
- snack_factorry=snackFactory()
- beverage_factory=beverageFactory()
- cheese_burger=burger_factory.createFood(cheeseBurger)
- print(cheese_burger.getName(),cheese_burger.getPrice())
- chicken_wings=snack_factorry.createFood(chickenWings)
- print(chicken_wings.getName(),chicken_wings.getPrice())
- coke_drink=beverage_factory.createFood(coke)
- print(coke_drink.getName(),coke_drink.getPrice())
可见,业务中先生成了工厂,然后用工厂中的createFood方法和对应的参数直接生成产品实例。打印结果如下:
- BURGER factory produce a instance.
- cheese burger 10.0
- SNACK factory produce a instance.
- chicken wings 12.0
- BEVERAGE factory produce a instance.
- coke 4.0
工厂模式模式的优点:
工厂模式的使用场景:
当系统实例要求比较灵活和可扩展时,可以考虑工厂模式或者抽象工厂模式实现。比如,
在通信系统中,高层通信协议会很多样化,同时,上层协议依赖于下层协议,那么就可以对应建立对应层级的抽象工厂,根据不同的“产品需求”去生产定制的实例。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。