装饰模式(decorator pattern)

依照Num模型。讨论职业/IProfession类层次。

IProfession定义了方法say(String),事实上现类教师/ Teacher、医生、律师……依照其职业习惯给出say(String)的实现,这些实现类相当于Num模型中的Zero。

而才艺/Talent类层次(相当于NextOne),能够装饰基本对象,say(String)实现中,在必要的时候会说english、在必要的时候会唱几句……

package closure.decorator;
public interface IProfession {
abstract public void say(String s);
} package closure.decorator;
import static yqj2065.util.Print.pln;
public class Teacher implements IProfession{
@Override public void say(String s){ pln(teach(s)) ; }
public String teach(String s){
String myStyle="解说["+s+"]";
return myStyle;
}
} package closure.decorator;
public abstract class Talent implements IProfession {
protected IProfession base;
public Talent(IProfession base) { this.base = base; }
}
package closure.decorator;
public class TSong extends Talent{
public TSong(IProfession base) {
super(base);
}
@Override public void say(String s){
s = this.song(s);
base.say(s); //
}
public String song(String s){
String strengthen="旋律("+s+")";
return strengthen;
}
}// TEnglish略

1.模板方法

抽象装饰类型Talent,只定义了其类层次的结构——作为类型闭包。没有提供say(String s)的默认实现,由于提供例如以下默认实现

@Override public final void say(String s) {

base.say(s);

}

尽管暗示其子类型应该调用base.say(),但不具有强制性。

Talent能够编写模板方法,使得详细装饰类不再须要改写say()并调用base.say(),而只关注编写增强say()功能的代码。

package closure.decorator;
public abstract class Talent implements IProfession {
protected IProfession base;
public Talent(IProfession base) { this.base = base; }
@Override public final void say(String s) { //模板方法
s = strengthen(s);
base.say(s);
}
public abstract String strengthen(String s);
}
package closure.decorator;
public class TEnglish extends Talent {
public TEnglish(IProfession base) { super(base); }
public String english(String s) {
String strengthen ="E文(" + s + ")";
return strengthen;
}
@Override public String strengthen(String s) { return this.english(s); }
}
//Test
IProfession p = (IProfession) God.create("Profession-decorator");//
p.say("类层次");
p = new TEnglish(new TSong(new TEnglish(p)));
p.say("LSP");
p = new TSong(p);
p.say("继承");
p= p.removeSong();
p.say("继承");

測试代码的输出为:

解说[类层次]

解说[E文(旋律(E文(LSP)))]

解说[E文(旋律(E文(旋律(继承))))]

装饰模式比較典型的标志:Person b = new T2(newT2(newT1(newLawyer())));

2.装饰模式与桥接模式

装饰模式与桥接模式非常相似。桥接模式将2次以上的策略选择逐一地串接起来。如例程3-5中定义的模板方法。

public default void lecture(String s) {

String myStyle = say(s);

next.say(myStyle);

}

桥接模式所串接的,是两种不同的类层次。而装饰模式则将Talent和它的父类型IProfession进行逐一的串接。

能够说,装饰模式是桥接模式的特例。

Java 装饰模式(4.4)的更多相关文章

  1. java装饰模式

    在java的IO中就是运用装饰模式设计的.一层装饰一层 如:DataOutputStream dos = new DataOutputStream(new BufferedOutputStream(n ...

  2. Java 装饰模式

    在阎宏博士的<JAVA与模式>一书中开头是这样描述装饰(Decorator)模式的: 装饰模式又名包装(Wrapper)模式.装饰模式以对客户端透明的方式扩展对象的功能,是继承关系的一个替 ...

  3. Java 装饰模式 (Decorator)

    装饰模式 动态的将责任附加到对象上.若要扩展功能,装饰者提供了比继承更有弹性的取代方案 代码 package gx.component; /** * 组件:装饰类和被装饰类 都要继承:为了类型保持一致 ...

  4. (私人收藏)[开发必备]最全Java离线快速查找手册(可查询可学习,带实例)

    (私人收藏)[开发必备]最全Java离线快速查找手册(可查询可学习,带实例) https://pan.baidu.com/s/1L54VuFwCdKVnQGVc8vD1TQnwmj java手册 Ja ...

  5. Spark案例分析

    一.需求:计算网页访问量前三名 import org.apache.spark.rdd.RDD import org.apache.spark.{SparkConf, SparkContext} /* ...

  6. 装饰模式,制作一个蛋糕java

    import java.text.DecimalFormat; //抽象组件组件 interface mkcake { public void cake(); } class Cake impleme ...

  7. Java设计模式(学习整理)----装饰模式

    1.概念: (在我看来,模式就像是是一种思想,在这种思想的指引下,对代码和结构的一番加工和整合而已!都是套路!) 装饰模式又称包装(Wrapper)模式,是以对客户端透明的方式扩展对象的功能,是继承关 ...

  8. Java设计模式---装饰模式

    装饰模式又名包装(Wrapper)模式.装饰模式以对客户端透明的方式扩展对象的功能,是继承关系的一个替代方案. 装饰模式的结构 装饰模式以对客户透明的方式动态地给一个对象附加上更多的责任.换言之,客户 ...

  9. java模式之装饰模式

    1. 什么叫装饰模式? 根据业务的需求,需要对一个类的方法进行增强的处理. 2. 为什么需要装饰模式? 拓展性更加的好,当觉得这个装饰不好的时候,可以直接拿下,不需要改变任何的代码. 3. 装饰模式的 ...

随机推荐

  1. Problem D: 程序填充(递归函数):数列2项和

    Problem D: 程序填充(递归函数):数列2项和 Time Limit: 1 Sec  Memory Limit: 64 MBSubmit: 2601  Solved: 2117 Descrip ...

  2. Java高级架构师(一)第33节:Nginx常用核心模块指令

    error_log:错误日志级别 http://www.nginx.cn/doc/  Nginx中文文档 # 并发总数是 worker_processes 和 worker_connections 的 ...

  3. Oracle 11gR2 RAC 数据库不能连接(ORA-12537: TNS:connection closed)的解决

        Oracle 11gR2 RAC 数据库不能连接(ORA-12537: TNS:connection closed)的解决 [oracle@rac01 ~]$ sqlplus /nolog S ...

  4. 发一个比trace功能更强大debug工具,MonterDebugger

    经常看到兄弟说trace不出东西啊,这样给你调试会带来很多不便:加入说我们需要将运行时的debug信息和之前某个版本的进行比对:又加入说我们需要在运行时通过debug动态调整显示对象的属性:查看当前整 ...

  5. 【Python】装饰器实现日志记录

    好的日志对一个软件的重要性是显而易见的.如果函数的入口都要写一行代码来记录日志,这种方式实在是太低效了,但一直没有找到更好的方法.后来用python写一些软件,了解到python的装饰器功能时,突然人 ...

  6. g++ 静态库连接顺序的巨坑

    在编译最新版本(12.04)的alljoyn的chat示例的时候,想使用bundle daemon,依照在以前的经验修改文件:alljoyn-14.02.00-src/build/linux/x86_ ...

  7. 教你用 google-drive-ocamlfuse 在 Linux 上挂载 Google Drive

    如果你在找一个方便的方式在 Linux 机器上挂载你的 Google Drive 文件夹, Jack Wallen 将教你怎么使用 google-drive-ocamlfuse 来挂载 Google ...

  8. 使用git-svn迁移SVN至GitLab

    使用git-svn迁移SVN至GitLab 1.安装git和git-svn 后面的步骤中对git版本有一定要求,通过yum安装的git版本较低,这里进行编译安装 [root@DevTest ~]# y ...

  9. automake--关于两个文件configure.in和Makefile.am的编写

    http://blog.csdn.net/shanzhizi/article/details/30251763 automake主要通过编辑Makefile.am来控制它的行为,下面就常用的三个Mak ...

  10. Win7如何关闭 打开文件-安全警告

    如图所示,运行一个EXE程序就会弹出提示,很麻烦.   在运行对话框中输入gpedit.msc打开组策略编辑器.定位到用户配置--管理模板--windows组件--附件管理器 点中等危险文件类型抱含列 ...