设计模式(Design Pattern,DP)入门以及六大原则(part 1)
面向对象编程
面向对象(Object Oriented)是软件开发方法。面向对象的概念和应用已超越了程序设计和软件开发,是一种对现实世界理解和抽象的方法,是计算机编程技术发展到一定阶段后的产物。
面向对象是相对于面向过程来讲的,指的是把相关的数据和方法组织为一个整体来看待,从更高的层次来进行系 统建模,更贴近事物的自然运行模式。
啥是面向过程,啥是面向对象,可能举个例子会比较清晰:
做一道西红柿炒蛋:
面向过程做法:买菜-->洗菜-->炒菜-->等吃
面向对象做法:雇一个厨师-->等吃
做一桌满汉全席:
面向过程做法: ....
面向对象做法: 雇一个会做满汉全席的厨师-->等吃
面向对象和面向过程思想是两种完全不同的编程思想,面向过程更像是个执行者,对程序执行的每一步都设计得非常清楚,而面向对象像是个管理者,管理对象去执行程序
设计模式的起源
“设计模式”这个术语最初并不是出现在软件设计中,而是被用于建筑领域的设计中。 直到 1990 年,软件工程界才开始研讨设计模式的话题。
1995年,“四人组”(Gang of Four,GoF)合作出版了《设计模式:可复用面向对象软件的基础》(Design Patterns: Elements of Reusable Object-Oriented Software)一书,在书籍中收录了 23 个设计模式,这是设计模式领域里程碑的事件,导致了软件设计模式的突破。
直到今天,狭义的设计模式还是该书中所介绍的23种经典设计模式。
所以,学习设计模式就是学习前人在程序和软件设计中总结出的经验,目的是为了提高代码的可重用性、代码的可读性和代码的可靠性。
设计模式的六大原则
开闭原则
概述
开闭原则由勃兰特·梅耶(Bertrand Meyer)提出,他在 1988 年的著作《面向对象软件构造》(Object Oriented Software Construction)中提出:软件实体应当对扩展开放,对修改关闭(Software entities should be open for extension,but closed for modifification),这就是开闭原则的经典定义。简单点说就是是:一个软件实应该通过扩展来实现变化,而不是通过修改已有的代码来实现变化。那么什么是软件实体呢?
这里的软件实体包括以下几个部分:
-
项目中划分出的模块
-
类与接口
-
方法
举例
# coding=utf-8
from abc import ABCMeta, abstractmethod
class BookInterface(metaclass=ABCMeta):
name = None
price = None
def __init__(self, name, price):
self.name = name
self.price = price
@abstractmethod
def get_name(self):
pass
@abstractmethod
def get_price(self):
pass
class Book(BookInterface):
def get_name(self):
return self.name
def get_price(self):
return self.price
if __name__ == '__main__':
tangshi_3 = Book("唐诗三百首", 300)
tangshi_2 = Book("唐诗两百首", 200)
tangshi_1 = Book("唐诗一百首", 100)
print("书名:{},售价:{}".format(tangshi_3.get_name(), tangshi_3.get_price()))
print("书名:{},售价:{}".format(tangshi_2.get_name(), tangshi_2.get_price()))
print("书名:{},售价:{}".format(tangshi_1.get_name(), tangshi_1.get_price()))
执行结果:
然而,商场如果赶上节假日啥的,需要对衣服进行打折,如何修改?
-
在抽象基类中添加打折的方法
-
修改具体衣服类中的方法
-
扩展接口
# coding=utf-8
from abc import ABCMeta, abstractmethod
class BookInterface(metaclass=ABCMeta):
name = None
price = None
def __init__(self, name, price):
self.name = name
self.price = price
@abstractmethod
def get_name(self):
pass
@abstractmethod
def get_price(self):
pass
class Book(BookInterface):
def get_name(self):
return self.name
def get_price(self):
return self.price
class DisCountBook(Book):
def get_price(self):
price = self.price
if price > 200:
return price * 0.9
else:
return price * 0.8
if __name__ == '__main__':
tangshi_3 = DisCountBook("唐诗三百首", 300)
tangshi_2 = DisCountBook("唐诗两百首", 200)
tangshi_1 = DisCountBook("唐诗一百首", 100)
print("书名:{},售价:{}".format(tangshi_3.get_name(), tangshi_3.get_price()))
print("书名:{},售价:{}".format(tangshi_2.get_name(), tangshi_2.get_price()))
print("书名:{},售价:{}".format(tangshi_1.get_name(), tangshi_1.get_price()))
执行结果:
单一职责
概述
单一职责原则(Single Responsibility Principle,SRP)又称单一功能原则,由罗伯特·C.马丁(Robert C.Martin)于《敏捷软件开发:原则、模式和实践》一书中提出的。这里的职责是指类变化的原因,单一职责原则规定一个类应该有且仅有一个引起它变化的原因,否则类应该被拆分(There should never be more than one reason for a class to change)。
单一职责原则的核心就是控制类的粒度大小、将对象解耦、提高其内聚性。如果遵循单一职责原则将有以下优点。
-
降低类的复杂度。一个类只负责一项职责,其逻辑肯定要比负责多项职责简单得多。
-
提高类的可读性。复杂性降低,自然其可读性会提高。
-
提高系统的可维护性。可读性提高,那自然更容易维护了。
-
变更引起的风险降低。变更是必然的,如果单一职责原则遵守得好,当修改一个功能时,可以显著降低对其他功能的影响。
举例
# coding=utf-8
from abc import ABCMeta, abstractmethod
class TeacherInterface(metaclass=ABCMeta):
subject = None
def __init__(self, subject):
self.subject = subject
@abstractmethod
def teach(self):
pass
@abstractmethod
def look_student(self):
pass
class Teacher(TeacherInterface):
def teach(self):
print("我是{}老师,我正在上课.....".format(self.subject))
def look_student(self):
print("我是{}老师,我来看望学生.....".format(self.subject))
if __name__ == '__main__':
t1 = Teacher("体育")
t1.teach()
t1.look_student()
假如我们要实现校长类,但是校长已经不需要上课了.......
# coding=utf-8
from abc import ABCMeta, abstractmethod
class TeacherInterface(metaclass=ABCMeta):
subject = None
def __init__(self, subject):
self.subject = subject
@abstractmethod
def teach(self):
pass
class WorkerInterface(metaclass=ABCMeta):
subject = None
def __init__(self, subject):
self.subject = subject
@abstractmethod
def look_student(self):
pass
class Teacher(TeacherInterface, WorkerInterface):
def teach(self):
print("我是{}老师,我正在上课.....".format(self.subject))
def look_student(self):
print("我是{}老师,我来看望学生.....".format(self.subject))
class SchoolMaster(WorkerInterface):
def look_student(self):
print("我是{}校长,我来看望学生.....".format(self.subject))
if __name__ == '__main__':
t1 = Teacher("体育")
t1.teach()
t1.look_student()
t2 = SchoolMaster("学校")
t2.look_student()
执行结果: