装饰模式:动态地给一个对象添加一些额外的职责,就增加功能来说,装饰模式比生成子类更为灵活
案例:人及其属性
普通实现
package 设计模式;
public class Text {
public static void main(String[] args) {
highChinese hc=new highChinese();
hc.setName("ym");
richChinese rc=new richChinese();
rc.setName("my");
highrichAmerican hra=new highrichAmerican();
hra.setName("Tom");
hc.desc();rc.desc();hra.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
{
public void desc()
{
System.out.print(name+"是中国人");
}
}
class American extends Person
{
public void desc()
{
System.out.print(name+"是美国人");
}
}
class highChinese extends Chinese
{
public void desc() {
super.desc();
System.out.println("是high人");
}
}
class richChinese extends Chinese
{
public void desc()
{
super.desc();
System.out.println("是rich人");
}
}
class highrichChinese extends Chinese
{
public void desc()
{
super.desc();
System.out.println("是high&rich人");
}
}
class highAmerican extends American
{
public void desc() {
super.desc();
System.out.println("是high人");
}
}
class richAmerican extends American
{
public void desc()
{
super.desc();
System.out.println("是rich人");
}
}
class highrichAmerican extends American
{
public void desc()
{
super.desc();
System.out.println("是high&rich人");
}
}
缺点:随着需求的变化,子类急剧增多,同时充斥着重复代码,此时的关键是划清责任。
改进版本一(组合代替继承)
package 设计模式;
public class Text {
public static void main(String[] args) {
Chinese p=new Chinese();
p.setName("ym");
highChinese hc=new highChinese(p);
hc.desc();
p.setName("my");
richChinese rc=new richChinese(p);
rc.desc();
American q=new American();
q.setName("Tom");
highrichAmerican hra=new highrichAmerican(q);
hra.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
{
public void desc()
{
System.out.print(name+"是中国人");
}
}
class American extends Person
{
public void desc()
{
System.out.print(name+"是美国人");
}
}
class highChinese
{
Chinese person;
public void desc()
{
person.desc();
System.out.println("是high人");
}
public highChinese(Chinese person)
{
this.person=person;
}
}
class richChinese
{
Chinese person;
public void desc()
{
person.desc();
System.out.println("是rich人");
}
public richChinese(Chinese person)
{
this.person=person;
}
}
class highrichChinese
{
Chinese person;
public void desc()
{
person.desc();
System.out.println("是high&rich人");
}
public highrichChinese(Chinese person)
{
this.person=person;
}
}
class highAmerican
{
American person;
public void desc() {
person.desc();
System.out.println("是high人");
}
public highAmerican(American person)
{
this.person=person;
}
}
class richAmerican
{
American person;
public void desc() {
person.desc();
System.out.println("是rich人");
}
public richAmerican(American person)
{
this.person=person;
}
}
class highrichAmerican
{
American person;
public void desc() {
person.desc();
System.out.println("是high&rich人");
}
public highrichAmerican(American person)
{
this.person=person;
}
当一个变量的声明类型都是某个基类的子类是,就该将他声明为这个基类的,由于多态可以使得它在未来运行时成为子类的对象。
基类代替子类,消除编译时的依赖
package 设计模式;
public class Text {
public static void main(String[] args) {
Chinese p=new Chinese();
p.setName("ym");
highChinese hc=new highChinese(p);
hc.desc();
p.setName("my");
richChinese rc=new richChinese(p);
rc.desc();
American q=new American();
q.setName("Tom");
highrichAmerican hra=new highrichAmerican(q);
hra.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
{
public void desc()
{
System.out.print(name+"是中国人");
}
}
class American extends Person
{
public void desc()
{
System.out.print(name+"是美国人");
}
}
class highChinese
{
Person person; //基类代替子类,消除编译时的依赖
public void desc()
{
person.desc();
System.out.println("是high人");
}
public highChinese(Person person)
{
this.person=person;
}
}
class richChinese
{
Person person; //基类代替子类,消除编译时的依赖
public void desc()
{
person.desc();
System.out.println("是rich人");
}
public richChinese(Person person)
{
this.person=person;
}
}
class highrichChinese
{
Person person; //基类代替子类,消除编译时的依赖
public void desc()
{
person.desc();
System.out.println("是high&rich人");
}
public highrichChinese(Person person)
{
this.person=person;
}
}
class highAmerican
{
Person person; //基类代替子类,消除编译时的依赖
public void desc() {
person.desc();
System.out.println("是high人");
}
public highAmerican(Person person)
{
this.person=person;
}
}
class richAmerican
{
Person person; //基类代替子类,消除编译时的依赖
public void desc() {
person.desc();
System.out.println("是rich人");
}
public richAmerican(Person person)
{
this.person=person;
}
}
class highrichAmerican
{
Person person; //基类代替子类,消除编译时的依赖
public void desc() {
person.desc();
System.out.println("是high&rich人");
}
public highrichAmerican(Person person)
{
this.person=person;
}
}
消除重复
package 设计模式;
public class Text {
public static void main(String[] args) {
Chinese p=new Chinese();
p.setName("ym");
highPerson hc=new highPerson(p);
hc.desc();
p.setName("my");
richPerson rc=new richPerson(p);
rc.desc();
American q=new American();
q.setName("Tom");
highrichPerson hra=new highrichPerson(q);
hra.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
{
public void desc()
{
System.out.print(name+"是中国人");
}
}
class American extends Person
{
public void desc()
{
System.out.print(name+"是美国人");
}
}
class highPerson
{
Person person;
public void desc()
{
person.desc();
System.out.println("是high人");
}
public highPerson(Person person)
{
this.person=person;
}
}
class richPerson
{
Person person;
public void desc()
{
person.desc();
System.out.println("是rich人");
}
public richPerson(Person person)
{
this.person=person;
}
}
class highrichPerson
{
Person person;
public void desc()
{
person.desc();
System.out.println("是high&rich人");
}
public highrichPerson(Person person)
{
this.person=person;
}
}
为实现接口继承基类Person
package 设计模式;
public class Text {
public static void main(String[] args) {
Chinese p=new Chinese();
p.setName("ym");
highPerson hc=new highPerson(p);
hc.desc();
p.setName("my");
richPerson rc=new richPerson(p);
rc.desc();
American q=new American();
q.setName("Tom");
highrichPerson hra=new highrichPerson(q);
hra.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
{
public void desc()
{
System.out.print(name+"是中国人");
}
}
class American extends Person
{
public void desc()
{
System.out.print(name+"是美国人");
}
}
class highPerson extends Person //为实现接口继承基类Person
{
Person person;
public void desc() //继承基类Person就能保证实现接口
{
person.desc();
System.out.println("是high人");
}
public highPerson(Person person)
{
this.person=person;
}
}
class richPerson extends Person //为实现接口继承基类Person
{
Person person;
public void desc() //继承基类Person就能保证实现接口
{
person.desc();
System.out.println("是rich人");
}
public richPerson(Person person)
{
this.person=person;
}
}
class highrichPerson extends Person //为实现接口继承基类Person
{
Person person;
public void desc() //继承基类Person就能保证实现接口
{
person.desc();
System.out.println("是high&rich人");
}
public highrichPerson(Person person)
{
this.person=person;
}
}
改进版本二(使用装饰模式<中间基类>)
package 设计模式;
public class Text {
public static void main(String[] args) {
Chinese p=new Chinese();
p.setName("ym");
highPerson hc=new highPerson(p);
hc.desc();
p.setName("my");
richPerson rc=new richPerson(p);
rc.desc();
American q=new American();
q.setName("Tom");
highrichPerson hra=new highrichPerson(q);
hra.desc();
}
}
abstract class Person
{
String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public abstract void desc();
};
//中间类
abstract class DecoratorPerson extends Person
{
Person person; //以聚合的方式支持未来多态的变化
public DecoratorPerson(Person person)
{
this.person=person;
}
};
class Chinese extends Person
{
public void desc()
{
System.out.print(name+"是中国人");
}
}
class American extends Person
{
public void desc()
{
System.out.print(name+"是美国人");
}
}
class highPerson extends DecoratorPerson
{//避免重复,实现接口继承DecoratorPerson
//Person person;
public void desc()
{
person.desc();
System.out.println("是high人");
}
public highPerson(Person person)
{
super(person);
}
}
class richPerson extends DecoratorPerson
{
//Person person;
public void desc()
{
person.desc();
System.out.println("是rich人");
}
public richPerson(Person person)
{
super(person);
}
}
class highrichPerson extends DecoratorPerson
{
//Person person;
public void desc()
{
person.desc();
System.out.println("是high&rich人");
}
public highrichPerson(Person person)
{
super(person);
}
}
保留单个属性,而组合属性操作就可以删除了
package 设计模式;
public class Text {
public static void main(String[] args) {
Chinese p=new Chinese();
p.setName("ym");
highPerson hc=new highPerson(p);
hc.desc();
p.setName("my");
richPerson rc=new richPerson(p);
rc.desc();
American q=new American();
q.setName("Tom");
//highrichPerson hra=new highrichPerson(q);
highPerson hp=new highPerson(q);
richPerson rp=new richPerson(hp);
rp.desc();
}
}
abstract class Person
{
String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public abstract void desc();
};
//中间类
abstract class DecoratorPerson extends Person
{
Person person; //以聚合的方式支持未来多态的变化
public DecoratorPerson(Person person)
{
this.person=person;
}
};
class Chinese extends Person
{
public void desc()
{
System.out.print(name+"是中国人");
}
}
class American extends Person
{
public void desc()
{
System.out.print(name+"是美国人");
}
}
class highPerson extends DecoratorPerson
{//避免重复,实现接口继承DecoratorPerson
//Person person;
public void desc()
{
person.desc();
System.out.println("是high人");
}
public highPerson(Person person)
{
super(person);
}
}
class richPerson extends DecoratorPerson
{
//Person person;
public void desc()
{
person.desc();
System.out.println("是rich人");
}
public richPerson(Person person)
{
super(person);
}
}
此时,无论是增加国家还是增加属性,只需增加一个类。
装饰类的代码实现
package 设计模式;
public class Text {
public static void main(String[] args) {
ConcreteComponent c=new ConcreteComponent();
ConcreteDecoratorA d1=new ConcreteDecoratorA();
ConcreteDecoratorB d2=new ConcreteDecoratorB();
d1.SetComponent(c);
d2.SetComponent(d1);
d2.Operation();
}
}
abstract class Component
{
public abstract void Operation();
}
class ConcreteComponent extends Component
{
public void Operation()
{//重写继承来的Operation()
System.out.println("具体对象的操作");
}
}
abstract class Decorator extends Component
//注意这里,装饰类也继承Component抽象类
{
protected Component component; //组合Component抽象类
public void SetComponent(Component component)
{//设置Component
this.component=component;
}
public void Operatin() //重写继承来的Operation()
{
if(component!=null)
{
component.Operation();
}
}
}
class ConcreteDecoratorA extends Decorator
{
private String addedState;//本类独有的功能
@Override
public void Operation() {
// TODO Auto-generated method stub
super.Operatin();
//首先运行原Decorator的Operation(),再执行本类的功能
//如addedState,相当于对原Component进行了装饰
addedState="New State";
System.out.println("具体装饰对象A的操作");
}
}
class ConcreteDecoratorB extends Decorator
{
public void Operation() {
// TODO Auto-generated method stub
super.Operatin();
//首先运行原Decorator的Operation(),再执行本类的功能
//如addedBeahavior(),相当于对原Component进行了装饰
addedBehavior();
System.out.println("具体装饰对象B的操作");
}
private void addedBehavior()
{//本类独有的方法
System.out.println("AddedBehavior Operation");
}
}
案例:给人搭配不同的服饰的系统
第一版
package 设计模式;
public class Text {
public static void main(String[] args) {
Person xc = new Person("小菜");
System.out.println("第一种装扮:");
xc.WearTShirts();
xc.WearBigTrouser();
xc.WearSneakers();
xc.Show();
System.out.println("第二种装扮:");
xc.WearSuit();
xc.WearTie();
xc.WearLeatherShoes();
xc.Show();
}
}
class Person
{
private String name;
public Person(String name)
{
this.name=name;
}
public void WearTShirts()
{
System.out.println("大T恤");
}
public void WearBigTrouser()
{
System.out.println("垮裤");
}
public void WearSneakers()
{
System.out.println("破球鞋");
}
public void WearSuit()
{
System.out.println("西装");
}
public void WearTie()
{
System.out.println("领带");
}
public void WearLeatherShoes()
{
System.out.println("皮鞋");
}
public void Show()
{
System.out.println("装扮的"+name);
}
}
增加新的装扮修改Person类,违背开放-封闭原则
第二版
package 设计模式;
public class Text {
public static void main(String[] args) {
Person xc = new Person("小菜");
System.out.println("第一种装扮:");
Finery dtx=new TShirts();
Finery kk=new BigTrouser();
Finery pqx=new Sneakers();
dtx.Show();
kk.Show();
pqx.Show();
xc.Show();
System.out.println("第二种装扮:");
Finery xz = new Suit();
Finery ld = new Tie();
Finery px = new LeatherShoes();
xz.Show();
ld.Show();
px.Show();
xc.Show();
}
}
class Person
{
private String name;
public Person(String name)
{
this.name=name;
}
public void Show()
{
System.out.println("装扮的"+name);
}
}
abstract class Finery
{
public abstract void Show();
}
class TShirts extends Finery
{
@Override
public void Show() {
// TODO Auto-generated method stub
System.out.print("大T恤"+" ");
}
}
class BigTrouser extends Finery {
@Override
public void Show() {
// TODO Auto-generated method stub
System.out.print("垮裤" + " ");
}
}
class Sneakers extends Finery {
@Override
public void Show() {
// TODO Auto-generated method stub
System.out.print("破球鞋" + " ");
}
}
class Suit extends Finery {
@Override
public void Show() {
// TODO Auto-generated method stub
System.out.print("西装" + " ");
}
}
class Tie extends Finery {
@Override
public void Show() {
// TODO Auto-generated method stub
System.out.print("领带" + " ");
}
}
class LeatherShoes extends Finery {
@Override
public void Show() {
// TODO Auto-generated method stub
System.out.print("皮鞋" + " ");
}
}
我们需要把所需的功能按正确的顺序串联起来进行控制
第三版(装饰模式)
package 设计模式;
public class Text {
public static void main(String[] args) {
Person xc = new Person("小菜");
System.out.println("第一种装扮:");
TShirts dtx=new TShirts();
BigTrouser kk=new BigTrouser();
Sneakers pqx=new Sneakers();
pqx.Decorate(xc);
kk.Decorate(pqx);
dtx.Decorate(kk);
dtx.Show();
System.out.println("第二种装扮:");
Suit xz = new Suit();
Tie ld = new Tie();
LeatherShoes px = new LeatherShoes();
px.Decorate(xc);
ld.Decorate(px);
xz.Decorate(ld);
xz.Show();
}
}
class Person
{
public Person()
{}
private String name;
public Person(String name)
{
this.name=name;
}
public void Show()
{
System.out.println("装扮的"+name);
}
}
class Finery extends Person
{
protected Person component;
public void Decorate(Person component)
{
this.component=component;
}
public void Show()
{
if(component!=null)
{
component.Show();
}
}
}
class TShirts extends Finery
{
@Override
public void Show() {
// TODO Auto-generated method stub
System.out.print("大T恤"+" ");
super.Show();
}
}
class BigTrouser extends Finery {
@Override
public void Show() {
// TODO Auto-generated method stub
System.out.print("垮裤" + " ");
super.Show();
}
}
class Sneakers extends Finery {
@Override
public void Show() {
// TODO Auto-generated method stub
System.out.print("破球鞋" + " ");
super.Show();
}
}
class Suit extends Finery {
@Override
public void Show() {
// TODO Auto-generated method stub
System.out.print("西装" + " ");
super.Show();
}
}
class Tie extends Finery {
@Override
public void Show() {
// TODO Auto-generated method stub
System.out.print("领带" + " ");
super.Show();
}
}
class LeatherShoes extends Finery {
@Override
public void Show() {
// TODO Auto-generated method stub
System.out.print("皮鞋" + " ");
super.Show();
}
}
- 以上部分摘取自朱红梅老师2020年5月的课件