设计模式-装饰模式

装饰模式:动态地给一个对象添加一些额外的职责,就增加功能来说,装饰模式比生成子类更为灵活
 

案例:人及其属性

普通实现

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月的课件

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值