设计模式


一、设计模式

1.1 如何理解设计模式

  在IT行业中有很多前辈针对固定的一些问题设计出了固定的解决套路

1.2 设计模式总共有23种

  设计模式目前为止总共有23种模式

 

 1.3 设计模式的分类

  如上图所示:

    设计模式总共分为三类: 

      1.创建型模式

      2.结构型模式

      3.行为型模式

1.4 各分类的关键点

单例模式:某个类只能有一个实例,提供一个全局的访问点。

简单工厂:一个工厂类根据传入的参量决定创建出那一种产品类的实例。

工厂方法:定义一个创建对象的接口,让子类决定实例化那个类。

抽象工厂:创建相关或依赖对象的家族,而无需明确指定具体类。

建造者模式:封装一个复杂对象的构建过程,并可以按步骤构造。

原型模式:通过复制现有的实例来创建新的实例。

适配器模式:将一个类的方法接口转换成客户希望的另外一个接口。

组合模式:将对象组合成树形结构以表示“”部分-整体“”的层次结构。

装饰模式:动态的给对象添加新的功能。

代理模式:为其他对象提供一个代理以便控制这个对象的访问。

亨元(蝇量)模式:通过共享技术来有效的支持大量细粒度的对象。

外观模式:对外提供一个统一的方法,来访问子系统中的一群接口。

桥接模式:将抽象部分和它的实现部分分离,使它们都可以独立的变化。

模板模式:定义一个算法结构,而将一些步骤延迟到子类实现。

解释器模式:给定一个语言,定义它的文法的一种表示,并定义一个解释器。

策略模式:定义一系列算法,把他们封装起来,并且使它们可以相互替换。

状态模式:允许一个对象在其对象内部状态改变时改变它的行为。

观察者模式:对象间的一对多的依赖关系。

备忘录模式:在不破坏封装的前提下,保持对象的内部状态。

中介者模式:用一个中介对象来封装一系列的对象交互。

命令模式:将命令请求封装为一个对象,使得可以用不同的请求来进行参数化。

访问者模式:在不改变数据结构的前提下,增加作用于一组对象元素的新功能。

责任链模式:将请求的发送者和接收者解耦,使的多个对象都有处理这个请求的机会。

迭代器模式:一种遍历访问聚合对象中各个元素的方法,不暴露该对象的内部结构。

而我们现在只需要了解单例模式即可

1.5设计模式之单例模式

  类加括号调用多次只能产生一个对象

1.6代码演示

class MyClass(object):
    pass


obj1 = MyClass()
obj2 = MyClass()
obj3 = MyClass()
# 一般情况下 类名加括号实例化对象 执行几次就会产生几个对象
print(id(obj1))  # 2241811157680
print(id(obj2))  # 2241811157792
print(id(obj3))  # 2241811158128
'''
而我们有时候不需要类产生那么多不同的对象
类中有很多的很好用的方法 程序有很多地方都需要使用(通过对象调用)
如果产生的地方特别多 那么就会浪费一定的内存空间 所以需要单例
'''

# 单例可以有很多方法产生
# 第一种:使用元类
class MyMetaClass(type):  # 继承元类
    instance = None  # 定义一个变量

    def __call__(self, *args, **kwargs):
        if self.instance:  # 如果存在返回之前赋值的
            return self.instance
        obj = super().__call__(*args, **kwargs)  # 产生一个空对象
        self.instance = obj  # 让对象赋值给 instance
        return obj  # 返回空对象


class MyClass(metaclass=MyMetaClass):  # 产生类的时候用MyMetaClass产生
    def __init__(self, name):  # 给空对象添加属性
        self.name = name


obj1 = MyClass('jason')
obj2 = MyClass('kevin')
obj3 = MyClass('tony')
print(obj1.name)
print(obj2.name)
print(obj3.name)

# 第二种: 使用装饰器
import settings
# settings中的内容为:
# HOST='1.1.1.1'
# PORT=3306


def singleton(cls):  # cls=Mysql
    _instance = cls(settings.HOST, settings.PORT)

    def wrapper(*args, **kwargs):
        if args or kwargs:
            obj = cls(*args, **kwargs)
            return obj
        return _instance

    return wrapper


@singleton  # Mysql=singleton(Mysql)
class Mysql:
    def __init__(self, host, port):
        self.host = host
        self.port = port


obj1 = Mysql()
obj2 = Mysql()
obj3 = Mysql()
print(obj1.host)
print(obj1.port)
print(obj2.host)
print(obj2.port)
print(obj1 is obj2 is obj3)  # True

obj4 = Mysql('1.1.1.3', 3307)
obj5 = Mysql('1.1.1.4', 3308)
print(obj3 is obj4)  # False

# 第三种:定义一个类方法实现单例模式
import settings


class Mysql:
    __instance = None

    def __init__(self, host, port):
        self.host = host
        self.port = port

    @classmethod
    def singleton(cls):
        if not cls.__instance:
            cls.__instance = cls(settings.HOST, settings.PORT)
        return cls.__instance


obj1 = Mysql('1.1.1.2', 3306)
obj2 = Mysql('1.1.1.3', 3307)
print(obj1 is obj2)  # False

obj3 = Mysql.singleton()
obj4 = Mysql.singleton()
print(obj3 is obj4)  # True

二、pickle模块

  pickle模块与json模块一样都是对象数据序列化和反序列化的

  而pickle模块支持python中所有的数据类型 而json模块有限制

  但是pickle模块不能跨语言传输 兼容性差只能自己python玩

  而json可以跨语言传输

  为了我们接下来要编写的选课系统才学的 后续我们不会再用

  因为有更高级的方法>>>:ORM(对象关系映射)

import json
import pickle

class MyClass(object):
    def __init__(self, name):
        self.name = name

obj = MyClass('jason')
# 我们现在需要把对象obj保存到文件中
# 1. 我们先使用文件操作看能不能写文件
with open(r'a.txt', 'w', encoding='utf8')as f:
    f.write(obj)
# 会报错 因为使用write()只能写字符串不能是对象
# 2. 使用json格式
with open(r'a.txt', 'w', encoding='utf8')as f:
    json.dump(obj, f)
# 也会报错 因为json格式不支持对象序列化
with open(r'a.txt', 'wb')as f:
    pickle.dump(obj, f)
# 这样就能保存到文件中 但是使用pickle模块是二进制形式的

 

 

三、选课系统项目分析

选课系统
  角色:学校、学员、课程、讲师
  要求:
    1. 创建北京、上海 2 所学校
    2. 创建linux , python , go 3个课程 , linux\py 在北京开, go 在上海开
    3. 课程包含,周期,价格,通过学校创建课程 
    4. 通过学校创建班级, 班级关联课程、讲师5. 创建学员时,选择学校,关联班级
    5. 创建讲师角色时要关联学校, 
    6. 提供三个角色接口  
        6.1 学员视图, 可以注册, 交学费, 选择班级,  
        6.2 讲师视图, 讲师可管理自己的班级, 上课时选择班级, 查看班级学员列表 , 修改所管理的学员的成绩   
        6.3 管理视图,创建讲师, 创建班级,创建课程
    7. 上面的操作产生的数据都通过pickle序列化保存到文件里
    
 
功能分析
    管理员功能(最核心)
        1.注册
       2.登录
       3.创建讲师
           4.创建学校
       5.创建课程
    讲师功能
        1.注册
       2.登录
        3.选择教授课程
       4.查看教授课程
        5.管理课程分数
     学生功能
        1.注册
       2.登录
        3.选择学校
       4.选择课程
           5.查看分数

四、系统架构设计

三层架构
    功能展示层
        src.py
       admin_view.py
        teacher_view.py
       student_view.py
       核心逻辑层
        admin_interface.py
       teacher_interface.py
        student_interface.py
    数据处理层
        db_hanlder.py
       model.py

五、作业

5.1 描述出选课系统管理员注册功能完整逻辑

1.在admin.view中编写一个注册功能
2.在这个功能中获取姓名和密码
3.然后调用admin_interface中的注册函数
4.在这个函数调用model中的admin类做判断是否已注册
5.在model中创建两个方法一个是保存数据一个是获取数据
6.保存数据是在db文件夹中利用类名在创建一个文件夹
    就是利用类名拼接一个路径创建 而类名的获取是 对象.__class__.__name__方法获得
7.然后在类名中创建管理员的文件文件名用获取到的名字
    也是利用os拼接一个路径创建 而对象的名字获取的方法是 对象.name
    就能够保存
8.然后就是获取这个路径就能够判断获取的名字是否存在
    存在就不注册
    不存在就注册
9.而想要获取的话我们传入的是对象而我们只能使用类的方式拼接 
    所以我们只能使用语法糖@classmethod让这个方法变成类的方法
    这样我们就可以使用类名.name就可以获取类中的姓名

 

posted @ 2022-08-01 19:53  stephen_hao  阅读(80)  评论(0编辑  收藏  举报