1.定义
动态的将责任附加到对象上,若要扩展功能,装饰者提供了 比继承者更有弹性的替代方案。
装饰者和被装饰者必须是一样的类型。所以有共同的超类。
利用继承同一个超类,达到“类型匹配”,而不是利用继承获得行为。
装饰者要做的事,就是增加行为到被装饰者(即包装对象)上。
2. 自定义装饰者模式实现
实现代码如下:
//抽象超类
public abstract class BaseComponent {
protected String description = "Unknown";
public abstract double cost();
public String getDescription() {
return description;
}
}
//鱼,肉类 = 被包装对象 = 被装饰者
public class Fish extends BaseComponent {
public Fish(){
description = "fish";
}
@Override
public double cost() {
return 100;
}
}
public class Meat extends BaseComponent{
public Meat(){
description = "meat";
}
@Override
public double cost() {
return 200;
}
}
//装饰者抽象类(装饰者的基类)
public abstract class Condiment extends BaseComponent{
public abstract String getDescription();
}
// 装饰者 辣椒 麻油 糖
public class ChilliCondiment extends Condiment {
private BaseComponent base;
public ChilliCondiment(BaseComponent base){
this.base = base;
}
@Override
public String getDescription() {
// TODO Auto-generated method stub
return base.getDescription() + ", 辣椒";
}
@Override
public double cost() {
// TODO Auto-generated method stub
return base.cost() + 10;
}
}
public class CastOilCondiment extends Condiment{
private BaseComponent base;
public CastOilCondiment(BaseComponent base){
this.base = base;
}
@Override
public String getDescription() {
// TODO Auto-generated method stub
return base.getDescription() + ", 麻油";
}
@Override
public double cost() {
// TODO Auto-generated method stub
return base.cost() + 20;
}
}
public class SugarCondiment extends Condiment{
private BaseComponent base;
public SugarCondiment(BaseComponent base){
this.base = base;
}
@Override
public String getDescription() {
// TODO Auto-generated method stub
return base.getDescription() + ", 糖";
}
@Override
public double cost() {
// TODO Auto-generated method stub
return base.cost() + 30;
}
}
测试代码:
public class MainTest {
public static void main(String[] args) throws IOException {
BaseComponent menu1 = new Fish();
menu1 = new ChilliCondiment(menu1);
menu1 = new CastOilCondiment(menu1);
System.out.println(menu1.getDescription() + menu1.cost());
BaseComponent menu2 = new Meat();
menu2 = new ChilliCondiment(menu2);
menu2 = new SugarCondiment(menu2);
System.out.println(menu2.getDescription() + menu2.cost());
}
}
运行结果如下:
fish, 辣椒, 麻油130.0
meat, 辣椒, 糖240.0
3. java内置装饰者模式, java.io
实例代码如下:
//包装类,继承FilterInputStream
public class LowerCaseInputStream extends FilterInputStream{
protected LowerCaseInputStream(InputStream in) {
super(in);
}
@Override
public int read() throws IOException {
int c = super.read();
return c == -1 ? c : Character.toLowerCase((char)c);
}
@Override
public int read(byte[] b, int off, int len) throws IOException {
int result = super.read(b, off, len);
for(int i=0;i<b.length;i++){
b[i] = (byte)Character.toLowerCase((char) b[i]);
}
return result;
}
}
测试代码如下:
public class MainTest {
public static void main(String[] args) throws IOException {
InputStream in = new LowerCaseInputStream(new BufferedInputStream(new FileInputStream("c:/test.txt")));
int c ;
while((c = in.read()) >=0){
System.out.print((char)c);
}
in.close();
}
}
OO原则:
封装变化
多用组合,少用继承
针对接口编程,不针对实现编程
为交互对象之间的松耦合设计而努力
对扩展开放,对修改封闭