文章目录
  1. 1. 简单介绍
  2. 2. UML图
    1. 2.1. 参与者
  3. 3. 实例
  4. 4. 输出
  5. 5. 效果
  6. 6. Java I/O包中的应用。

OCP原则是指对扩展开放,对修改关闭。OCP的关键是抽象和封装,下面我们将会围绕OCP原则介绍一些设计模式,包含有Decorator、Strategy、State、Bridge等设计模式,本文将先介绍第四种设计模式—装饰者模式(Decorator Pattern).

简单介绍

装饰扩展一个类的实例的功能,而无需更改类代码(Decorators expand the functionality of an instance of a class without changing the class code )。

比静态继承更灵活(More flexibility than static inheritance)。

装饰着在后台工作,他们有开放的接口(Decorators work behind the scenes, they are transparent to the interface)。

UML图

参与者

  1. 抽象构件(Component)角色:给出一个抽象接口,以规范准备接收附加责任的对象。
  2. 具体构件(Concrete Component)角色:定义一个将要接收附加责任的类。
  3. 装饰(Decorator)角色:持有一个构件(Component)对象的实例,并定义一个与抽象构件接口一致的接口。
  4. 具体装饰(Concrete Decorator)角色:负责给构件对象”贴上”附加的责任。

实例

  1. Component类

    public abstract class Component {
        public abstract void operation();
    }
    
  2. ConcreteComponent类

    public class ConcreteComponent extends Component{
    
        @Override
        public void operation() {
            System.out.println("ConcreteComponent.operation()");
        }
    
    }
    
  3. Decorator类

    public abstract class Decorator extends Component{
        private Component component;
    
        public Decorator(Component component) {
            this.component = component;
        }
    
        @Override
        public void operation() {
            if(null != component) {
                component.operation();
            }
        }
    
    }
    
  4. ConcreteDecoratorA类

    public class ConcreteDecoratorA extends Decorator{
        private String addString = "";
    
        public ConcreteDecoratorA(Component component) {
            super(component);
        }
    
        public void operation() {
            addString = "add a new String";
            System.out.println("Add a new String:" + addString);
            super.operation();
        }
    }
    
  5. ConcreteDecoratorB类

    public class ConcreteDecoratorB extends Decorator{
        public ConcreteDecoratorB(Component component) {
            super(component);
        }
    
        public void operation() {
            doOtherThing();
            System.out.println("call doOtherThing();");
            super.operation();
        }
    
        private void doOtherThing() {
            System.out.println("doOtherThing");
        }
    }
    
  6. Test类

    public class Test {
        public static void main(String arg[]) {
            Component component = new ConcreteComponent();
            component.operation();
    
            System.out.println("---------------------");
    
            Decorator decorator = new ConcreteDecoratorA(component);
            decorator.operation();
    
            System.out.println("---------------------");
    
            Decorator decorator2 = new ConcreteDecoratorB(decorator);
            decorator2.operation();
        }
    }
    

输出

ConcreteComponent.operation()
---------------------
Add a new String:add a new String
ConcreteComponent.operation()
---------------------
doOtherThing
call doOtherThing();
Add a new String:add a new String
ConcreteComponent.operation()

效果

  1. More flexible than static inheritance
  2. Avoids feature laden classes high up in hierarchy
  3. Lots of little objects that look alike. So it is hard to learn and debug
  4. A decorator and its components are not identical. So checking object identification can cause problems

Java I/O包中的应用。

InputStream就相当于最高的父类。而FileInputStream, StringBufferInputStream…这几个类相当于用来被包装核心。如最前面的代码所示,它们只能用在最里边。而那些用来包装的类如BufferedInputStream…这些都继承自FilterInputStream类。FilterInputStream相当于前面的Decorator类

java IO一般分为两类,一类是面向字节的,采用InputStream或者OutputStream。还有一类是面向字符的,采用Reader和Writer。而针对这些所有的类的结构都采用了Decorator的结构。所以,根据命名的约定,我们就可以很容易猜出里面哪些类是干什么的以及在这个类结构中起什么作用。用一句话来概括java io包中的类的话,就是这个包中基本上就是包含了InputStream, OutputStream,Reader和Writer这四大家族和他们的小喽罗们:

文章目录
  1. 1. 简单介绍
  2. 2. UML图
    1. 2.1. 参与者
  3. 3. 实例
  4. 4. 输出
  5. 5. 效果
  6. 6. Java I/O包中的应用。