在一个现代化的工程中,人们要相互沟通和合作,就必须使用标准的工业化设计语言,用这些语言来对待开发的产品进行建模。
建模过程把复杂的问题分解成为易于理解的小问题,以达到问题的求解。
建模是开发优秀软件的所有活动中核心部分之一,其目的是把所要设计的结构和系统的行为联系起来,并对系统的结构进行可视化控制。
常用的设计模式原则包括7个
1、单一职责——不能把太多的任务放在一个类中(一个类做一件事)
2、开闭原则——在不需要修改既有功能的前提下的扩展性(扩展开放,修改关闭)
3、里氏代换原则——软件中如果能够使用基类(父类)对象,那么一定能够使用其子类对象(喜欢动物==>喜欢猫,因为猫是动物)
4、依赖倒转原则——要针对接口编程,不要针对实现编程(降低耦合性)
5、接口隔离原则——用多个专门的接口来取代一个统一的接口(客户端不应该依赖那些它不需要的接口实现,所以要细分出专门的接口,单一职责)
6、合成复用原则——尽量使用对象组合,而不是继承来达到复用的目的(类与类之间的耦合度降低)
7、迪米特法则——一个软件实体对其他实体的引用越少越好,或者说如果两个类不必彼此直接通信,那么这两个类就不应当发生直接的相互作用,而是通过引入一个第三者发生间接交互(降低类之间的耦合)
设计模式(Design Pattern)是一套被反复使用、多数人知晓的、经过分类编目的、代码设计经验的总结,使用设计模式是为了可重用代码、让代码更容易被他人理解、保证代码可靠性。
设计模式根据其目的可分为创建型(Creational),结构型(Structural)和行为型(Behavioral)三种:
创建型模式主要用于创建对象。
结构型模式主要用于处理类或对象的组合。
行为型模式主要用于描述对类或对象怎样交互和怎样分配职责。
——————————————————————————————
单例模式
对于系统中的某些类来说,只有一个实例很重要
单例模式确保某一个类只有一个实例,而且自行实例化并向整个系统提供这个实例
节约系统资源
# 懒汉模式
class A:
instance=None
iscreate=0
def __init__(self):
if A.iscreate==1:
return print('is exist')
print('create')
A.iscreate=1
def __new__(cls, *args, **kwargs):
if cls.instance is None:
cls.instance=super().__new__(cls)
return cls.instance
懒汉模式:类加载时不初始化。饿汉模式:类加载时就创建了对象。
所以懒汉节省资源利用效率,但饿汉反应时间快,具体场景具体选择。
应用:系统只需要一个实例对象,客户调用时只允许一个公共访问点
——————————————————————————
工厂设计模式
只需要知道水果的名字则可得到相应的水果
通过工厂函数返回对应对象.橘子.苹果什么的
工厂模式包涵一个超类,这个超类提供一个抽象化的接口来创建一个特定类型的对象,而不是决定哪个对象可以被创建
当程序运行输入一个“类型”的时候,就会创建相应的对象
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)
factory = Factory()
person = factory.getPerson("Chetan", "M")
工厂模式可扩展、可维护,降低了系统的耦合度
当增加一个新的类型时,不在需要修改已存在的类,只增加能够产生新类型的子类即可
工厂类负责创建的对象不能太多,否则业务逻辑太复杂
应用:饭店点菜,买包子(只需知道要什么东西,不需知道如何创建)
——————————————————————————————
抽象工厂模式
创建一系列相关或相互依赖对象的接口,而无须指定它们具体的类
和工厂模式不同的是,它面向的是多个种类对象的创建
包括:产品、工厂的抽象类、实例共4个类
优点:
1、抽象工厂模式隔离了具体类的生成,使得客户并不需要知道什么被创建。
由于这种隔离,更换一个具体工厂就变得相对容易。
所有的具体工厂都实现了抽象工厂中定义的那些公共接口,因此只需改变具体工厂的实例,就可以在某种程度上改变整个软件系统的行为。
另外,应用抽象工厂模式可以实现高内聚低耦合的设计目的,因此抽象工厂模式得到了广泛的应用。
2、当一个产品族中的多个对象被设计成一起工作时,它能够保证客户端始终只使用同一个产品族中的对象。
这对一些需要根据当前环境来决定其行为的软件系统来说,是一种非常实用的设计模式。
3、增加新的具体工厂和产品族很方便,无须修改已有系统,符合“开闭原则”。
缺点是虽然它增加新的工厂和产品族容易,但它增加新的产品等级结构麻烦。
实例:买披萨,几个工厂(实体店),什么风味的披萨
————————————————————————————
适配器模式
(类结构型和对象结构型,类似于计算机电源适配器)
客户端可以通过目标类的接口访问它所提供的服务(包装类-过渡抽象类)
包含总接口类、目标适配器抽象类、适配者服务类
由于适配器类是适配者类的子类,因此可以在适配器类中置换一些适配者的方法,使得适配器的灵活性更强。
应用:系统使用的接口类不符合需要、重复使用并且彼此间没有太大关联的类.需要他们一起工作
————————————————————————————
代理模式
(用户的操作通过远程代理服务器来做)
在某些情况下,一个客户不想或者不能直接引用一个对象,此时可以通过一个称之为“代理”的第三者来实现间接引用。
代理对象可以在客户端和目标对象之间起到中介的作用,并且可以通过代理对象去掉客户不能看到的内容和服务或者添加客户需要的额外服务。
定义:给某一个对象提供一个代理,并由代理对象控制对原对象的引用。
代理模式的优点
(权限管理、远程代理处理、弱耦合、减少资源消耗)
代理模式用来协调调用者和被调用者,在一定程度上降低了系统的耦合度。
远程代理使得客户端可以访问在远程机器上的对象,远程机器可能具有更好的计算性能与处理速度,可以快速响应并处理客户端请求。
虚拟代理通过使用一个小对象来代表一个大对象,可以减少系统资源的消耗,对系统进行优化并提高运行速度。
保护代理可以控制对真实对象的使用权限。
缺点就是有些时候代理造成的请求处理速度会变慢,并且有时候代理类(额外的类.工作)会影响效率.不如不要。
————————————————————————————
建造者模式
(类似于造车,对象属性相当于车的零件)
建造者模式可以将部件和其组装过程分开,一步一步创建一个复杂的对象。
它和抽象工厂模式相似,但产出不同,一个是造车,一个是汽车配件生产。
包括:抽象builder、具体builder、director、product
(如果有一个builder的话可以省略抽象类和director类)
优点:
在建造者模式中,客户端不必知道产品内部组成的细节,将产品本身与产品的创建过程解耦,使得相同的创建过程可以创建不同的产品对象。
每一个具体建造者都相对独立,而与其他的具体建造者无关,因此可以很方便地替换具体建造者或增加新的具体建造者,用户使用不同的具体建造者即可得到不同的产品对象。
可以更加精细地控制产品的创建过程。将复杂产品的创建步骤分解在不同的方法中,使得创建过程更加清晰,也更方便使用程序来控制创建过程。
增加新的具体建造者无须修改原有类库的代码,指挥者类针对抽象建造者类编程,系统扩展方便,符合“开闭原则”。
缺点:不适用产品之间差异大、产品内部变化复杂的情况。
应用:在很多游戏软件中,地图包括天空、地面、背景等组成部分,人物角色包括人体、服装、装备等组成部分,可以使用建造者模式对其进行设计,通过不同的具体建造者创建不同类型的地图或人物。
——————————————————————————