设计模式2—结构型模式

目录

1.适配器模式(Adapter)

2.代理模式(Proxy)

3.装饰模式(Decorator)

4.桥模式(Bridge、多维度)

5.组合模式(Composite)  

6.外观模式

7.享元模式(Flyweight)


1.适配器模式(Adapter)

意图:

将一个类的接口转换成客户希望的另外一个接口。

使得原本由于接口不兼容而不能一起工作的那些类可以一起工作。 

适用性:

你想使用一个已经存在的类,而它的接口不符合你的需求。

你想创建一个可以复用的类,该类可以与其他不相关的类或不可预见的类(即那些接口可能不一定兼容的类)协同工作。

你想使用一些已经存在的子类,但是不可能对每一个都进行子类化以匹配它们的接口。对象适配器可以适配它的父类接口。(仅适用于对象Adapter )

基本思想:

适配器模式(Adapter)包含以下主要角色。

1.目标(Target)接口:当前系统业务所期待的接口,它可以是抽象类或接口。

2.适配者(Adaptee)类:它是被访问和适配的现存组件库中的组件接口。

3.适配器(Adapter)类:它是一个转换器,通过继承或引用适配者的对象,把适配者接口转换成目标接口,让客户按目标接口的格式访问适配者。

'''1.adapter model'''
# ForeignCenter-->Translator
# 使得原本由于接口不兼容而不能一起工作的那些类可以一起工作

#球员类
class Player():
    name=''
    def __init__(self,name):
        self.name=name
    def Attack(self,name):
        pass
    def Defense(self):
        pass

#前锋
class Forwards(Player):
    def __init__(self,name):
        Player.__init__(self,name)
    def Attack(self):
        print('%s Attack'%self.name)
    def Defense(self):
        print('%s Defense'%self.name)

#中锋(目标类)
class Center(Player):
    def __init__(self,name):
        Player.__init__(self,name)
    def Attack(self):
        print('%s Attack'%self.name)
    def Defense(self):
        print('%s Defense'%self.name)
#后卫
class Guards(Player):
    def __init(self,name):
        Player.__init__(self,name)
    def Attack(self):
        print('%s Attack'%self.name)
    def Defense(self):
        print('%s Defense'%self.name)

#外籍中锋(待适配类)
class ForeignCenter(Player):
    name=''
    def __init__(self,name):
        Player.__init__(self,name)
    def ForeignAttack(self):
        print('Foreign %s Attack'%self.name)
    def ForeignDefense(self):
        print('Foreign %s Defense'%self.name)
        
#翻译(适配类)
class Translator(Player):
    foreigncenter=None
    def __init__(self,name):
        self.foreigncenter=ForeignCenter(name)
    def Attack(self):
        self.foreigncenter.ForeignAttack()
    def Defense(self):
        self.foreigncenter.ForeignDefense()
        
   
def adapter_model():
    a=Forwards('A')
    b=Guards('B')
    c=Translator('C')
    
    a.Attack()
    b.Defense()
    c.Attack()
    b.Attack()

if __name__=='__main__':
    adapter_model()

2.代理模式(Proxy)

意图:

由于某些原因需要给某对象提供一个代理以控制对该对象的访问。

这时,访问对象不适合或者不能直接引用目标对象,代理对象作为访问对象和目标对象之间的中介。

适用性:

代理模式在客户端与目标对象之间起到一个中介作用和保护目标对象的作用;

代理对象可以扩展目标对象的功能;

代理模式能将客户端与目标对象分离,在一定程度上降低了系统的耦合度;

基本思想:

代理模式的主要角色如下。

1.抽象主题(Subject)类:通过接口或抽象类声明真实主题和代理对象实现的业务方法。

2.真实主题(Real Subject)类:实现了抽象主题中的具体业务,是代理对象所代表的真实对象,是最终要引用的对象。

3.代理(Proxy)类:提供了与真实主题相同的接口,其内部含有对真实主题的引用,它可以访问、控制或扩展真实主题的功能。

'''2.proxy model'''
#为其他对象提供一种代理以控制对这个对象的访问。
class sender_base:
    def __init__(self):
        pass
    def send_sth(self,sth):
        pass
class send_class(sender_base):
    def __init__(self,receiver):
        self.receiver=receiver
    def send_sth(self,sth):
        print('SEND'+sth+'TO'+self.receiver.name)
#agent代理sender的服务,给receive发送消息        
class agent_class(sender_base):
    def __init__(self,receiver):
        self.send_obj=send_class(receiver)
    def send_sth(self,sth):
        self.send_obj.send_sth(sth)
        
class receive_class:
    def __init__(self,someone):
        self.name=someone


def proxy_model():
    receiver=receive_class('交换设备维护班')
    agent=agent_class(receiver)
    agent.send_sth('高频告警')
    
    print(receiver.__class__)
    print(agent.__class__)

if __name__=='__main__':
    proxy_model()

3.装饰模式(Decorator)

意图: 

动态地给一个对象添加一些额外的职责。就增加功能来说,Decorator 模式相比生成子类更为灵活。

适用性:

1.在不影响其他对象的情况下,以动态、透明的方式给单个对象添加职责。

2.处理那些可以撤消的职责。

3.当不能采用生成子类的方法进行扩充时。

一种情况是,可能有大量独立的扩展,为支持每一种组合将产生大量的子类,使得子类数目呈爆炸性增长。

一种情况是,因为类定义被隐藏,或类定义不能用于生成子类。

基本思想:

装饰模式主要包含以下角色。

1.抽象构件(Component)角色:定义一个抽象接口以规范准备接收附加责任的对象。

2.具体构件(Concrete    Component)角色:实现抽象构件,通过装饰角色为其添加一些职责。

3.抽象装饰(Decorator)角色:继承抽象构件,并包含具体构件的实例,可以通过其子类扩展具体构件的功能。

3.具体装饰(ConcreteDecorator)角色:实现抽象装饰的相关方法,并给具体构件对象添加附加的责任。

'''3.decorator model'''
class room(object):
    def func1(self):
        print('功能模块1')
    def func2(self):
        print('功能模块2')
        
class room_decorator(object):
    def __init__(self,decoratee):
        self._decoratee=decoratee
    def func3(self):
      # 在功能1的基础上,再扩展功能3
        print('功能模块3')
        self._decoratee.func1()
        
    def __get__(self,name):
        return print(self._decoratee,name)


def decorator_model():
    r=room()
    r_d=room_decorator(r)
    r_d.func3()
    r_d.__get__('room')

if __name__=='__main__':
    decorator_model()   

4.桥模式(Bridge、多维度)

目的:

将抽象与实现分离,使它们可以独立变化。它是用组合关系代替继承关系来实现,从而降低了抽象和实现这两个可变维度的耦合度

适用性:

某些类具有两个或多个维度的变化,如图形既可按形状分,又可按颜色分。如果用继承方式,m 种形状和 n 种颜色的图形就有 m×n 种,不但对应的子类很多,而且扩展困难。

基本思想:

桥接(Bridge)模式包含以下主要角色。

1.抽象化(Abstraction)角色:定义抽象类,并包含一个对实现化对象的引用。

2.扩展抽象化(Refined    Abstraction)角色:是抽象化角色的子类,实现父类中的业务方法,并通过组合关系调用实现化角色中的业务方法。

3.实现化(Implementor)角色:定义实现化角色的接口,供扩展抽象化角色调用。

4.具体实现化(Concrete Implementor)角色:给出实现化角色接口的具体实现。

'''4.bridge model'''
#类似decorator model在原有基础上扩展功能
#基类
class AbstractRoad(object):
    tool=None
class AbstractCar(object):
    def run(self):
        pass
class People(object):
    pass
#道路
class Street(AbstractRoad):
    def run(self):
        self.tool.run()
        print('在市区街道上')
class SpeedWay(AbstractRoad):
    def run(self):
        self.tool.run()
        print('在高速公路上')
#交通工具
class Car(AbstractCar):
    def run(self):
        print('小汽车')
class Bus(AbstractCar):
    def run(self):
        print('公共汽车')
#人
class Man(People):
    def drive(self):
        print('Man开着')
        self.road.run()
class Woman(People):
    def drive(self):
        print('Woman开着')
        self.road.run()


def bridge_model1():
    road1=SpeedWay()
    road1.tool=Car()
    road1.run()
    
    p1=Man()
    p1.road=road1
    p1.drive()   

if __name__=='__main__':      
    bridge_model1()

5.组合模式(Composite)  

意图:

它是一种将对象组合成树状的层次结构的模式,用来表示“部分-整体”的关系,使用户对单个对象和组合对象具有一致的访问性。 

适用性:

可以一致地处理单个对象和组合对象,无须关心自己处理的是单个对象,还是组合对象,这简化了客户端代码

更容易在组合体内加入新的对象,客户端不会因为加入了新的对象而更改源代码,满足“开闭原则”

基本思想:

组合模式包含以下主要角色。

1.抽象构件(Component)角色:它的主要作用是为树叶构件和树枝构件声明公共接口,并实现它们的默认行为。在透明式的组合模式中抽象构件还声明访问和管理子类的接口;在安全式的组合模式中不声明访问和管理子类的接口,管理工作由树枝构件完成。

2.树叶构件(Leaf)角色:是组合中的叶节点对象,它没有子节点,用于实现抽象构件角色中 声明的公共接口。

3.树枝构件(Composite)角色:是组合中的分支节点对象,它有子节点。它实现了抽象构件角色中声明的接口,它的主要作用是存储和管理子部件,通常包含 Add()、Remove()、GetChild() 等方法。

'''5.composite model'''
#对象组合成树形结构以表示“部分-整体”的层次结构
class Component:
    def __init__(self,strName):
        self._strName=strName
    def Add(self,com):
        pass
    def Display(self,depth):
        pass
class Composite(Component):
    def __init__(self,strName):
        self._strName=strName
        self.c=[]
    def Add(self,com):
        self.c.append(com)
    def Display(self,depth):
      # depth表示是底几层嵌套
        strtemp='-'* depth
        strtemp=strtemp+self._strName
        print(strtemp)
        for com in self.c:
            com.Display(depth+2)
class Leaf(Component):
    def Add(self,com):
        print('leaf cant add')
    def Display(self,depth):
        strtemp='-'*depth
        strtemp=strtemp+self._strName
        print(strtemp)


def composite_model():
    p=Composite('1')
    p.Add(Leaf('2'))
    p.Add(Leaf('3'))
    p.Display(1)       
    p1=Composite('4')
    p1.Add(Leaf('5'))
    p.Add(p1)
    p.Display(2)

if __name__=='__main__':
    composite_model()

6.外观模式

意图:

提供一个一致的接口,用来访问多个子系统

适用性:

降低了子系统与客户端之间的耦合度,对客户屏蔽了子系统组件,使得子系统的变化不会影响调用它的客户类。

'''6.facade model'''
#为子系统中的一组接口提供一个一致的界面,定义一个高层接口
class Com_alarm():
    name='12小时小区告警'
    def collect(self):
        print('采集'+self.name)
    def send(self):
        print('推送'+self.name)
class Bro_alarm():
    name='断站告警'
    def collect(self):
        print('采集'+self.name)
    def send(self):
        print('推送'+self.name)
class High_alarm():
    name='高频告警'
    def collect(self):
        print('采集'+self.name)
    def send(self):
        print('推送'+self.name)
#三个类的统一调用接口
class Alarm():
    def __init__(self):
        self.com_alarm=Com_alarm()
        self.bro_alarm=Bro_alarm()
        self.high_alarm=High_alarm()
    def collectAlarm(self):
        self.com_alarm.collect()
        self.bro_alarm.collect()
        self.high_alarm.collect()
    def sendAlarm(self):
        self.com_alarm.send()
        self.bro_alarm.send()
        self.high_alarm.send()


def facade_model():
    ayAlarm=Alarm()
    ayAlarm.collectAlarm()        
    ayAlarm.sendAlarm()
                  
if __name__=='__main__':
    facade_model()

7.享元模式(Flyweight)

意图:

通过共享已经存在的对象来大幅度减少需要创建的对象数量、避免大量相似类的开销,从而提高系统资源的利用率。

同对象只要保存一份,这降低了系统中对象的数量,从而降低了系统中细粒度对象给内存带来的压力。
 

'''flyweight model'''
class FlyweightBase(object):
  # 1.算法实例化的对象内存地址    
    _instance=dict()
  # 2.继承的子类必须初始化   
    def __init__(self,*args,**kwargs):
        raise NotImplementedError
#    
    def __new__(cls,*args,**kwargs):
        print(cls._instance,type(cls))
        return cls._instance.setdefault(
                (cls,args,tuple(kwargs.items())),#key
                super(FlyweightBase,cls).__new__(cls)#value
                )
        #调用自身的_instance字典,如果没有找父类_instance字典
        #setdefault:判断_instance字典是否有该key:obj=  实例
        #            如果有,返回该key的value(上次实例化对象(内存地址))
        #setdefault:如果找不到key:obj=  实例,就在_instance字典
        #            创建返回该新建key的value(该次实例化的对象的内存地址)
        #注:实例化对象的时候,如果形参相同的化,不用实例化,直接返回存在的实例的内存

class Client(FlyweightBase):
    def __init__(self,a,b):
        self.a=a
        self.b=b
    def test_data(self):
        pass
    def test_data(self):
        print('客户端准备好了',self.a,self.b)
        
class Server(FlyweightBase):
    def __init__(self,x,y):
        self.x=x
        self.y=y
#    def test_data(self):
#        pass
    def test_data(self):
        print('服务器准备好了',self.x,self.y)


def flyweight_model():
   #test1
   #key一样,则不会新建内存地址。key不一样,会新建内存地址
    client1=Client(1,'abc')
    client2=Client(1,'abc')       
    client3=Client(3,'DEF')      
    
    server=Server(1,'ABC')
    print(id(client1),id(client2),id(client3))
    
   #test2
    client2.test_data()
    server.test_data()
    print(server._instance)
    print(server._instance.keys())
                  
if __name__=='__main__':
    flyweight_model()
    

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值