设计模式——单例模式

设计模式笔记

面向对象编程的基本概念

  • 封装

对象的行为对于外部世界是不可见的,是私密的

  • 多态
  1. 根据输入参数提供方法的不同实现
  2. 不同类型的对象可以使用相同的接口
  • 继承

继承表示一个类可以使用父类(基类)的大部分功能,被描述为一个重用基类中定义的功能并允许对原始软件的实现进行独立扩展的选项

class Base(object):
    def base():
        pass
    
 
class B(Base):
    def b():
        pass
    
b = B()
b.b()
b.base()
  • 抽象

将内部类的复杂实现抽象为一个接口,对于使用者而言,不需要考虑接口内部的具体实现,而只需要知道这个接口能干什么

class Adder(object):
    def __init__(self):
        self.sum = 0
        
    def add(self, value: int):
		self.sum += value
        
acc = Adder()
for i in range(99):
    acc.add(i)
print(acc.sum)
  • 组合

对象或类组合成一种更复杂的数据结构的一种方法,比如在一个对象中调用其它模块中的成员函数

class A(object):
    def a1(self):
        print("a1")
        
class B(object):
	def b(self):
        print("b")
        A().a1()

面向对象应该注意的几点原则

  • 开放/封闭原则

类或对象及其方法对于扩展来说,应该是开放的,但是对于修改来说,应该是封闭的

  • 控制反转原则

高层级的模块不依赖于底层级的模块,他应该都依赖于抽象,而不是抽象依赖于细节

  • 接口隔离原则

类不应该依赖于他没有用到的接口

  • 单一职责原则

一个类只完成一个功能,或者只有一个职责,即类的职责单一,引起类变化的原因单一

  • 替换原则

派生类必须完全取代基类

单例模式

介绍

单例模式的一句话来讲可能就是,一个类只有一个实例化对象,这个对象包含全局属性,可以在任何地方获得调用,并且在任意地方获得的这个类的实例都是一样的对象,其衍生出来的思路就有五种

UML类图

  1. 饿汉式,即在最开始就初始化这个对象,然后其它地方调用就直接返回这个对象即可,采用空间换时间的方法,优点是本身是线程安全的,缺点是占内存空间
  2. 懒汉式,即在第一次使用的时候才初始化这个对象,采用时间换空间的方法,需要借助外部的助力来实现线程安全,本身是线程不安全的
  3. Monostate变种单例模式,即一个类的实例可以有多个,但是不同的实例之间有相同的状态,即以这样的一种思路来理解的,面向对象的方法调用也就是对其维护的属性进行操作,那么实例之间属性状态相同的话,那么得到的操作结果也是一样的,一样的米饭,放到不同的电饭煲里面煮出来的都是能吃的饭,那么什么地方的电饭煲、是不是一样的电饭煲这类的考虑就不重要了
  4. 元类,在Python中有的,可以通过元类来实现单例模式下类的实例化对象的创建

实现

Python
  1. __new__的方式实现
# 以__new__的方式实现
class MySignelMode(object):
    
    def __new__(cls):
        if not hasattr(cls, "instance"):
            cls.instance = super(MySignelMode, cls).__new__(cls)
        else:
            return cls.instance
s = MySignelMode()
print("Obejct created:", s)
s1 = MySignelMode()
print("Obejct created:", s1)
Object create: <__main__.MySignleMode object at 0x0000016F9A6FA9E8>
Object create: <__main__.MySignleMode object at 0x0000016F9A6FA9E8>
  1. 懒汉模式(lazy_mode)
# 懒汉模式,类只在被需要的时候才创建,而避免先前创建好占用资源
class MyLazySignelMode(object):
    
    __instance = None
    
    def __init__(self):
        if not __instance:
            print("__init__ method call...")
        else:
            print("Instance already create:", self.getInstance())
            
    @classmethod
    def getInstance(cls):
		if not cls.__instance:
            cls.__instance = MyLazeSignelMode()
         return cls.__instance
   


s = MyLazeSignelMode()
print("Object create:", MyLazySignelMode.getInstance())
s1 = MyLazeSignelMode()
__init__ method called..
__init__ method called..
Object created: <__main__.MyLazeSignelMode object at 0x0000021BBEB6A518>
Instance already created: <__main__.MyLazeSignelMode object at 0x0000021BBEB6A518>
  1. Monostate变种单例模式
# python中可以借用__dict__来实现这一功能,使得不同的对象之间拥有相同的状态
class MyMonostateMode(object):
	
    __share_state = {}
    
    def __init__(self):
		self.x = 0
        self.__dict__ = MyMonostateMode.__share_state
        
m1 = MyMonostateMode()
m2 = MyMonostateMode()
m1.x = 5
print("Object create m1:", id(m1))
print("Object create m2:", id(m2))

print("Object state m1:", m1.__dict__)
print("Obejct state m2:", m2.__dict__)

print("Object value m1:", m1.x)
print("Object value m2:", m2.x)
Object create m1: 1594109045224
Object create m2: 1594109045168
Object state m1: {'x': 5}
Obejct state m2: {'x': 5}
Object value m1: 5
Object value m2: 5
  1. 元类
# 利用python的元类来实现单例对象的创建
class MyMetaSignelMode(type):
	
    _instances = {}
    
    def __call__(self, *args, **kwargs):
		if self not in _instances:
            self._instance[self] = super(MyMetaSignelMode, self).__call__(*args, **kwargs)
         return self._instance[self]
    
class log(metaclass=MyMetaSignelMode):
    pass

l1 = log()
l2 = log()

print("Object create l1:", l1)
print("Object create l2:", l2)
Object create l1: <__main__.log object at 0x000001B7C53BA9E8>
Object create l2: <__main__.log object at 0x000001B7C53BA9E8>
C++
// 饿汉模式,一开始就创建了实例,空间换时间
#include<iostream>
#include<mutex>

using namespace std;

class Signelton{
private:
    Signelton(){}

public:
    // 懒汉获取对象实例
    static Signelton* GetInstance(){
        static Signelton instance;
        return &instance;
    }
    // 重载运算符
    ostream& operator <<(const Signelton *instance){
        cout<<"This object id "<<(Signelton*)(instance)<<"\n";
        return cout;
    }
    
};


int main(int argc, char *argv[]){
    Signelton *s1 = Signelton::GetInstance();
    Signelton *s2 = Signelton::GetInstance();

    *s1<<s1;
    *s2<<s2;
    return 0;
}
This object id 0x7ff734e730c0
This object id 0x7ff734e730c0S
//懒汉模式,线程安全的
#include<iostream>
#include<mutex>

using namespace std;

class Signelton{
private:
    Signelton(){}

public:
    // 懒汉获取对象实例
    static Signelton* GetInstance(){
        
        if(instance == nullptr)
        {
            __mutex.lock();   // 上锁
            if(instance == nullpt)
            	instance = new Signelton();
        	__mutex.unlock(); // 解锁
        }
        return instance; 
    }
    // 重载运算符
    ostream& operator <<(ostream &o){
        o<<"This object id"<<(Signelton*)(instance)<<"\n";
        return o;
    }

private:
    static Signelton *instance; // 定义的static变量应该在类外部进行一个声明
    static mutex __mutex;
};

Signelton * Signelton::instance = nullptr;
mutex Signelton::__mutex;

int main(int argc, char *argv[]){
    Signelton *s1 = Signelton::GetInstance();
    Signelton *s2 = Signelton::GetInstance();

    *s1<<cout;
    *s2<<cout;
    return 0;
}
This object id0x26dc6011770
This object id0x26dc6011770
Java
// 懒汉式
public class Signelton {

    private static Signelton instance = null;

    private Signelton(){

    }

    public static synchronized Signelton getInstance(){
        if(instance == null) instance = new Signelton();
        return instance;
    }

    public static void main(String[] args) {
        Signelton s1 = Signelton.getInstance();
        Signelton s2 = Signelton.getInstance();
        System.out.println("Object s1:"+s1);
        System.out.println("Object s2:"+s2);
    }
}
Object s1:Compilter.Signelton@5fd0d5ae
Object s2:Compilter.Signelton@5fd0d5ae
// 饿汉式
public class Signelton {

    private static Signelton instance = new Signelton();

    private Signelton(){

    }

    public static Signelton getInstance(){
        return instance;
    }

    public static void main(String[] args) {
        Signelton s1 = Signelton.getInstance();
        Signelton s2 = Signelton.getInstance();
        System.out.println("Object s1:"+s1);
        System.out.println("Object s2:"+s2);
    }
}
Object s1:Compilter.Signelton@5fd0d5ae
Object s2:Compilter.Signelton@5fd0d5ae
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值