设计模式

Posted _慕

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了设计模式相关的知识,希望对你有一定的参考价值。

 一 单例设计模式

    单例模式提供了这样一个机制,确保类有且只有一个特定类型的对象,并提供全局访问点。

  适用情形:日志记录、数据库操作、打印机后台处理程序等,上述程序运行过程中只生成一个实例,避免对同一资源产生相互冲突的请求。

  我们希望使用一个数据库对象对数据库进行操作,以维护数据的一致性;或者希望使用同一个日志对象,将多项服务的日志信息按照顺序转储到一个特定文件中。

class Singletom(object):
    def __new__(cls, *args, **kwargs):
        if not hasattr(cls,‘_instance‘):
            cls._instance = super(Singletom,cls).__new__(cls)
        return cls._instance
s = Singletom()
print(s)           # <__main__.Singletom object at 0x000000000214B400>
s1 = Singletom()
print(s1)          # <__main__.Singletom object at 0x000000000214B400>

  通过覆盖__new__方法(Python 用于创建实例 self 的特殊方法)来控制对象创建。对象 s 就是由__new__方法创建的,在创建之前会检查对象是否存在。

  方法hasattr(Python 的特殊方法,用来了解对象是否具有某个属性)用于查看对象是否有_instance属性,该属性的作用是检查该类是否已经生成了一个对象。当对象s1被请求的时候,hasattr( )发现对象已经存在,所以s1对象将被分配已有的对象实例(地址位于 0x000000000214B400)。

  单例模式懒汉式实例化

    单例模式的用例之一就是懒汉式实例化,在导入模块的时候,我们可能会无意中创建一个对象,但是当时根本用不到它。懒汉式实例化能确保在实际需要的时候才创建对象。

  懒汉式实例化是一种节约资源并仅在需要的时候创建它们

  在下面的代码中,s = Singletom( ) 时,它会调用__init__方法,但没有新对象被创建。

  然而,实际对象创建发生在调用Singletom.getInstance( )的时候,我们正是通过这种方式来实现懒汉式实例化的。

class Singletom(object):
    __instance = None
    def __init__(self):
        if not Singletom.__instance:
            print(‘__init__ method called . .‘)
        else:
            print(‘Instance already created: ‘,self.__instance)
    @classmethod
    def getInstace(cls):
        if not cls.__instance:
            cls.__instance = Singletom()
        return cls.__instance
s = Singletom()
print(‘Object created‘,Singletom.getInstace())
s1 = Singletom()
# 输出如下:
# __init__ method called . .
# __init__ method called . .
# Object created <__main__.Singletom object at 0x0000000002ABD400>
# Instance already created:  <__main__.Singletom object at 0x0000000002ABD400>

  模块级别的单例模式

# mysingleton.py
class My_Singleton(object):
    def foo(self):
        pass
  
my_singleton = My_Singleton()
  
# to use
from mysingleton import my_singleton
  
my_singleton.foo()

  单例模式的缺点

  • 全局变量可能在某处已经被修改,但是开发人员仍然认为它们没有发生变化,而该变量还在应用程序中的其他位置被使用。
  • 可能会对同一对象创建多个引用
  • 所有依赖全局变量的类都会由于一个类的改变而紧密耦合为全局数据,从而可能在无意中影响另一个类。

 二 工厂模式

1.简单工厂模式

  父类规定必须要继承的方法,父类自己不实现,子类需要继承该方法。

技术分享图片
from abc import ABCMeta,abstractclassmethod

class Animal(metaclass=ABCMeta):
    @abstractclassmethod
    def do_say(self):
        pass

class Dog(Animal):
    def do_say(self):
        print(Wang Wang)

class Cat(Animal):
    def do_say(self):
        print(miao miao)

class ForestFactory(object):
    def make_sound(self,object_type):
        return eval(object_type)().do_say()

if __name__ == __main__:
    ff = ForestFactory()
    animal = input(Which animal should make_sound Dog or Cat ?)
    ff.make_sound(animal)
简单工厂模式
2.工厂方法模式

  定义一个用于创建对象的接口(工厂接口),让子类决定实例化哪一个产品类。

  即 每个子类都有一个对应的工厂方法。

技术分享图片
from abc import abstractmethod, ABCMeta


class Payment(metaclass=ABCMeta):
    @abstractmethod
    def pay(self, money):
        pass


class Alipay(Payment):
    def pay(self, money):
        print("支付宝支付%s元" % money)


class ApplePay(Payment):
    def pay(self, money):
        print("苹果支付%s元"%money)


class PaymentFactory(metaclass=ABCMeta):
    @abstractmethod
    def create_payment(self):
        pass


class AlipayFactory(PaymentFactory):
    def create_payment(self):
        return Alipay()

class ApplePayFactory(PaymentFactory):
    def create_payment(self):
        return ApplePay()

# 用户输入
# 支付宝,120

af = AlipayFactory()
ali = af.create_payment()
ali.pay(120)
工厂方法
3.抽象工厂模式

  定义一个工厂类接口,让工厂子类来创建一系列相关或相互依赖的对象。

技术分享图片
from abc import abstractmethod, ABCMeta

# ------抽象产品------
class PhoneShell(metaclass=ABCMeta):
    @abstractmethod
    def show_shell(self):
        pass

class CPU(metaclass=ABCMeta):
    @abstractmethod
    def show_cpu(self):
        pass

class OS(metaclass=ABCMeta):
    @abstractmethod
    def show_os(self):
        pass


# ------抽象工厂------

class PhoneFactory(metaclass=ABCMeta):
    @abstractmethod
    def make_shell(self):
        pass

    @abstractmethod
    def make_cpu(self):
        pass

    @abstractmethod
    def make_os(self):
        pass


# ------具体产品------


class SmallShell(PhoneShell):
    def show_shell(self):
        print("普通手机小手机壳")

class BigShell(PhoneShell):
    def show_shell(self):
        print("普通手机大手机壳")

class AppleShell(PhoneShell):
    def show_shell(self):
        print("苹果手机壳")


class SnapDragonCPU(CPU):
    def show_cpu(self):
        print("骁龙CPU")


class MediaTekCPU(CPU):
    def show_cpu(self):
        print("联发科CPU")


class AppleCPU(CPU):
    def show_cpu(self):
        print("苹果CPU")


class android(OS):
    def show_os(self):
        print("Android系统")


class ios(OS):
    def show_os(self):
        print("iOS系统")


# ------具体工厂------

class MiFactory(PhoneFactory):
    def make_cpu(self):
        return SnapDragonCPU()

    def make_os(self):
        return Android()

    def make_shell(self):
        return BigShell()


class HuaweiFactory(PhoneFactory):
    def make_cpu(self):
        return MediaTekCPU()

    def make_os(self):
        return Android()

    def make_shell(self):
        return SmallShell()


class IPhoneFactory(PhoneFactory):
    def make_cpu(self):
        return AppleCPU()

    def make_os(self):
        return IOS()

    def make_shell(self):
        return AppleShell()


# ------客户端------


class Phone:
    def __init__(self, cpu, os, shell):
        self.cpu = cpu
        self.os = os
        self.shell = shell

    def show_info(self):
        print("手机信息:")
        self.cpu.show_cpu()
        self.os.show_os()
        self.shell.show_shell()


def make_phone(factory):
    cpu = factory.make_cpu()
    os = factory.make_os()
    shell = factory.make_shell()
    return Phone(cpu, os, shell)

p1 = make_phone(HuaweiFactory())
p1.show_info()
抽象工厂模式

 

以上是关于设计模式的主要内容,如果未能解决你的问题,请参考以下文章

十条实用的jQuery代码片段

尝试使用片段保存夜间模式状态

如何更改谷歌地图标记上方的标题和片段设计

炫酷 CSS 背景效果的 10 个代码片段

添加片段时的 FlyOut 菜单设计问题

高效Web开发的10个jQuery代码片段