例子:一个可以给人搭配不同服饰的系统,即可以换各种各样的衣服裤子的个人形象系统
最先想到的是,先建一个Person类
package deractor;
public class Person {
private String name;
public Person(String name){
this.name=name;
}
public void show(){
System.out.println("装扮"+name);
}
}
各种服饰的抽象类
package deractor;
abstract class Finery {
public abstract void Show();
}
服饰子类
package deractor;
public class TShirts extends Finery{
@Override
public void Show() {
// TODO Auto-generated method stub
System.out.println("大T恤");
}
}
package deractor;
public class BigTrouser extends Finery{
@Override
public void Show() {
// TODO Auto-generated method stub
System.out.println("垮裤");
}
}
package deractor;
public class WearSneakers extends Finery{
@Override
public void Show() {
// TODO Auto-generated method stub
System.out.println("破球鞋");
}
}
package deractor;
public class WearSuit extends Finery{
@Override
public void Show() {
// TODO Auto-generated method stub
System.out.println("西装");
}
}
测试代码
package deractor;
public class Test {
public static void main(String[] args) {
// TODO Auto-generated method stub
Person test=new Person("Autumn");
System.out.println("装扮如下");
Finery ts=new TShirts();
Finery bt=new BigTrouser();
Finery ws=new WearSneakers();
Finery wsuit=new WearSuit();
ts.Show();
bt.Show();
ws.Show();
wsuit.Show();
}
}
Test中,把“大T恤”、“垮裤”、“破球鞋”、“西装”一个一个进行显示,好比:你光着身子,当着大家的面,一件一件穿上衣服,so,应该在内部组装完毕
即装饰模式Decorator,动态地给一个对象添加一些额外的职责,就增加功能来说,装饰模式比生成子类更为灵活。
其中,Component定义一个对象接口,可以给这些对象动态地添加职责。ConcreteComponent定义了一个具体的对象,也可以给这个对象添加一些职责。Decorator装饰抽象类,继承了Component,从外类来扩展Component类的功能,但对于Component来说,无需知道Decorator的存在,至于ConcreteDecorator就是具体的装饰对象,起到给Component添加职责的功能。基本代码实现如下:
package deractor;
abstract class Component {
public abstract void Operation();
}
package deractor;
public class ConcreteComponent extends Component{
@Override
public void Operation() {
// TODO Auto-generated method stub
System.out.println("具体的操作对象");
}
}
package deractor;
abstract class Decorator extends Component{
protected Component component;
public void setComponent(Component component){
this.component=component;
}
// 重写Operation,实际执行的是Component的Operation
public void Operation(){
if(component!=null){
component.Operation();
}
}
}
package deractor;
public class ConcreteDecoratorA extends Decorator{
private String addedState;
public void Operation(){
super.Operation();//首先运行原Operation,再执行本类的功能,如addedState,相当于对原Component进行了装饰
addedState="new state";
System.out.println("具体装饰对象A的操作");
}
}
package deractor;
public class ConcreteDecoratorB extends Decorator{
public void Operation(){
super.Operation();
AddedBehavior();
System.out.println("具体装饰对象B的操作");
}
private void AddedBehavior(){
}
}
装饰的方法是:先用ConcreteComponent实例化对象c,然后用ConcreteDecoratorA的实例化对象d1来包装c,再用ConcreteDecoratorB的对象d2包装d1,最终执行d2的Operation
package deractor;
public class DeTest {
public static void main(String[] args) {
// TODO Auto-generated method stub
ConcreteComponent c=new ConcreteComponent();
ConcreteDecoratorA d1=new ConcreteDecoratorA();
ConcreteDecoratorB d2=new ConcreteDecoratorB();
d1.setComponent(c);
d2.setComponent(d1);
d2.Operation();
}
}
如果只有一个ConcreteComponent类而没有抽象的Component类,那么Decorator类可以是ConcreteComponent的一个子类,如果只有一个ConcreteDecorator类,那么就没有必要建立一个单独的Decorator类,而是可以把Decorator和ConcreteDecorator的责任合并成一个类
将上述衣服搭配稍作修改
package deractor;
public class PersonConcreteComponent {
private String name;
public PersonConcreteComponent(){}
public PersonConcreteComponent(String name){
this.name=name;
}
public void Show(){
System.out.println("装扮的"+name);
}
}
package deractor;
public class FineryDecorator extends PersonConcreteComponent{
protected PersonConcreteComponent component;
public void Decorate(PersonConcreteComponent component){
this.component=component;
}
public void Show(){
if(component!=null){
component.Show();
}
}
}
package deractor;
public class TShirts2 extends FineryDecorator{
@Override
public void Show() {
// TODO Auto-generated method stub
super.Show();
System.out.println("大T恤");
}
}
package deractor;
public class WearSneakers2 extends FineryDecorator{
@Override
public void Show() {
// TODO Auto-generated method stub
super.Show();
System.out.println("破球鞋");
}
}
package deractor;
public class BigTrouser2 extends FineryDecorator{
@Override
public void Show() {
// TODO Auto-generated method stub
super.Show();
System.out.println("垮裤");
}
}
package deractor;
public class DecorateTest {
public static void main(String[] args) {
// TODO Auto-generated method stub
PersonConcreteComponent person=new PersonConcreteComponent("Autumn");
System.out.println("the following装扮");
TShirts2 ts=new TShirts2();
BigTrouser2 bt=new BigTrouser2();
WearSneakers2 ws=new WearSneakers2();
ts.Decorate(person);
bt.Decorate(ts);
ws.Decorate(bt);
ws.Show();
}
}
运行结果:
the following装扮
装扮的Autumn
大T恤
垮裤
破球鞋
由此可以看出,装饰模式把每个要装饰的功能放在单独的类中,并让这个类包装它索要装饰的对象,因此,当需要执行特殊行为时,客户代码就可以在运行时根据需要有选择地、按顺序地使用装饰功能包装对象。