程序设计及单例实现
程序设计及单例实现
-
程序设计23种模式
-
单例实现
-
pickle序列化模块
-
设计原则七大原则
- 单一职责原则(Single Reponsibility Principle)
是尽量让一个类负责一个接口(功能)。 - 开闭原则(Open/Close Principle)
是指编写类的时候,要符合对类扩展开放,对类的修改关闭。 - 里氏替换原则(Liskov substitution Principle)
是指我们的编写子类,可以在保证业务正确的情况下,替换掉父类。 - 接口隔离原则(Interface Segregation Principle)
是指接口应该保持单一性,一个接口干一件事情。不要合并多个接口到一个接口。 - 依赖反转原则(Dependency Inversion Principle)
指高层模块不应该依赖底层模块,具体就是Controller使用Service的接口,而不应该直接使用Service具体类。 - 迪米特原则/最少知识原则(Least Knowledge Principle)
是指使用类和被使用类之间有个中介,达到使用者尽可能少的知道被使用者的信息。也就是如果客户端要使用service,那么客户端直接使用service的中介就好了。
- 设计模式分类
- 创建型模式:
描述的是根据需求怎样创建对象。 - 结构型模式:
描述的是如何处理类或者对象之间的关系,通过某种布局组成一个比较完善的结构。然后方便客户端使用。 - 行为型模式:
描述多个类或者对象如何协同处理单个对象无法完成的任务。(程序在运行时复杂的流程控制)。
我们应该根据自己的应用场景,选择合适的模式类型,再定位具体的设计模式。
-
- 创建型模式
描述的是根据需求怎样创建对象。
单例模式(Singleton Pattern):
如何在系统环境确保某个类的对象只能创建一个对象。
- 创建型模式
-
原型模式(Prototype Pattern):
就是如何完全复制出已经存在的一个对象。主要是通过Clone,Serializable来实现。参看:深拷贝和浅拷贝(Shallow Copy and Deep Copy) -
工厂方法模式(Fatory Method Pattern):
是指在父类中定义获取对象接口(工厂方法)和使用对象,但是具体的创建对象由子类完成。 -
抽象工厂模式(Abstract Method Pattern):
就是创建一个抽象的工厂,这个工厂可以生产想要的对象(具体有他的子类完成),然后通过FactoryProductor生产出工厂,客户端使用工厂对象获取对象。 -
建造者模式(Builder Pattern):
就是创建一个用于方便创建对象的一个类。参考:建造者模式 -
- 结构型模式
描述的是如何处理类或者对象之间的关系,通过某种布局组成一个比较完善的结构。然后方便客户端使用。
- 结构型模式
-
代理模式(Proxy Pattern):
实质上是创建一个代理对象,而这个带来对象包含了对目标对象的引用。动态代理可以带来任何对象,静态带来可以代理某一类对象。 -
适配器模式(Adapter Pattern):
主要是组合两个不同的功能组件,通过适配器进行合并。具体办法就是:就是target是一个接口,Adapter实现这个接口,并且持有这个Adaptee的引用。 -
桥接模式(Bridge Pattern):
通过抽象和实现分离 达到 对象可以独立变化。这种模式避免了过多的子类,通过使用组合的方法独立变化(interface和abstract)。 -
装饰者模式(Decorator Pattern):
在不改变组件的情况下,增强组件的方法(增加装饰)。主要是通过Decorator持有组件的引用并且实现Compoment来增强组件的方法。 -
外观模式(Facade Pattern):
通过对不同的服务提供统一的门面来实现。 -
亨元模式(Flyweight Pattern):
主要是区分可共享部分(亨元元素)和不可共享部分(Unshare),通过一个context保存对象,根据获取对象的key判断获取的对象是否需要创建,如果不需要,则直接返回。我的亨元模式是完全亨元。 -
组合模式(Composition Pattern):
就是通过把对象组成树状达到对一组对象的操作看成对一个对象的操作。 -
行为型模式
描述多个类或者对象如何协同处理单个对象无法完成的任务。(程序在运行时复杂的流程控制)。 -
策略模式(Strategy Pattern):
是指一个算法的多种实现,并且在运行阶段只有一个算法被选中执行。他符合开闭原则。 -
责任链模式(Chain of Responsibility):
为了避免多个接收对象对一个请求去处理带来的耦合性高的问题,我们解耦这些接受对象,把他们用link串起来。其实就是通过Receiving objects are linked together来简化一个代码块中,handle的行数。 -
观察者模式(Observer Pattern):
是指观察者(多个)对一个目标进行观测,当目标对象被修改时,所有的观察者将会收到通知。观察者模式有两种广播方法push和pull,push是目标对象push到观察者,pull是观察者对象主动pull目标对象的数据。 -
状态模式(State Pattern):
指当对象内部的某个状态改变后会改变其相应的行为。比如,我把这个Context的状态改为A,这个Context的handle是handleA,如果我把Context的状态改为B,这个Context的handle是handleB. -
命令模式(Command Pattern):
是把请求方和接受处理方分离(解耦),通过一个对象来封装处理方的调用。
模板方法模式(Template Pattern):定义一个操作中的算法骨架,而将算法的一些步骤延迟到子类中,使得子类可以不改变该算法结构的情况下重定义该算法的某些特定步骤。 -
中介模式(Mediator Pattern):
定义一个中介对象来封装一系列对象之间的交互,使原有对象之间的耦合松散,且可以独立地改变它们之间的交互。中介者模式又叫调停模式,它是迪米特法则的典型应用最少知识原则(Least Knowledge Principle) -
迭代器模式(Iterator Pattern):
定义一个迭代器对象来顺序访问聚合列表。这样可以复合开闭原则,最少知识原则。 -
Visitor模式(Visitor Pattern)
是指通过封装一个对象实现聚合列表中每个元素的操作(访问)。 -
备忘录模式(Memento Pattern)
是指在不影响对象封装的前提下,对对象的某个状态进行外部保存,以便使用(记录,撤销)。 -
解释器(Interpreter)模式的定义:
给分析对象定义一个语言,并定义该语言的文法表示,再设计一个解析器来解释语言中的句子。也就是说,用编译语言的方式来分析应用中的实例。这种模式实现了文法表达式处理的接口,该接口解释一个特定的上下文。 -
单例实现
单例模式就是确保这一个类无论调用度多少次,只会产生一个对象
单例模式实现方式一
class C1:
# 定义一个用户对象是否产生的属性
__instance = None
def __init__(self, name, age):
self.name = name
self.age = age
# 使用类装饰器传入类的名字
@classmethod
def Singlenton(cls):
if not cls.__instance:
cls.__instance = cls('wesley', 18)
return cls.__instance
obj1 = C1.Singlenton()
obj2 = C1.Singlenton()
obj3 = C1.Singlenton()
# 现在处理第一次传值会执行cls.__instance外,另外两次都是条件不成立直接返回原有cls.__instance
print(id(obj1), id(obj2), id(obj3))
# 这里使用C1进行传值是和原本的对象是没有关系的,所以这里也可以使用这种对象独有数据
obj4 = C1('kevin', 28)
obj5 = C1('tony', 38)
print(id(obj4), id(obj5))
- 单例实现方式二
class Mymeta(type):
# 定义类mysql时就触发
def __init__(self, name, bases, dict):
# 实现从配置文件中取配置来造一个Mysql的实例出来
self.__instance = object.__new__(self) # 产生对象
self.__init__(self.__instance, 'wesley', 18) # 初始化对象
# 上述两步可以合成下面一步
# self.__instance=super().__call__(*args, **kwargs)
super().__init__(name, bases, dict)
def __call__(self, *args, **kwargs): # Mysql(..) 触发
if args or kwargs:
obj = object.__new__(self)
self.__init__(obj, *args, **kwargs)
return obj
return self.__instance
class Mysql(metaclass=Mymeta):
def __init__(self, name, age):
self.name = name
self.age = age
obj1 = Mysql()
obj2 = Mysql()
print(id(obj1), id(obj2))
obj3 = Mysql('tony', 321)
obj4 = Mysql('kevin', 222)
print(id(obj3), id(obj4))
- pickle序列化模块
# pickle序列化模块
"""
优势: 能够序列化python中所有的类型
缺陷: 只能在python中使用,无法跨语言传输
"""
# 先来看一下如何使用,需求是产生一个对象保存到文件中,取出来还是一个对象
class C1:
def __init__(self, name, age):
self.name = name
self.age = age
def func1(self):
print('from func1')
def func2(self):
print('from func2')
obj = C1('wesley', 18)
# 接下来使用pickle模块进行存储,使用方式和json差不多
import pickle
# 将对象存入文件a.txt
with open(r'a.txt', 'wb') as f:
pickle.dump(obj, f)
# 读取
with open(r'a.txt', 'rb') as f:
data = pickle.load(f)
# 打印一下data看一下
print(data)
data.func1()
data.func2()
print(data.name)

浙公网安备 33010602011771号