设计模式的艺术 结构性模式之装饰模式

不懂使用为学过,说出用途,绘制结构为了解,不会灵活使用基本等于没学。

前言

我们大多数时候买的新房都是毛坯房,想要入住的话无疑需要进行一次装修自己才能高高兴兴的入住,虽然装修了,但是并没有改变房子的本质,但这样会让你更乐于到房子里面去入住,在软件设计中,也有这么一种技术可以对已有的对象的功能进行扩展,以此来获得更加符合用户需求的对象,使得对象具有更加强大的功能,这是一种被称之为装饰模式的设计模式

什么是装饰模式 Decorator Pattern

动态的给一个对象增加一些额外的职责,就增加对象功能来说,装饰模式比生成子类的实现更加灵活,装饰模式是一种对象结构型模式

装饰模式的优点

(1)、对于扩展一个对象的功能,装饰模式对比继承而言更加具有灵活性,不会导致类的个数急剧的增加。

(2)、可以通过一种动态的方式来扩展一个对象的功能,通过配置文件可以在运行时选择不同的具体装饰类,从而实现不同的行为。

(3)、可以对一个对象进行多次的装饰,通过使用不同的具体装饰类以及这些装饰类的排列组合,可以创造出很多不同行为的组合,得到功能更加强大的对象

(4)、具体构件类与具体装饰类可以独立变化,用户可以根据需要增加具体的构件类或者具体的装饰类,原有类库代码无须改变,符合开闭原则和里氏替换原则

装饰模式的缺点

(1)、使用装饰模式进行系统设计时将产生很多小对象,这些对象之间的区别在于它们之间相互连接的方式有所不同,而不是它们的类或者属性值的不同,大量的小对象的产生势必会影响到程序的性能,毕竟占据了一部分的系统的资源

(2)、装饰模式提供了一种比继承更为灵动的解决方案,但同时也意味着比继承更加容易出错,排查错误比较困难,对于多次装饰的对象,调试时寻找错误可能需要逐级排查,较为的繁琐

装饰模式适用的场景

(1)、在不影响其他对象的前提下,动态,透明的给单个的对象添加职责

(2)、当不能采用继承的方式对系统进行扩展或者采用继承不利于系统扩展和维护时可以采用装饰模式,不能采用继承的情况主要有两类:第一类是系统中存在大量的独立的扩展,为支持每一种扩展或者扩展之间的组合都将产生大量的子类,使得子类数目呈爆炸性增长。而第二类是那么已经被定义为不可继承的类(final类)

装饰模式的具体实现

项目结构(表现形式为为构建类添加新的功能)

抽象构件类与具体构件类

//抽象界面构件类:抽象构件类,为了突出与模式有关的核心代码,对原有控件代码进行了大量的简化
public abstract class Component {
    public abstract void display();
}
package com.company.component;

import com.company.component.Component;

//列表框类:具体构件类
public class ListBox extends Component {
    @Override
    public void display() {
        System.out.println("显示列表框");
    }
}
package com.company.component;

import com.company.component.Component;

//窗体类:具体构件类
public class TextBox extends Component {

    @Override
    public void display() {
        System.out.println("显示窗体!");
    }
}

抽象装饰类

package com.company;

import com.company.component.Component;

//构件装饰类:抽象装饰类
public class ComponentDecorator extends Component {
    private Component component;  //维持对对象构件类型对象的引用,根据里氏替换原则
    //注入抽象构件类型的对象
    public ComponentDecorator(Component component) {
        this.component = component;
    }

    @Override
    public void display() {
        component.display();
    }
}

具体装饰类

package com.company.decorator;

import com.company.ComponentDecorator;
import com.company.component.Component;

public class BlockBorderDecorator extends ComponentDecorator {
    public BlockBorderDecorator(Component component) {
        super(component);
    }
    public void display(){
        this.setBlockBorder();
        super.display();
    }
    public void setBlockBorder(){
        System.out.println("为构件增加黑色边框");
    }
}
package com.company.decorator;

import com.company.ComponentDecorator;
import com.company.component.Component;

//滚动条装饰类:具体装饰类
public class ScrollDecorator extends ComponentDecorator {
    public ScrollDecorator(Component component) {
        super(component);
    }
    public void display(){
        this.setScrollBar();
        super.display();
    }
    public void setScrollBar(){
        System.out.println("为构件增加滚动条");
    }
}

测试类

public static void main(String[] args) {
    Component component,component1,component2;  //使用抽象构件定义
    component=new ListBox();  //定义具体构件
    component1=new ScrollDecorator(component);  //定义装饰后的构件
    component1.display();
    component2=new BlockBorderDecorator(component1);
    component2.display();
}

转载请注明出处,掌声送给社会人

猜你喜欢

转载自blog.csdn.net/SCDN_CP/article/details/82960707