装饰模式
装饰模式(Decorator),动态地给一个对象添加一些额外的职责。
Component是抽象构件,定义一个对象接口,可以给这些对象动态地添加职责;
ConreteComponent定义一个具体对象,也可以给这个对象添加一些职责;
Decorator是装饰抽象类,实现接口或抽象方法;
ConreteDecorator是具体装饰对象,起到给Component添加职责的功能。
实例:描述一个人
源代码:基本实现功能
package org.zangyu.Decorator;
public class Decorator {
public static void main(String[] args) {
// TODO Auto-generated method stub
HighC hc =new HighC();
hc.setName("姚明");
RichC rc=new RichC();
rc.setName("马云");
HRUSA hrusa =new HRUSA();
hrusa.setName("Tom");
hc.desc();
rc.desc();
hrusa.desc();
}
}
abstract class Person{//公共基类,含有公共方法
String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public abstract void desc();
}
//主体类:中国人,美国人两个类
class Chinese extends Person{
@Override
public void desc() {
// TODO Auto-generated method stub
System.out.println(name+"是中国人");
}
}
class USA extends Person{
@Override
public void desc() {
// TODO Auto-generated method stub
System.out.println(name+"是美国人");
}
}
//扩展操作,对各国人进行操作
class HighC extends Chinese{
public void desc() {
super.desc();
System.out.println("高");
}
}
class RichC extends Chinese{
public void desc() {
super.desc();
System.out.println("富");
}
}
class HRC extends Chinese{
public void desc() {
super.desc();
System.out.println("高富");
}
}
class HighUSA extends USA{
public void desc() {
super.desc();
System.out.println("高");
}
}
class RichUSA extends USA{
public void desc() {
super.desc();
System.out.println("富");
}
}
class HRUSA extends USA{
public void desc() {
super.desc();
System.out.println("高富");
}
}
缺点:
结果往往是随着需求的变化,子类急剧增多,同时充斥着重复代码,需要划清职责问题
源代码:
改进——组合代替继承
package org.zangyu.Decorator;
public class Decorator {
public static void main(String[] args) {
// TODO Auto-generated method stub
Chinese p=new Chinese();
p.setName("姚明");
HighC hc =new HighC(p);
hc.desc();
p.setName("马云");
RichC rc=new RichC(p);
rc.desc();
USA p1 =new USA();
p1.setName("Tom");
HRUSA hrusa =new HRUSA(p1);
hrusa.desc();
}
}
abstract class Person{//公共基类,含有公共方法
String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public abstract void desc();
}
//主体类:中国人,美国人两个类
class Chinese extends Person{
@Override
public void desc() {
// TODO Auto-generated method stub
System.out.println(name+"是中国人");
}
}
class USA extends Person{
@Override
public void desc() {
// TODO Auto-generated method stub
System.out.println(name+"是美国人");
}
}
//扩展操作,对各国人进行操作
//组合代替继承
class HighC {
Chinese person;
public HighC(Chinese person) {
this.person=person;
}
public void desc() {
person.desc();
System.out.println("高");
}
}
class RichC {
Chinese person;
public RichC(Chinese person) {
this.person=person;
}
public void desc() {
person.desc();
System.out.println("富");
}
}
class HRC {
Chinese person;
public HRC(Chinese person) {
this.person=person;
}
public void desc() {
person.desc();
System.out.println("高富");
}
}
class HighUSA {
USA person;
public HighUSA(USA person) {
this.person=person;
}
public void desc() {
person.desc();
System.out.println("高");
}
}
class RichUSA {
USA person;
public RichUSA(USA person) {
this.person=person;
}
public void desc() {
person.desc();
System.out.println("富");
}
}
class HRUSA {
USA person;
public HRUSA(USA person) {
this.person=person;
}
public void desc() {
person.desc();
System.out.println("高富");
}
}
改进——积累代替子类效除编译依赖
源代码:
package org.zangyu.Decorator;
public class Decorator2 {
public static void main(String[] args) {
// TODO Auto-generated method stub
Chinese p=new Chinese();
p.setName("姚明");
HighP hc =new HighP(p);
hc.desc();
p.setName("马云");
RichP rc=new RichP(p);
rc.desc();
USA p1 =new USA();
p1.setName("Tom");
HRP hrusa =new HRP(p1);
hrusa.desc();
}
}
abstract class Person{//公共基类,含有公共方法
String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public abstract void desc();
}
//主体类:中国人,美国人两个类
class Chinese extends Person{
@Override
public void desc() {
// TODO Auto-generated method stub
System.out.println(name+"是中国人");
}
}
class USA extends Person{
@Override
public void desc() {
// TODO Auto-generated method stub
System.out.println(name+"是美国人");
}
}
//扩展操作,对各国人进行操作
//组合代替继承
//基类代替子类消除编译时的依赖
class HighP {
Person person;
public HighP(Person person) {
this.person=person;
}
public void desc() {
person.desc();
System.out.println("高");
}
}
class RichP {
Person person;
public RichP(Person person) {
this.person=person;
}
public void desc() {
person.desc();
System.out.println("富");
}
}
class HRP {
Person person;
public HRP(Person person) {
this.person=person;
}
public void desc() {
person.desc();
System.out.println("高富");
}
}
数据重构:当类中含有重复的字段和方法就应当提到积累里
解决:设计一个中间基类——装饰模式
package org.zangyu.Decorator;
public class Decorator3 {
public static void main(String[] args) {
// TODO Auto-generated method stub
Chinese p=new Chinese();
p.setName("姚明");
HighP hc =new HighP(p);
hc.desc();
p.setName("马云");
RichP rc=new RichP(p);
rc.desc();
USA p1 =new USA();
p1.setName("Tom");
HighP hp =new HighP(p1);
RichP rp=new RichP(hp);
rp.desc();//高富
HRP hrusa =new HRP(p1);
hrusa.desc();
}
}
abstract class Person{//公共基类,含有公共方法
String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public abstract void desc();
}
//主体类:中国人,美国人两个类
class Chinese extends Person{
@Override
public void desc() {
// TODO Auto-generated method stub
System.out.println(name+"是中国人");
}
}
class USA extends Person{
@Override
public void desc() {
// TODO Auto-generated method stub
System.out.println(name+"是美国人");
}
}
abstract class DPerson extends Person{
Person person;//依据和的方式来支持多态的变化
public DPerson(Person person){
this.person=person;
}
}
//扩展操作,对各国人进行操作
//组合代替继承
//基类代替子类消除编译时的依赖
class HighP extends DPerson{
public HighP(Person person) {
super(person);
this.person=person;
}
public void desc() {
super.person.desc();
System.out.println("高");
}
}
class RichP extends DPerson{
public RichP(Person person) {
super(person);
this.person=person;
}
public void desc() {
super.person.desc();
System.out.println("富");
}
}
class HRP extends DPerson{
Person person;
public HRP(Person person) {
super(person);
this.person=person;
}
public void desc() {
super.person.desc();
System.out.println("高富");
}
}
扩展操作:
class HSP extends DPerson{
Person person;
public HSP(Person person) {
super(person);
this.person=person;
}
public void desc() {
super.person.desc();
System.out.println("帅");
}
}
装饰模式框架:
package org.zangyu.Decorator;
public class Decorator4 {
public static void main(String[] args) {
// TODO Auto-generated method stub
CComponent c =new CComponent();
CDecoratorA d1 =new CDecoratorA();
CDecoratorB d2 =new CDecoratorB();
d1.SetComponent(c);
d2.SetComponent(d1);
d2.Operation();
}
}
abstract class Component{
public abstract void Operation();
}
class CComponent extends Component{
@Override
public void Operation() {
// TODO Auto-generated method stub
System.out.println("具体对象操作");
}
}
//装饰类
class Decorator extends Component{
protected Component component;//组合抽象类
public void SetComponent(Component component) {
//设置抽象类
this.component=component;
}
@Override
public void Operation() {
// TODO Auto-generated method stub
//重写继承的方法
if(component!=null)
{//实际执行的方法
component.Operation();
}
}
}
//具体装饰类
class CDecoratorA extends Decorator
{
private String addedState;
//本类的独有的功能,区别于别的装饰类
public void Operation() {
//这个操作是抽象类Decorator中定义的方法
super.Operation();
//首先运行原Decorator的方法在执行本类的特有属性
System.out.println("具体抽象类A的操作");
}
}
class CDecoratorB extends Decorator
{
private String addedState;
//本类的独有的功能,区别于别的装饰类
public void Operation() {
//这个操作是抽象类Decorator中定义的方法
super.Operation();
//首先运行原Decorator的方法在执行本类的特有属性
System.out.println("具体抽象类B的操作");
}
private void CDB()
{
System.out.println("具体装饰类B的独有方法");
}
}
装饰模式的应用
-
何时使用
在不想增加很多子类的情况下扩展类时
-
方法
将具体功能职责划分,同时继承装饰者模式
.
-
优点
装饰类和被装饰类可以独立发展,而不会相互耦合。它有效地把类的核心职责和装饰功能分开了 装饰模式是继承关系的一个替代方案 装饰模式可以动态地扩展一个实现类的功能
-
缺点
多层装饰比较复杂。比如我们现在有很多层装饰,出了问题,一层一层检查,最后发现是最里层的装饰出问题了,想想工作量都害怕
-
使用场景
需要扩展一个类的功能时 需要动态地给一个对象增加功能,并可以动态地撤销时 需要为一批的兄弟类进行改装或加装功能时
以上部分摘取自朱红梅老师2020年5月的课件。