装饰者模式示例demo

介绍

在不改变类的源代码或者不使用继承类的基础上动态地为一个对象增加新的功能(OCP原则,即开闭原则)

示例demo

背景:在火锅中任意加自己喜欢吃的菜品

装饰者抽象类:

public abstract class DecoratorComponent {
    /**
     * 加菜
     */
    public abstract void addGreens();
}

被装饰者:

public class HotSpotComponent extends DecoratorComponent {
    @Override
    public void addGreens() {
        System.out.print("火锅锅底");
    }
}

装饰者抽象类,具体的装饰者都继承这个类:

public abstract class GreensDecorator extends DecoratorComponent {
    protected DecoratorComponent decoratorComponent;

    public GreensDecorator(DecoratorComponent decoratorComponent) {
        this.decoratorComponent = decoratorComponent;
    }

    @Override
    public void addGreens() {
        decoratorComponent.addGreens();
    }
}

具体的装饰者:

/**
 * 牛肉装饰者
 **/
public class BeefDecorator extends GreensDecorator {

    public BeefDecorator(DecoratorComponent decoratorComponent) {
        super(decoratorComponent);
    }

    @Override
    public void addGreens() {
        decoratorComponent.addGreens();
        System.out.print(" 添加牛肉了");
    }
}


/**
 * 面条装饰者
 **/
public class NoodleDecorator extends GreensDecorator {
    public NoodleDecorator(DecoratorComponent decoratorComponent) {
        super(decoratorComponent);
    }

    @Override
    public void addGreens() {
        decoratorComponent.addGreens();
        System.out.println(" 添加面条了");
    }
}

/**
 * 土豆装饰者
 **/
public class PotatoDecorator extends GreensDecorator {

    public PotatoDecorator(DecoratorComponent decoratorComponent) {
        super(decoratorComponent);
    }

    @Override
    public void addGreens() {
        decoratorComponent.addGreens();
        System.out.print(" 添加了土豆");
    }
}

装饰者测试类:

public class DecoratorTest {
    @Test
    public void decoratorTest() {
        DecoratorComponent decoratorComponent = new NoodleDecorator(new BeefDecorator(new PotatoDecorator(new HotSpotComponent())));
        decoratorComponent.addGreens();
    }
}

运行结果如下图:

装饰者模式示例demo_第1张图片

拓展

针对 JDK 中 inputstream 对装饰者模式的应用,自己实现一个自定义的 inputstream处理,只需要继承 FilterInputStream(装饰者)重写 read 方法即可

自定义输入流:

public class CustomInputStream extends FilterInputStream {
    protected CustomInputStream(InputStream in) {
        super(in);
    }

    @Override
    public int read() throws IOException {
        int c = super.read();

        return (c == -1 ? c : Character.toUpperCase(c));
    }

    @Override
    public int read(byte[] b, int off, int len) throws IOException {
        int result = super.read(b, off, len);
        for (int i = off; i < off + result; i++) {
            b[i] = (byte) Character.toUpperCase((char) b[i]);
        }
        return result;
    }
}

同目录下创建一个test.txt文件

测试类:

public class DecoratorTest {
    @Test
    public void customInputStreamTest() {
        StringBuilder stringBuilder = new StringBuilder();
        int c;
        try {
            String fileName = this.getClass().getResource("test.txt").getPath();
            InputStream inputStream = new CustomInputStream(new BufferedInputStream(new FileInputStream(fileName)));
            while ((c = inputStream.read()) >= 0) {
                stringBuilder.append((char) c);
            }
            System.out.println(stringBuilder.toString());
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

运行结果:

装饰者模式示例demo_第2张图片

你可能感兴趣的:(java基础知识)