第二十二天

Posted ztx695911088

tags:

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

单例模式

 

"""
单例模式:当希望一个类只有一个实例存在的时候,会使用单例模式。
应用场景:数据库连接。
数据库:有用户名,有密码:如果都使用的是相同的用户名和相同密码,
那么进入的就是同一个数据库,产生数据库连接对象
数据库连接之后,可以对数据库中的表进行操作
"""
class Connection:
pass
p1=Connection()
p2=Connection()
print(p1 is p2)

# 大概的思路:当创建对象的时候,先判断一下,对象是否已存在,
# 如果已存在则返回当前对象即可,如果不存在就创建一个新的对象。

# 在pythonn中实现单例模式方法:
"""
1. 使用模块
2. 使用__new__
3. 使用装饰器
4. 使用元类
"""

1. 使用模块:python本身纯天然就是单例模式。这是python独有。
# 当使用import或者是from都会执行模块中的代码,但是只执行一次
# 在当前的py文件中使用的my永远只有一个。
# from day22.another import my
# my.foo()

2. 使用__new__
# __new__是用来创建对象的。
 class MySingleton:
     _instance=None
     def __init__(self,x):
         self.x=x
     def __new__(cls,*args,**kwargs):
         # 判断是否应存在对象了
         if not cls._instance:
             # 创建新的对象
             print("创建一个新的对象")
             cls._instance=super().__new__(cls,*args,**kwargs)
         else:
             print("没有创建新的对象")
         return cls._instance
 one=MySingleton(1)  # 先执行new,再执行init
 two=MySingleton(2)  # two=one
 print(id(one),id(two))
 print(one is two)
 print(one.x)
 print(two.x)
 3.使用装饰器
定义一个装饰器,里面只返回单独的一个对象,在需要使用单例模式创建的类上面加装饰器。
# on_duty=check_in(on_duty)
# @check_in
# class A:
# pass
# A()
# A=check_in(A)
# A()

# 只要去把装饰器函数中的inner方法里,实现创建同一个对象的功能。
from functools import wraps
def singleton(cls):
    _instance={} # 类名:对象
    @wraps(cls)
    def inner(*args,**kwargs):
        if cls not in _instance:
            _instance[cls]=cls(*args,**kwargs)
        print("instance的值",_instance)
        return _instance[cls]
    return inner
@singleton  #A=singleton(A)
class A:
pass
a1=A()
a2=A()
@singleton #B=singleton(B)
class B:
pass
b=B()
print(A.__name__)
print(a1 is a2)
print(id(a1),id(a2))


4. 使用元类
创建类的类是元类,在元类中有__call__
# a=A()
# a()
# print(type(a))
class Singleton(type):
    _instance={}
    def __call__(cls, *args, **kwargs):
        if cls not in cls._instance:
            cls._instance[cls]=super().__call__(*args, **kwargs)
        return cls._instance[cls]
class A(metaclass=Singleton):
pass
a1=A()
a2=A()
print(a1 is a2)
print(id(a1),id(a2))

# 适用性:1.当资源共享的情况下,希望创建的对象只有一个,避免资源的浪费。数据库连接。
# 2.线程池


适配器、桥接、装饰、组合(mix_in)
"""
结构型模式:类和类之间的关系
适配器、桥接、装饰、组合(mix_in)
"""


1. 适配器:当已有的功能可以使用,但是接口和调用者不匹配,需要用适配器。
# 中国球员:前锋、中锋、后卫
# 目标:需要进行是配的对象(外籍中锋)
# 适配器:需要要是配的对象转换成可以使用的类(方式)
class Player:
def attack(self):
pass

def defense(self):
pass


class Forward(Player):
def __init__(self, name):
self.name = name

def attack(self):
print("前锋{}在进攻".format(self.name))

def defense(self):
print("前锋{}在防御".format(self.name))


class Center(Player):
def __init__(self, name):
self.name = name

def attack(self):
print("中锋{}在进攻".format(self.name))

def defense(self):
print("中锋{}在防御".format(self.name))


# 需要被适配的类
class ForginCenter:
def __init__(self, name):
self.name = name

def forginAttack(self):
print("外籍中锋{}在进攻".format(self.name))

def forgindefense(self):
print("外籍中锋{}在防御".format(self.name))


class Guards(Player):
def __init__(self, name):
self.name = name

def attack(self):
print("后卫{}在进攻".format(self.name))

def defense(self):
print("后卫{}在防御".format(self.name))


# 需要一个适配器,希望下面调用ForginCenter的时候,也希望使用attack、defense
class Translator(Player):
    def __init__(self, name):
        self.name = name
        self.forginCenter = ForginCenter(self.name)

    def attack(self):
        self.forginCenter.forginAttack()

    def defense(self):
        self.forginCenter.forgindefense()
f = Forward("孙悦")
# c=Center("张飞")
c = Translator("奥尼尔")
g = Guards("巩振")
f.attack()
f.defense()
c.attack()
c.defense()
g.attack()
g.defense()

# 使用场景
# 希望使用一个已经存在的类,而它的接口(方法),不符合我们的需求。
# 希望复用一些现存存类,方式跟已有的也不同。


"""
桥接模式:把抽象化和实现化解耦,使得二者独立。接口模式
当使用继承解决问题时,需要创建大量的子类。
"""


# N品牌的手机运行游戏
# class Handsetgame:
# def run(self):
# pass
# class HandsetNgame(Handsetgame):
# def run(self):
# print("正在运行N品牌的手机游戏")
#
# class HandsetMgame(Handsetgame):
# def run(self):
# print("正在运行M品牌的手机游戏")
# ng=HandsetNgame()
# mg=HandsetMgame()
# ng.run()
# mg.run()


# 继续加需求,手机还有通讯录的功能
# class Phone:
# pass
# class MPhone(Phone):
# pass
# class NPhone(Phone):
# pass
# # class Handsetgame:
# # def run(self):
# # pass
# class HandsetNgame(NPhone):
# def run(self):
# print("正在运行N品牌的手机游戏")
#
# class HandsetMgame(MPhone):
# def run(self):
# print("正在运行M品牌的手机游戏")
#
#
# class PhoneNaddress(NPhone):
# def insert(self):
# print("N手机添加通讯录")
# def delete(self):
# print("N手机删除通讯录")
#
#
# class PhoneMaddress(MPhone):
# def insert(self):
# print("M手机添加通讯录")
# def delete(self):
# print("M手机删除通讯录")
#
# ng=HandsetNgame()
# mg=HandsetMgame()
# ng.run()
# mg.run()
#
# na=PhoneNaddress()
# na.insert()
# na.delete()

# 如果再增加功能,需要继承非常多的子类。需要使用到桥接模式。
# 手机---类 游戏、通讯录、MP3(软件)---类
class Soft:
pass


class Address(Soft):
def run(self):
print("运行通讯录")


class Game(Soft):
def run(self):
print("正在运行游戏")


class Mp3(Soft):
def run(self):
print("MP3正在运行")

class Phone:
    def __init__(self):
        self.name = None

    def setSoft(self, soft):
        self.soft = soft

    def run(self):
        print(self.name + "正在", end="")
        self.soft.run()

class Mphone(Phone):
def __init__(self):
super().__init__()
self.name = "M手机"


class Nphone(Phone):
def __init__(self):
super().__init__()
self.name = "N手机"


class Sphone(Phone):
def __init__(self):
super().__init__()
self.name = "S手机"


mp = Mphone()
a = Address()
mp.setSoft(a)
mp.run()
mp.setSoft(Game())
mp.run()

np = Nphone()
np.setSoft(Address())
np.run()
np.setSoft(Game())
np.run()

# 加MP3功能
np.setSoft(Mp3())
np.run()

# 多一款手机S
sp = Sphone()
sp.setSoft(Mp3())
sp.run()

桥接模式:两个类之间 ,存在一定的依赖关系,但是两个类增加子类非常灵活,非常多。


装饰模式:想一个现有对象上添加功能,而且按照添加功能的顺序执行,又不改变原对象的结构。
# 小明穿衣服
# class People:
# def __init__(self,name):
# self.name=name
# class AbstractCloth:
# def show(self):
# pass
# class Underwear(AbstractCloth):
# def show(self):
# print("[背心]")
# class Tshirt(AbstractCloth):
# def show(self):
# print("[衬衫]")
# class Sweater(AbstractCloth):
# def show(self):
# print("[毛衣]")
# p=People("小明")
# print("小明穿着:")
# sw=Sweater()
# sw.show()
# underwear=Underwear()
# underwear.show()
# tshirt=Tshirt()
# tshirt.show()

# 使用装饰模式实现
# 被装饰的类


class People:
    def __init__(self, name):
        self.name = name

    def show(self):
        return "{}穿着:".format(self.name)


class Decorator:
    def __init__(self, people):
        self.people = people


class AbstractCloth(Decorator):
    pass


class Underwear(AbstractCloth):
    def show(self):
        return self.people.show() + "[背心]"


class Tshirt(AbstractCloth):
    def show(self):
        return self.people.show() + "[衬衫]"
p = People("张三")
underwearp = Underwear(p)
tshirtP = Tshirt(underwearp)
print(tshirtP.show())

"""
优点:装饰器类和被装饰的类可以独立发展,扩展原有的类的时候,不需要修改原来类的内容
缺点:多层装饰器比较复杂
适用:动态的增加功能。对类进行动态的扩展
"""

"""
mix_in Mixin: 组合模式的特例,整体部分模式。 把一些主体部分跟附加的部分整合起来。
"""


# 茶、牛奶,加糖的牛奶。
# 多继承
class Drink:
pass


class Milk(Drink):
def __init__(self):
self.name = "牛奶"
self.price = 5


# 附属品是mix_in
# 使用mix_in模式的时候,附属品一定是不能单独被实例化。一定没有init方法
class MininSuger:
def addName(self):
return "_糖"

def addPrice(self):
return 2


class MixinSalt:
def addSaltName(self):
return "_盐"

def addSaltPrice(self):
return -1


# 采用多继承实现min_in模式,注意,主体放在前面,
# 附属品放在后面,为了简洁,名字尽量不要重复

class MilkSuger(Milk, MininSuger, MixinSalt):
def get_name(self):
return self.name + self.addName() + self.addSaltName()

def get_price(self):
return self.price + self.addPrice() + self.addSaltPrice()


ms = MilkSuger()
print(ms.get_name())
print(ms.get_price())

"""
适用性:
1. 需要表名整体-部分结构,一个是主体,N个附属品,附属品是mix_in
2. 对于主体部分可以单独创建, 对于附属品,业务上不可以单独创建。

优点:客户端调用方便
缺点:最终的mix_in都是实现类,都不是接口,会违反依赖倒置原则。

注意:
1. 是python这种多继承的语言才有的模式
2. mix_in不定义init方法
3. mix_in尽量精简
4.关系上,子类即使没有继承mix_in,也可以单独存在(主体部分可以独立存在)
mix_in没有主体,不能被执行
5. 继承的顺序尽量让mix_in放在后面,同时还要尽量避免同名函数。
6. 只有一个主体类,其他都是mix_in
7. mixin不能继承非mixin类
"""

 


























































































































































































































































































































































以上是关于第二十二天的主要内容,如果未能解决你的问题,请参考以下文章

二刷java基础第二十二天——反射

菜鸟学Python第二十二天

学习python课程第二十二天

华为实习日记——第二十二天

软件课设第二十二天 9.9

第二十二天