首页 > 其他分享 >设计模式简介及单例模式

设计模式简介及单例模式

时间:2022-11-09 17:22:09浏览次数:48  
标签:__ .__ 简介 self 模式 单例 Mysql 设计模式

目录

设计模式简介及单例模式

1.设计模式
	前人通过大量的验证创建出来解决一些问题的固定高效方法
2.IT行业
	设计模式分为三大类,总共23种模式
        创建型模式(5种):工厂方法模式、抽象工厂模式、单例模式、建造者模式、原型模式
        结构型模式(7种):适配器模式、装饰器模式、代理模式、外观模式、桥接模式、组合模式、享元模式
        行为型模式(11种):策略模式、模板方法模式、观察者模式、迭代子模式、责任链模式、命令模式、备忘录模式、状态模式、访问者模式、中介者模式、解释器模式
 	
3.单例模式
	类加括号无论执行多少次永远只会产生一个对象
 	目的:
        当类中有很多非常强大的方法 我们在程序中很多地方都需要使用
        如果不做单例 会产生很多无用的对象浪费存储空间
        我们想着使用单例模式 整个程序就用一个对象

设计模式的23种方法图如下:

image

单例模块实现的多种方式

方式一:绑定给类的方法

class MyClass:
    __instance = None

    def __init__(self,name,age):
        self.name = name
        self.age = age

    @classmethod
    def singleton(cls):
        if not cls.__instance:  # 判断全局的__instance是否有值
            cls.__instance = cls('kimi',18)
        return cls.__instance

# 1 单例模式下,执行多少次的类名加括号都只会产生一个对象
obj1 = MyClass.singleton()
obj2 = MyClass.singleton()
obj3 = MyClass.singleton()
print(id(obj1),id(obj2),id(obj3))  # 1467506641648 1467506641648 1467506641648

# 2.要是想产生新的对象,需要在类调用的时候传入新的数据
obj4 = MyClass('rose', 22)
obj5 = MyClass('kiki', 19)
print(id(obj4),id(obj5))  # 1582454534352 1582454534640
"""  这样的单例模式,扩展性更强一些"""

方式二:基于元类的类名加括号

class Mymeta(type):
    def __init__(self,name,bases,dict):  # 定义一个类MYsql时就触发
        # 事先从配置文件种配置来造一个Mysql的实例出来
        self.__instance = object.__new__(self)  #产生一个对象
        self.__init__(self.__instance,'kimi',18) # 给空对象初始化数据
        # 上面两步可以合成下面一步
        # self.__instance = super().__call__(*args,**kwargs)
        super().__init__(name,bases,dict)


    def __call__(self, *args, **kwargs):  # Mysql(...)时触发
        if args or kwargs:   # 判断args or kwargs 是否有值
            obj = object.__new__(self)
            self.__init__(obj,*args,**kwargs)
            return  obj  # 传值说明我们要用新的对象
        return self.__instance  # 不传值说明我们要用单例的值


class Mysql(metaclass=Mymeta):  #不用创建对象也能触发__init__方法,因为时元类干扰了创建类的过程。 类名加括号 触发__call__方法
    def __init__(self,name,age):
        self.name = name
        self.age = age

 # 1 单例模式下,执行多少次的类名加括号都只会产生一个对象
print(Mysql.__dict__)  # {.....'_Mymeta__instance': <__main__.Mysql object at 0x00000268A06A4AF0>}
obj1 = Mysql()
obj2 = Mysql()
print(id(obj1),id(obj2))  # 1994724494064 1994724494064

 # 2.要是想产生新的对象,需要在类调用的时候传入新的数据
obj4 = Mysql('rose', 25)
obj5 = Mysql('kiki', 15)
print(id(obj4),id(obj5))   # 2000220058336 2000220058288

方式三:基于模块的单例模式

"""要是通过类的方式去调,比如func1(self),说万一要传东西,而self是绑定给对象的方法,类是不能直接调的"""
>>>把下述当作模块,通过模块点obj的形式调用
'''基于模块的单例模式:提前产生一个对象 之后导模块使用'''
class C1:
    def __init__(self,name,age,gender):
        self.name = name
        self.age = age
        self.gender = gender

    def func1(self):pass
    def func2(self):pass
    def func3(self):pass
    def func4(self):pass

obj = C1('kimi',22,'female')
# 把上述当作模块,通过模块点obj的形式调用

另一个模块去点
from django.conf  import settings

方式四:定义一个装饰器实现单例模式

def singleton(cls):  # cls = Mysql
    __instance = cls('kimi',18)
    def wrapper(*args,**kwargs):  # 判断Mysql()括号里面有没有参数
        if args or kwargs:  #
            obj = cls(*args,**kwargs)
            return obj  # 有值就会产生一个新的对象
        return __instance  # 没有值就会返回装饰器给的对象
    return wrapper

@singleton # Mysql = singleton(Mysql)
class Mysql:
    def __init__(self,name,age):
        self.name = name
        self.age = age

# 1 单例模式下,括号里面不传参数,执行多少次的类名加括号都只会产生一个对象
obj1 = Mysql()
obj2 = Mysql()
obj3 = Mysql()
print(obj3 is obj2 is obj1)  # True

# 2.要是想产生新的对象,需要在类调用的时候传入新的数据
obj4 = Mysql('kiki',20)
obj5 = Mysql('rose',18)
print(obj5 is obj4)  # False

方法五:基于元类

class MyMetaClass(type):
    def __call__(self, *args, **kwargs):
        if not self.instance:
            obj = self.__new__(self)  # 创建一个空对象
            self.__init__(obj)  # 调用__init__给对象添加独有的数据
            self.instance = obj    # 创建新的对象
        return self.instance # 返回类中定义好的intance

class C1(metaclass=MyMetaClass):
    instance = None

obj1 = C1()
obj2 = C1()
obj3 = C1()
print(id(obj1),id(obj2),id(obj3))  # 1992688159568 1992688159568 1992688159568

# 利用反射来做

标签:__,.__,简介,self,模式,单例,Mysql,设计模式
From: https://www.cnblogs.com/zhanglanhua/p/16874499.html

相关文章

  • 单例模式、pickle模块、选课系统
    今日内容概要单列模式实现的多种方式pickle序列化模块选课系统需求分析选课系统架构设计选课系统目录搭建选课系统功能搭建选课系统管理员功能今日内容详细......
  • 设计模式利剑14-迭代器模式
    定     义:它提供一种方法访问一个容器对象中各个元素,而又不需暴露该对对象的内部细节,,Iterator模式就是分离了集合对象的遍历行为,抽象出一个迭代器类来负责,这样既可以......
  • 设计模式利剑17-门面模式
    定     义:要求一个子系统的外部与其内部的通信必须通过一个统一的对象进行,门面模式提供一个高层次的接口,使得子系统更易于使用优     点:           ......
  • 设计模式利剑22--享元模式
    定     义:使用共享对象可以有效地支持大量的细粒度的对象,享元模式可以避免大量非常相似类的开销。在程序设计中有时需要生成大量细             粒度的......
  • 多种方法实现单例模式 pickle模块
    目录单例模式类方法@classmethod实现元类实现模块实现装饰器实现双下call、反射实现pickle序列化模块单例模式类方法@classmethod实现classC1:__instance=None......
  • Kubernetes集群YAML文件简介
    概述k8s集群中对资源管理和资源对象编排部署都可以通过声明样式(YAML)文件来解决,也就是可以把需要对资源对象操作编辑到YAML格式文件中,我们把这种文件叫做资源清单文件,通......
  • Kubernetes集群管理工具kubectl简介
     概述kubectl是Kubernetes集群的命令行工具,通过kubectl能够对集群本身进行管理,并能够在集群上进行容器化应用的安装和部署 命令格式kubectl[command][type][na......
  • js设计模式-类式继承
    js中怎么实现类式继承呢?首先声明父类,在声明子类,然后将父类的实例赋予给子类的原型就可以了。假设父类长这样:varBook=function(id,name,price){//私有的属性......
  • 设计模式汇总
    基础​​UML各种图总结​​​​依赖、关联、聚合和组合之间的区别​​设计模式的原则​​设计模式七大原则​​创建型​​简单工厂模式​​​​工厂方法模式​​​​抽象工......
  • php 设计模式
    <?php//协程生成器函数并发classTest{publicfunctionasync(){$start=microtime(true);$url="https://money.finance.sina.com.c......