第二十一天

 面向对象编程

# 面向过程:重点在于 “做什么”,使用大量的函数解决
# 优点:思维简单,容易实现
# 缺点:当需求发生改变的时候,不容易维护,不容易扩展
# 适合场景:底层的操作系统,服务器,中间件。。。。

# 面向对象:重点在于“谁” ,谁有什么,有什么行为
# 优点:当需求发生改变时,系统容易扩展
# 缺点:跟面向过程相比,复杂。跟面向切面相比,容易产生代码的冗余。
# 适合的场景:应用系统的开发。

# 人,起床,穿衣服,开门(开自己家楼门),锁门(门),开车(车)
# Person Door Car
# 人和车之间,人和门之间都是弱依赖。
# 人的名字
class Person:
    def __init__(self, name):
        self.name = name

    def getup(self):
        print("起床")

    def getdress(self):
        print("穿衣服")

    def openDoor(self, door):
        door.opendoor()

    def lockDoor(self, door):
        door.lockdoor()

    def drive(self, car):
        car.driver()

    def working(self):
        pass


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

    def opendoor(self):
        print("打开{}".format(self.name))

    def lockdoor(self):
        print("锁门{}".format(self.name))

    def modify(self):
        print("修理门")


class Car:
    def __init__(self):
        self.name = None

    def driver(self):
        print("开{}车".format(self.name))


class AUDICar(Car):
    def __init__(self):
        super().__init__()
        self.name = "奥迪A6"


p = Person("张三")
p.getup()
p.getdress()
housedoor = Door("自己家门")
p.openDoor(housedoor)
p.lockDoor(housedoor)
audiCar = AUDICar()
p.drive(audiCar)
p.working()
# 面向对象的相关概念
1. OO 面向对象 object-oriented
# 以对象为中心,以类和继承为构造机制,来认识或者理解客观世界的设计。

2.OOA 面向对象分析法
# 开发之前面向对象的分析。针对OO方法所需要的 素材记性归类分析和整理。
# 对于OO的细化工作,得到OO的属性和方法。
# OOA的主要原则
(1)抽象
# 编程:算法和数据结构 抽象把业务整理成合理的算法和数据结构。
# 抽象定义:从许多事务中舍弃个别的,非本质的特征,抽取共同,本质的特征,这就是抽象
# 设计class,把所有的对象分析成Class

# 抽象的原则:
# 过程抽象:在类中创建什么样的方法。类中方法
# 数据抽象:在类中应该有什么样的数据类型。类中属性

(2) 封装:就是把对象的属性和方法结合为一个不可分割系统单位,尽量对外隐藏内部的设计细节。
# python通过定义私有属性和私有方法 __name
# 为了能够让用户便捷的访问,需要使用property函数或者property装饰器。
class Tea:
def __init__(self, name, price):
self.__name = name
self.__price = price

def get_name(self):
return self.__name

name = property(get_name)
# def __del__(self):
# print("tea被删除")


(3)继承:特殊类的对象拥有一般类的全部属性和方法。把具有一般和特殊关系的类设计成继承。
# 一般:父类
# 特殊:子类
# 设计原则:父类 < 子类
class RedTea(Tea):
def __init__(self, name, price, level):
self.level = level
super().__init__(name, price)


(4)分类:是抽象原则应用对象描述的一种表现形式。把具有相同属性或者相同方法对象先划分成一类,
# 其他的类在这个类基础上扩展。
class BaseCold:
    def store(self):
        print("冷饮储藏")


class BaseHot:
    def store(self):
        print("热饮储藏")


class iceCream(BaseCold):
    pass 

(5)聚合:组装,可以看成是把一个复杂的事务看成由若干事务组装起来。若干事务和复杂的事务之间强依赖。整体和部分之间的关系。
# A必须有B
class Milk:
    pass
    # def __del__(self):
    #     print("milk被删除")


class MilkTea:
    def __init__(self, milk, tea, name, price):
        self.milk = milk
        self.tea = tea
        self.name = name
        self.price = price
    # def __del__(self):
    #     print("奶茶被删除")


milk = Milk()
tea = Tea("红茶", 2)
mt = MilkTea(milk, tea, "牛奶红茶", 20)

# milk和milktea之间就是聚合关系
del mt

  创建整体时,必须先有部分,才能创建整体

 删除整体的时候,部分也会被跟着删除。


(6)关联:比较弱的类和类之间的关系,强调的是A可以有B
class MilkTea:
    def __init__(self, milk, tea, name, price):
        self.milk = milk
        self.tea = tea
        self.name = name
        self.price = price

    def addSuger(self, suger):
        suger.addSuguer(2)
    # def __del__(self):
    #     print("奶茶被删除")


class Suger:
    def addSuguer(self, n):
        print("加入{}糖".format(n))


milk = Milk()
tea = Tea("红茶", 2)
mt = MilkTea(milk, tea, "牛奶红茶", 20)

  (7)消息通信:要求对象和对象之间只能通过消息进行通信(需要调用对应方法来访问属性)

#   而不是直接访问属性。封装

3. OOD面向对象的设计
# 是面向对象分析之后,在做编码之前的一个设计工作。
# 系统设计目标:
"""
(1)可扩展:保证新性能可以很容易的加入到先有的系统。不影响已有的内容
(2)可修改:当修改一部分代码的时候,尽量不影响其他相关的部分。
(3)可替代:调用父类的地方 可以用子类代替,说明父子关系实现的是对的。
"""

# 为了达到目标,希望遵守的原则SOLID原则
"""
1. 单一职责原则
2. 开放关闭原则
3. 里氏转换原则
4. 接口隔离原则
5. 依赖倒置原则
"""


1. 单一职责原则:一个类只做好一件事情。核心解耦。尽量将其他功能放入其他的类中。
2. 开放关闭原则:
# 对于模块和函数来说,应该扩展开放,对于修改关闭
# 类---扩展---继承
# 函数--扩展--装饰器
# 抽象出相对稳定的接口,这一部分一般不做修改。
# 扩展新功能,尽量通过其他新建的方式。

3.里氏替换原则:所有引用的基(父)类的地方必须能够透明使用其子类对象。判断对象之间的继承
# 关系是否合理。
# 在真正设计的时候,尽量采用的组合,而不是继承。
# 按照原则来说,子类对于父类的方法尽量不去重载

4. 接口隔离原则:多继承时,当创建一个接口(父类)尽量不强迫用户去实现不需要实现的内容。
# 茶: 加糖,加盐,做茶汤。
# 红茶(茶):如果不适合做茶汤,所以受限制。
# 最小继承。(父类中尽量保留最少的属性和方法,通用的)
# bike ride gps不应该出现在父类接口中。

5. 依赖倒置原则
# class Book():
#     def getContent(self):
#         print("很久很久以前。。。。")
# class Mother():
#     def tellStory(self, book):
#         print("妈妈开始讲故事")
#         book.getContent()
# b=Book()
# m=Mother()
# m.tellStory(b)
class IReader():
    def getContent(self):
        pass


class Book(IReader):
    def getContent(self):
        print("很久很久以前。。。。")


class News(IReader):
    def getContent(self):
        print("中国足球队。。。。")


class Mother():
    def tellStory(self, ireader):
        print("妈妈开始讲故事")
        ireader.getContent()


b = Book()
news = News()
m = Mother()
m.tellStory(b)
m.tellStory(news)

  # 解耦的目的

设计模式之工厂模式

"""
设计模式
GOP四个博士运用了5种原则,形成了一套经典设计模式
什么样的代码要抽取 ,什么样的代码不抽取,抽取的时候按什么规则抽取
"""
# 工厂模式:
class Shoe:
def __init__(self):
self.address="北京制造"
s=Shoe()
s.address="北京制造"

# 设计模式分为三种类型:
# 创建型模式
# 结构型模式
# 行为型模式

一、 创建型的模式
1. 工厂模式
"""
为了解决一个类不知道它所必须创建的对象是什么的时候。
解决的方式:
创建一个对象的接口,让子类决定实例化哪一个一个类,
创建Factory接口方法,按照客户的需求指定创建哪个类的对象
"""
# 创建圆形,画圆形
# class cirle:
# def __init__(self):
# self.name="circle"
# def draw(self):
# print("画一个圆形")
# class Rectangle:
# def __init__(self):
# self.name="rectangle"
# def draw(self):
# print("画一个矩形")

(1)简单工厂
 class Shape:
     def __init__(self):
         self.shape_name=None
     # def getShape(self):
     #     return self.shape_name
 class cirle(Shape):
     def __init__(self):
         super().__init__()
         self.name="circle"
     def draw(self):
         print("画一个圆形")
 class Rectangle(Shape):
     def __init__(self):
         super().__init__()
         self.name="rectangle"
     def draw(self):
         print("画一个矩形")
 class ShapeFactory:
     def create(self,shape_name):
         if shape_name=="circle":
            return cirle()
         if shape_name=="rectangle":
             return Rectangle()
         else:
             return None
 fac=ShapeFactory()
 obj=fac.create("circle")
 obj.draw()

 obj1=fac.create("rectangle")
 obj1.draw()

"""
优点:当指定创建某一个形状的时候,不需要调用不同的类创建对象
缺点:当新增加一个形状时,需要修改客户端的传入,还需要添加形状类,还需要修改工厂类。
"""

(2) 工厂方法模式
# 对于各个类有自己的工厂,对于原来简单工厂的扩展,
# 这个类不在负责具体产品的生产,只是指定规范,由其他扩展的工厂子类去完成对象的加工
class Shape:
    def __init__(self):
        self.shape_name=None
    # def getShape(self):
    #     return self.shape_name
class cirle(Shape):
    def __init__(self):
        super().__init__()
        self.name="circle"
    def draw(self):
        print("画一个圆形")
class Rectangle(Shape):
    def __init__(self):
        super().__init__()
        self.name="rectangle"
    def draw(self
):
        print("画一个矩形")
class Square(Shape):
    def __init__(self):
        super().__init__()
        self.name = "square"

    def draw(self):
        print("画一个正方形")
class ShapeFactory:
    def create(self):
        pass
class cirleFacotry(ShapeFactory):
    brand="圆形工厂"
    def create(self):
        return cirle()
class rectangeFacotry(ShapeFactory):
    brand="长方工厂"
    def create(self):
        return Rectangle()
class squareFacotry(ShapeFactory):
    brand="正方形工厂"
    def create(self):
        return Square()

circleF=cirleFacotry()
obj=circleF.create()
print(circleF.brand)
obj.draw()

rectangeF=rectangeFacotry()
obj1=rectangeF.create()
print(rectangeF.brand)
obj1.draw()
"""
优点:扩展性比较好,如果希望增加一个产品,增加一个产品类,增加一个工厂类
缺点:当每次加工产品,一定程度上,如果不需要批量从工厂中加工出特殊的对象,可能还不如普通的new
"""

(3) 抽象工厂模式
"""
抽象工厂:围绕着一个超级工厂去创建其他工厂,超级工厂又称为其他工厂的工厂。
对产品族中一套产品生成多个对象
"""
"""
实现思路:
产品族的工厂:包含了生产不同等级产品的方法
"""
# cpu
class CPU:
    pass


class IntelCpu(CPU):
    def __init__(self, name):
        self.name = name


class AmdCpu(CPU):
    def __init__(self, name):
        self.name = name


class Memory:
    pass


class IntelMemory(Memory):
    def __init__(self, name):
        self.name = name


class AmdMemory(Memory):
    def __init__(self, name):
        self.name = name


class ComputerFacotry:
    def createCpu(self):
        pass

    def createMemory(self):
        pass


class IntelFacotry(ComputerFacotry):
    computer_name = "Inter-7 computer"

    def createCpu(self):
        return IntelCpu("IntelCPU-2000")

    def createMemory(self):
        return IntelMemory("IntelMemory")


class AmdFacotry(ComputerFacotry):
    computer_name = "AMD -n  computer"

    def createCpu(self):
        return AmdCpu("AMDCPU-4000")

    def createMemory(self):
        return AmdMemory("AMDMemory")
# 希望要什么电脑,直接指定对应的工厂即可
# 电脑中已经对产品族中每一个产品进行了创建。
# ifa=IntelFacotry()
ifa = AmdFacotry()
cpu = ifa.createCpu()
memory = ifa.createMemory()
info = """

computer名字{}: cpu:{}
memory:{}
""".format(ifa.computer_name, cpu.name, memory.name)
print(info)

# 抽象工厂模式的优缺点:
"""
1. 客户端使用抽象工厂创建对象,客户端不需要知道具体的实现
2. 切换产品族非常容易,通过修改工厂即可
3. 增加新的具体工厂和产品族,对修改关闭,完全新建

缺点:
不容易扩展新的产品,需要向所有的工厂中添加新的产品。

应用场景:
1. 产品族不是经常修改。要修改就改一套产品族。
所以规定在产品族中的产品,一定是规定好的产品。
2. 一个系统不应当依赖于产品类实例如何被创建,也就是,当不关心创建本身的细节
只关心如何创建即可。
"""

"""
创建模式:new ,简单工厂、工厂方法、抽象工厂
"""


# 生产宝马车。
# 1. 没有工厂的时候,只能new,很可能需要创建好其他的对象,而且找好对象和对象之间的关系。
# 2. 简单工厂:相当于要宝马车的时候,向宝马车工厂要,不是自己去new
class BMWFacory:
def create(self):
pass


bf = BMWFacory()
b = bf.create()


# 3. 工厂方法:如果宝马车的系列原来的越多,一个工厂不够用,所以需要多个工厂进行加工。
# class BMWFacory:
# def create(self,type):
# # 判断具体要什么样宝马, 创建宝马对象,违反的关闭原则
# pass
class BMWFacory1:
def create(self):
pass


class BMWFacory2:
def create(self):
pass


class BMWFacory3:
def create(self):
pass


bf1 = BMWFacory1()


# 4. 抽象工厂:不同宝马车配不同的空调。宝马1系列配置A空调 ,宝马2系列配B空调。
class BMWFacory1A:
def create(self):
pass


class BMWFacory2B:
def create(self):
pass

 

posted on 2018-08-15 21:05  不虚此行ztx  阅读(136)  评论(0编辑  收藏  举报