Adding State in Decorator Pattern

后端 未结 3 855
眼角桃花
眼角桃花 2021-01-22 09:07

I wonder how to add state to the chain of decorators that will be available to the consumer. Given this simplified model:

abstract class AbstractPizza 
{
    pub         


        
3条回答
  •  离开以前
    2021-01-22 09:36

    one way of adding state is by using a self referential data structure (a list). but this uses the visitor pattern and does more than you probably want. this code is rewritten from A little Java, a few patterns

    // a self referential data structure with different types of nodes
    abstract class Pie
        {
        abstract Object accept(PieVisitor ask);
        }
    class Bottom extends Pie
        {
        Object accept(PieVisitor ask) { return ask.forBottom(this); }
        public String toString() { return "crust"; }
        }
    class Topping extends Pie
        {
        Object topping;
        Pie rest;
        Topping(Object topping,Pie rest) { this.topping=topping; this.rest=rest; }
        Object accept(PieVisitor ask) { return ask.forTopping(this); }
        public String toString() { return topping+" "+rest.toString(); }
        }
    //a class to manage the data structure
    interface PieManager
        {
        int addTopping(Object t);
        int removeTopping(Object t);
        int substituteTopping(Object n,Object o);
        int occursTopping(Object o);
        }
    class APieManager implements PieManager
        {
        Pie p=new Bottom();
        // note: any object that implements a rational version of equal() will work
        public int addTopping(Object t)
            {
            p=new Topping(t,p);
            return occursTopping(t);
            }
        public int removeTopping(Object t)
            {
            p=(Pie)p.accept(new RemoveVisitor(t));
            return occursTopping(t);
            }
        public int substituteTopping(Object n,Object o)
            {
            p=(Pie)p.accept(new SubstituteVisitor(n,o));
            return occursTopping(n);
            }
        public int occursTopping(Object o)
            {
            return ((Integer)p.accept(new OccursVisitor(o))).intValue();
            }
        public String toString() { return p.toString(); }
        }
    //these are the visitors
    interface PieVisitor
        {
        Object forBottom(Bottom that);
        Object forTopping(Topping that);
        }
    class OccursVisitor implements PieVisitor
        {
        Object a;
        OccursVisitor(Object a) { this.a=a; }
        public Object forBottom(Bottom that) { return new Integer(0); }
        public Object forTopping(Topping that)
            {
            if(that.topping.equals(a))
                return new Integer(((Integer)(that.rest.accept(this))).intValue()+1);
                else return that.rest.accept(this);
            }
        }
    class SubstituteVisitor implements PieVisitor
        {
        Object n,o;
        SubstituteVisitor(Object n,Object o) { this.n=n; this.o=o; }
        public Object forBottom(Bottom that) { return that; }
        public Object forTopping(Topping that)
            {
            if(o.equals(that.topping))
                that.topping=n;
            that.rest.accept(this);
            return that;
            }
        }
    class RemoveVisitor implements PieVisitor
        {
        Object o;
        RemoveVisitor(Object o) { this.o=o; }
        public Object forBottom(Bottom that) { return new Bottom(); }
        public Object forTopping(Topping that)
            {
            if(o.equals(that.topping))
                return that.rest.accept(this);
                else return new Topping(that.topping,(Pie)that.rest.accept(this));
            }
        }
    public class TestVisitor
        {
        public static void main(String[] args)
            {
            // make a PieManager
            PieManager pieManager=new APieManager();
            // add some toppings
            pieManager.addTopping(new Float(1.2));
            pieManager.addTopping(new String("cheese"));
            pieManager.addTopping(new String("onions"));
            pieManager.addTopping(new String("cheese"));
            pieManager.addTopping(new String("onions"));
            pieManager.addTopping(new String("peperoni"));
            System.out.println("pieManager="+pieManager);
            // substitute anchovies for onions
            int n=pieManager.substituteTopping(new String("anchovies"),new String("onions"));
            System.out.println(n+" pieManager="+pieManager);
            // remove the 1.2's
            n=pieManager.removeTopping(new Float(1.2));
            System.out.println(n+" pieManager="+pieManager);
            // how many anchovies do we have?
            System.out.println(pieManager.occursTopping(new String("anchovies"))+" anchovies");
            }
        }
    

提交回复
热议问题