大话设计模式之装饰模式总结-java实现

注:示例来自《大话设计模式》

现有如下要求 写一个可以给人搭配不同的服饰的系统 代码如下

Person类

package Test06;

public class Person {

    private String name;
    public Person(String name)
    {
        this.name = name;
    }

    public void WearTShirts()
    {
        System.out.print("大T恤 ");
    }

    public void WearBigTrouser()
    {
        System.out.print("垮裤 ");
    }

    public void WearSneakers()
    {
        System.out.print("破球鞋 ");
    }

    public void WearSuit()
    {
        System.out.print("西装 ");
    }

    public void WearTie()
    {
        System.out.print("领带 ");
    }

    public void WearLeatherShoes()
    {
        System.out.print("皮鞋 ");
    }

    public void Show()
    {
        System.out.print("装扮的"+name);
    }

}

客户端代码

package Test06;

public class Program {

    public static void main(String[] args)
    {
        Person xc = new Person("小菜");

        System.out.println("\n第一种装扮:");

        xc.WearTShirts();
        xc.WearBigTrouser();
        xc.WearSneakers();
        xc.Show();

        System.out.println("\n第二种装扮:");

        xc.WearSuit();
        xc.WearTie();
        xc.WearLeatherShoes();
        xc.Show();

    }

}

现在有个问题就是如果需要增加超人的装扮 该如何做呢
需要改Person类 违背了开放-封闭原则 应该把服饰都写成子类
重构后代码如下

Person类

package Test06;

public class Person {

    private String name;
    public Person(String name)
    {
        this.name = name;
    }

    public void Show()
    {
        System.out.print("装扮的"+name);
    }

}

服饰抽象类

package Test06;

public abstract class Finery {

    public abstract void Show();

}

各种服饰子类

package Test06;

public class TShirts extends Finery {

    @Override
    public void Show() {
        System.out.print("大T恤 ");   
    }   

}
package Test06;

public class BigTrouser extends Finery {

    @Override
    public void Show() {
        System.out.print("垮裤 ");    
    }

}
package Test06;

public class Sneakers extends Finery {

    @Override
    public void Show() {
        System.out.print("破球鞋 ");
    }

}
package Test06;

public class Suit extends Finery {

    @Override
    public void Show() {
        System.out.print("西装 ");
    }
}
package Test06;

public class Tie extends Finery {

    @Override
    public void Show() {
        System.out.print("领带 ");
    }
}
package Test06;

public class LeatherShoes extends Finery {

    @Override
    public void Show() {
        System.out.print("皮鞋 ");
    }
}

客户端代码

package Test06;

public class Program {

    public static void main(String[] args)
    {
        Person xc = new Person("小菜");

        System.out.println("\n第一种装扮:");

        Finery dtx = new TShirts();
        Finery kk = new BigTrouser();
        Finery pqx = new Sneakers();

        dtx.Show();
        kk.Show();
        pqx.Show();
        xc.Show();

        System.out.println("\n第二种装扮:");

        Finery xz = new Suit();
        Finery ld = new Tie();
        Finery px = new LeatherShoes();

        xz.Show();
        ld.Show();
        px.Show();
        xc.Show();

    }

}

上面的代码是一个词一个词显示出来的 就好比 光着身子 当着大家的面 先穿 T恤 再穿裤子 再穿鞋 应该把所需的功能按正确的顺序串联起来进行控制 用装饰模式看看如何实现 代码如下

Person类

package Test06;

public class Person {

    public Person()
    { }

    private String name;
    public Person(String name)
    {
        this.name = name;
    }

    public void Show()
    {
        System.out.print("装扮的"+name);
    }

}

服饰类

package Test06;

public class Finery extends Person {

    protected Person component;

    //打扮
    public void Decorate(Person component)
    {
        this.component = component;
    }
    @Override
    public void Show()
    {
        if (component != null)
        {
            component.Show();
        }
    }
}

具体服饰类

package Test06;

public class TShirts extends Finery {

    @Override
    public void Show() {
        System.out.print("大T恤 ");
        super.Show();
    }   

}
package Test06;

public class BigTrouser extends Finery {

    @Override
    public void Show() {
        System.out.print("垮裤 ");
        super.Show();
    }

}
package Test06;

public class Sneakers extends Finery {

    @Override
    public void Show() {
        System.out.print("破球鞋 ");
        super.Show();
    }

}
package Test06;

public class Suit extends Finery {

    @Override
    public void Show() {
        System.out.print("西装 ");
        super.Show();
    }
}
package Test06;

public class Tie extends Finery {

    @Override
    public void Show() {
        System.out.print("领带 ");
        super.Show();
    }
}
package Test06;

public class LeatherShoes extends Finery {

    @Override
    public void Show() {
        System.out.print("皮鞋 ");
        super.Show();
    }
}

客户端代码

package Test06;

public class Program {

    public static void main(String[] args)
    {
        Person xc = new Person("小菜");

        System.out.println("\n第一种装扮:");

        Sneakers pqx = new Sneakers();
        BigTrouser kk = new BigTrouser();
        TShirts dtx = new TShirts();

        pqx.Decorate(xc);
        kk.Decorate(pqx);
        dtx.Decorate(kk);
        dtx.Show();

        System.out.println("\n第二种装扮:");

        LeatherShoes px = new LeatherShoes();
        Tie ld = new Tie();
        Suit xz = new Suit();

        px.Decorate(xc);
        ld.Decorate(px);
        xz.Decorate(ld);
        xz.Show();

    }

}

装饰模式是为已有功能动态地添加更多功能的一种方式 它把每个要装饰的功能放在单独的类中 并让这个类包装它所要装饰的对象 可以在运行时 根据需要有选择地 按顺序地使用装饰功能包装对象

缺点:会产生过多的相似的对象 不容易排错

猜你喜欢

转载自blog.csdn.net/qq_26814945/article/details/82252742