几种常见的设计模式

176 阅读4分钟

什么是设计模式?

设计模式是为了编程设计时的推荐方案,其目的是为了将变化带来的影响降到最小,达到代码的复用。设计模式大体上又可以分为三类:

1、创建型模式:介绍处理对象创建的设计模式。

2、结构型模式:介绍处理一个系统中不同实体(类和对象)之间关系的设计模式。

3、行为型模式:介绍处理系统实体之间通信的设计模式。


本处主要介绍创建型模式下的三种模式:

一、工厂模式

工厂模式就是将各种需要的方法都集中封装成一个类里面,传入需要的参数,根据传入参数的不同最终生成不同的产品,例如你要造一辆汽车,只需要传入‘小汽车‘这个名字参数,然后通过工厂方法去生产,客户只关心最终的结果,至于是如何创建出来的,客户并不关心,你的各种配件还需要先创建这些类实例,最终才能将汽车给造出来。

如下图所示:

工厂方法模式:我们要创建一个开发者模式下的app,只需要将config_name传进工厂方法中即可,然后我们把日志等级的设置、加载配置信息、csrf保护、redis数据库的连接、404错误的处理以及蓝图的注册都封装在此工厂方法中,从而省去了每个对象都要去调用各种方法的臃肿代码量。

其实个人觉得编程最核心的就是将重复的操作用代码的规则让计算机不断的去执行,而工厂方法就是实现了一个代码的复用功能。当然如果是有不同的产品需求,我们也可以有不同的工厂方法。

# 工厂方法模式,manager传入不同参数,info就按照不同方法去执行配置环境
def create_app(config_name):
    # 创建一个flask实例对象
    app = Flask(__name__)
    config_cls = config_dict[config_name]

    # 从配置类中调用日志等级
    setup_logging(config_cls.LOG_LEVEL)

    # 从配置类中加载配置信息
    app.config.from_object(config_cls)

    # 为flask项目设置csrf保护
    # 生成csrf_token   
    CSRFProtect(app)

    # 将产生的session数据存储到redis数据库中
    Session(app)

    # db关联扩展app
    db.init_app(app)

    # 创建redis数据库
    global redis_stone
    redis_stone = redis.StrictRedis(host=config_cls.REDIS_HOST, port=config_cls.REDIS_PORT)

    from info.utils.commons import login_user_data

    # 自定义处理404错误
    @app.errorhandler(404)
    @login_user_data
    def handle_page_not_found(e):
        user = g.user
        return render_template('news/404.html', user=user)

    # 3.使用app注册蓝图
    from info.modules.index import index_blu
    from info.modules.passport import passport_blu
    from info.modules.news import news_blu
    from info.modules.profile import profile_blu
    from info.modules.admin import admin_blu

    app.register_blueprint(index_blu)
    app.register_blueprint(passport_blu, url_prefix='/passport')
    app.register_blueprint(news_blu, url_prefix='/news')
    app.register_blueprint(profile_blu, url_prefix='/user')
    app.register_blueprint(admin_blu, url_prefix='/admin')

    return app

二、建造者模式

讲一个复杂对象的构建与他的表示分离,使得同样的构建过程可以有不同的表示,举个例子:

点餐系统:假设点餐分为主食、酒水、甜品三类,这时我们会定义一个总的方法类,分别对应这三个类别,然后分别去到这些类别里面,然后根据不同食物创建不同类方法和属性,最终找到用户所输入的三种食物的价格、产品信息等属性最终展示给用户的一个过程。

优点:封装性好,系统容易扩展,容易实现‘流水线’,便于控制细节。

三、原型模式

所谓原型模式,即有一个原型对象,我们需要通过这个原型来创建一个副本,这是我们就可以用到原型模式,通过拷贝,注意深浅拷贝的不同,浅拷贝只是拷贝第一层引用,改变副本里面的代码时,很容易改变原模型对象的属性

优点:对于一些复杂对象的复用,使用原型模式会比较方便,没有那么多规则的约束。模型类的使用会减少内存的占用,对于一些需要频繁实例化对象的原型,选择模型类方法会更好。

四、单例模式

单例模式:确保类只有一个实例对象。为对象提供一个访问点,以使程序程序可以全局访问该对象,控制共享资源的访问。

经典实现:

class Singleton(object):
    __instance = None

    def __new__(cls):
        if not cls.__instance:
            cls.__instance = object.__new__(cls)
        return cls.__instance

测试代码:

s1 = Singleton()
s2 = Singleton()
print(id(s1))
print(id(s2))

测试id地址相同,只创建出一个实例化对象。