装饰者模式(Decorator Pattern)
是指在不改变原有对象的基础上,将功能附加到对象上,提供比继承更优弹性的替换方案(扩展原有对象的功能),属于结构型模式。
适用场景:
1、用于扩展一个类的功能或给一个类添加附加的职责。
2、动态的给一个对象添加功能,这些功能可以再动态的撤销。
不加装饰类示例:
public class AssembleComputer {
private BigDecimal bigDecimal = new BigDecimal("6000");
public String getMsg() {
return "电脑组装";
}
public BigDecimal getPrice() {
return bigDecimal;
}
}
public class AddScreen extends AssembleComputer {
private BigDecimal bigDecimal = new BigDecimal("1500");
@Override
public String getMsg() {
return super.getMsg() + "_增加显示器";
}
@Override
public BigDecimal getPrice() {
return super.getPrice().add(bigDecimal);
}
public BigDecimal getBigDecimal() {
return bigDecimal;
}
public void setBigDecimal(BigDecimal bigDecimal) {
this.bigDecimal = bigDecimal;
}
}
public class AddMainBoard extends AssembleComputer {
private BigDecimal bigDecimal=new BigDecimal("1000");
@Override
public String getMsg() {
return super.getMsg()+"_新增主板";
}
@Override
public BigDecimal getPrice() {
return super.getPrice().add(bigDecimal);
}
public BigDecimal getBigDecimal() {
return bigDecimal;
}
public void setBigDecimal(BigDecimal bigDecimal) {
this.bigDecimal = bigDecimal;
}
}
public class AssembleComputerTest {
public static void main(String[] args) {
AssembleComputer assembleComputer = new AssembleComputer();
System.out.println(assembleComputer.getMsg()+"价格为:"+assembleComputer.getPrice());
AddMainBoard addMainBoard = new AddMainBoard();
System.out.println(addMainBoard.getMsg()+"价格为:"+addMainBoard.getBigDecimal());
System.out.println("总价为:"+addMainBoard.getPrice());
AddScreen addScreen = new AddScreen();
System.out.println(addScreen.getMsg()+"价格为:"+addScreen.getBigDecimal());
System.out.println("总价为:"+addScreen.getPrice());
}
}
结果输出:
电脑组装价格为:6000
电脑组装_新增主板价格为:1000
总价为:7000
电脑组装_增加显示器价格为:1500
总价为:7500
在java提供的工具包中,IO工具大多采用的就是装饰者模式,例如:BufferedInputStream(高级流)就是充当装饰者的IO类,通常将基本流作为高级流的构造器的参数传入,将其作为高级流的关联对象,从而对其功能功能进行扩展和装饰。
public class AssembleComputer {
private BigDecimal bigDecimal = new BigDecimal("6000");
public String getMsg() {
return "电脑组装";
}
public BigDecimal getPrice() {
return bigDecimal;
}
}
public class AssembleComputerDecorator extends AssembleComputer{
private AssembleComputer assembleComputer;
public AssembleComputerDecorator(AssembleComputer assembleComputer) {
this.assembleComputer = assembleComputer;
}
@Override
public String getMsg() {
return this.assembleComputer.getMsg();
}
@Override
public BigDecimal getPrice() {
return this.assembleComputer.getPrice();
}
}
public class AddMainBoard extends AssembleComputerDecorator {
private BigDecimal bigDecimal=new BigDecimal("1000");
public AddMainBoard(AssembleComputer assembleComputer) {
super(assembleComputer);
}
@Override
public String getMsg() {
return super.getMsg()+"_新增主板";
}
@Override
public BigDecimal getPrice() {
return super.getPrice().add(bigDecimal);
}
public BigDecimal getBigDecimal() {
return bigDecimal;
}
}
public class AddScreen extends AssembleComputerDecorator {
private BigDecimal bigDecimal = new BigDecimal("1500");
public AddScreen(AssembleComputer assembleComputer) {
super(assembleComputer);
}
@Override
public String getMsg() {
return super.getMsg() + "_增加显示器";
}
@Override
public BigDecimal getPrice() {
return super.getPrice().add(bigDecimal);
}
public BigDecimal getBigDecimal() {
return bigDecimal;
}
}
public class AssembleComputerTest {
public static void main(String[] args) {
AssembleComputer assembleComputer = new AssembleComputer();
System.out.println(assembleComputer.getMsg()+"价格为:"+assembleComputer.getPrice());
AddScreen addScreen = new AddScreen(assembleComputer);
System.out.println(addScreen.getMsg()+"价格为:"+addScreen.getBigDecimal());
System.out.println("总价为:"+addScreen.getPrice());
AddMainBoard addMainBoard = new AddMainBoard(addScreen);
System.out.println(addMainBoard.getMsg()+"价格为:"+addMainBoard.getBigDecimal());
System.out.println("总价为:"+addMainBoard.getPrice());
}
}
执行的结果为:
电脑组装价格为:6000
电脑组装_增加显示器价格为:1500
总价为:7500
电脑组装_增加显示器_新增主板价格为:1000
总价为:8500
结构关系图如下:
AssembleComputerDecorator 装饰器类将AssembleComputer作为构造器的参数传入,并且将AssembleComputer作为关联的对象,对其进行扩展和延伸。
版权声明:本文为tealala原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。