java23种设计模式-装饰者模式

定义

装饰模式指的是在不必改变原类文件和使用继承的情况下,动态地扩展一个对象的功能。它是通过创建一个包装对象,也就是装饰来包裹真实的对象。

UML

角色

  • Component: 抽象组件接口
  • ConcreteComponent: 具体组件实现类
  • Decorator: 由abstract申明的抽象装饰者类,实现了Component接口
  • ConcreteDecorator: 抽象装饰者的具体实现,组合了Component对象,由构造器显式注入。

示例代码

/**
 * desc : 组件接口
 * Created by tiantian on 2018/10/5
 */
public interface Component {
    void doSomething();
}

/**
 * desc : 具体组件
 * Created by tiantian on 2018/10/5
 */
public class ConcreteComponentA implements Component{
    @Override
    public void doSomething() {
        System.out.println("hello");
    }
}

/**
 * desc : 具体组件
 * Created by tiantian on 2018/10/5
 */
public class ConctreteComponentB implements Component{
    @Override
    public void doSomething() {
        System.out.println("world");
    }
}

/**
 * desc : 抽象装饰者
 * Created by tiantian on 2018/10/5
 */
public abstract class Decorator implements Component {
}
/**
 * desc : 具体装饰者A
 * Created by tiantian on 2018/10/5
 */
public class ConcteteDecoratorA extends Decorator {
    private Component component;

    public ConcteteDecoratorA(Component component) {
        this.component = component;
    }
    
    @Override
    public void doSomething() {
        System.out.println("Decorating component object.");
        component.doSomething();
        System.out.println("Decorating component object again.");

    }
}

/**
 * desc : 具体装饰者
 * Created by tiantian on 2018/10/5
 */
public class ConcteteDecoratorB extends Decorator {
    private Component component;

    public ConcteteDecoratorB(Component component) {
        this.component = component;
    }

    @Override
    public void doSomething() {
        System.out.println("Decorating component object.");
        component.doSomething();
        System.out.println("Decorating component object again.");

    }
}
/**
 * desc : 测试
 * Created by tiantian on 2018/10/5
 */
public class Test {
    public static void main(String[] args) {
        Component component = new ConcreteComponentA();
        Component beDecoratedComp = new ConcteteDecoratorA(component);
        beDecoratedComp.doSomething();
    }
    // Decorating component object.
    // hello
    // Decorating component object again.
}

与适配器区别

相同点:都是结构型设计模式。对象适配器has-a被适配者;装饰者同样has-a被装饰者。
一个对象可以由多个装饰者装饰,以增加不同的特性。
装饰者和被装饰对象拥有相同的接口,而对象适配器与适配目标接口相同,而非与被适配中接口相同。
适配器模式中,被适配对象同样也是与适配器组合起来使用,但目的是使接口适配,而非增加新的特性。
装饰者模式可以在运行时动态的为被装饰对象增加特性。

源码分析(装饰者在jdk IO中的应用)

// 示例代码
public class IOTest {
    public static void main(String[] args) {
        File file = new File("hello.txt");
        InputStream is = new FileInputStream(file);
        InputStreamReader reader = new InputStreamReader(is);
    }
}

以下为jdk中InputStreamReader部分源码。

public class InputStreamReader extends Reader {

    private final StreamDecoder sd;

    /**
     * Creates an InputStreamReader that uses the default charset.
     *
     * @param  in   An InputStream
     */
    public InputStreamReader(InputStream in) {
        super(in);
        try {
            sd = StreamDecoder.forInputStreamReader(in, this, (String)null); // ## check lock object
        } catch (UnsupportedEncodingException e) {
            // The default encoding should always be available
            throw new Error(e);
        }
    }
// ... 省略jdk其他实现细节
}    

通过源码可以了解到,InputStreamReader在构造自己时,通过装饰者StreamDecoder的静态方法forInputStreamReader把自己装饰为StreamDecoder对象。forInputStreamReader方法有个参数this用户传入自己。StreamDecoder和InputStreamReader都继承自Reader类,这正好也印证了装饰者和被装饰对象拥有相同接口的特点。

猜你喜欢

转载自blog.csdn.net/m0_37577221/article/details/82944913