装饰器模式

装饰模式(IO设计的核心思想)

装饰模式的定义:在不影响原对象的前提下,无入侵的给一个对象增一些额外的功能。

换句话就是:装饰模式就是对原对象进行包装,使之具有其不具备的功能。但这些功能是在原有功能的基础上进行增强的。

例如这个使用场景:现在苹果出了12了,每一代苹果都是继承自上代苹果的。那么我要增加一些2代苹果的功能,我可以直接直接在2代的类上加功能吗?答案是肯定不可以的一是因为其巨大的调用关系与函数,再者就是其派生类怎么办?所以装饰者模式就是解决对象链中的其中某个对象功能的扩增。

这是其一,其二是如果类的跨度特别大,我只需要这两个跨度大的类,那么在其中的中间类是非常多的,会形成子类膨胀。装饰模式就是解决子类膨胀的一种方法。

综上:装饰者模式可以解决两种问题:

  • 子类膨胀。
  • 将对象链中的对象单独拆出来进行功能扩展,而不用担心其派生类。

例如:文件可以作为字符串的扩展:new File(“d:/abc.txt”);

原字符串没有影响,给原有对象字符串增加额外的功能(作为文件的功能)

Java中的装饰器模式

再例如:流可以作为文件的扩展:new FileInputStream(new File(“d:/abc.txt”));

从上述可以看出装饰模式需要两个对象:被装饰对象、装饰对象。(与java中的设计相同可以设计一个接口与实现类)

例如实例:手机被智能手机装饰。

值得注意的是:装饰者要装饰一个对象必然要持有该对象的引用。

public interface IPhone{
    void call();
}

public class PhoneImpl{
    public void call(){
        
    }
}
public abstract class SmartPhone implements Phone{
    //设计为抽象类是因为再类中需要一个被装饰的引用。实现被引用对象的接口是因为要在原有对象的基础上(增加功能)
    
    IPhone iphone;
    public SmartPhone(){}
    public SmartPhone(IPhone iphone){
        this.iphone = iphone;
    }
    
    //原电话的功能
    public void call(){
        iphone.call();
    }
}

抽象类中包含被装饰对象的引用,并且实现、调用其原有方法。功能的增加可以用其派生类增加,不同功能派生不同派生类。

public class ConcreteSmartPhone1 extends SmartPhone{
    public ConcreteSmartPhone1(Phone phone){
        super(phone);
    }
    
    public void call(){
        super.call();
        this.changeBackground();
        //在原有功能的基础上进行增强
    }
    
    public void changeBackground(){
        System.out.print("改变背景颜色");
    }
}
public class ConcreteSmartPhone2 extends SmartPhone{
    public ConcreteSmartPhone1(Phone phone){
        super(phone);
    }
    
    public void call(){
        super.call();
        this.changeSize();
        //在原有功能的基础上进行增强
    }
    
    public void changeSize(){
        System.out.print("改变尺寸");
    }
}

Python中的装饰器模式

  • 在python中,装饰器是用来包装函数的函数
  • 装饰器常用于下列情况:
    • 将多个函数中的重复代码拿出来整理成一个装饰器
    • 对多个函数的共同功能进行处理

在python中装饰器的定义方式如下:

def decorator(func):
    pass

@decorator
def func():
    pass

decorator是一个装饰器。func是被装饰的函数。

例如这样一个场景:我想知道一个项目中的各个函数的执行时间,**我总不可能把每个函数都添加一遍代码吧?**这时就可以使用装饰器。

import time

def deco(func):
    def dothat():
        print("star time:", time.ctime())
        func()
        print("end time:", time.ctime())
        return "deco end!"
    return dothat
    
@deco
def func():
    print("i am a func")
    
print(func())
star time: Wed Sep 29 19:03:41 2021
i am a func
end time: Wed Sep 29 19:03:41 2021
deco end!

装饰器就是闭包的应用。

funcdeco装饰了,在func的时候就相当于deco(func)了,然后返回了dothat函数,加()被执行。

import time

def deco(func):
    def dothat():
        print("star time:", time.ctime())
        func()
        print("end time:", time.ctime())
    return dothat
    
@deco
def func():
    print("i am a func")
    
print(func)
<function __main__.deco.<locals>.dothat()>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值