Java中的嵌套调用(装饰器模式)

Java中的嵌套调用(装饰器模式),java,design-patterns,Java,Design Patterns,我正在做一个基本的比萨饼程序。这个程序使用装饰图案设计在比萨饼中添加配料 public static void main(String[] args) { Pizza pizza = new PizzaBakery(); //lets put Onion,Pepper and Salami into pizza: pizza = new Salami(new Pepper(new Onion(pizza)));} 我的代码运行良好,能够创建比萨饼并放置其配料。 问题是,

我正在做一个基本的比萨饼程序。这个程序使用装饰图案设计在比萨饼中添加配料

public static void main(String[] args) {
    Pizza pizza = new PizzaBakery();
    //lets put Onion,Pepper and Salami into pizza:
    pizza = new Salami(new Pepper(new Onion(pizza)));}
我的代码运行良好,能够创建比萨饼并放置其配料。 问题是,我将从输入文件中获取比萨饼和配料订单

输入文件示例:

AddTopping 7辣椒苏朱克萨拉米香肠(7是比萨饼的ID)

加入1个辣椒洋葱

在比萨中添加配料必须是嵌套的(比如新的萨拉米香肠(新的胡椒粉(新的洋葱(比萨)))。有什么不同的方法来代替写很多if-else语句吗


编辑:文件中将有4种不同的配料,一个比萨饼最多可以包含3种配料。

你的代码对我来说很奇怪。首先,你说:

Pizza pizza = new PizzaBakery();
然后你做到了:

pizza = new Salami(new Pepper(new Onion(pizza)));
这意味着“比萨”现在是“意大利腊肠”的对象。根据你的描述,我会这样做:

public static void main (String[] args) {
    Pizza pizza = new Pizza();
    Salami s1 = new Salami(...);
    Pepper p1 = new Pepper(...);
    Onion  o1 = new  Onion(...);
    pizza.addToppings(s1, p1, o1);
}
  • 在Pizza类中添加一个方法:

    public class Pizza {
        // constructor
        public Pizza (...) {
        // ...
        }
    
        // function to add toppings
        public void addToppings (Salami s, Pepper p, Onion o) {
        // ...
        }
    }
    
  • 现在重新编写主函数,如下所示:

    public static void main (String[] args) {
        Pizza pizza = new Pizza();
        Salami s1 = new Salami(...);
        Pepper p1 = new Pepper(...);
        Onion  o1 = new  Onion(...);
        pizza.addToppings(s1, p1, o1);
    }
    

  • 你为什么认为你会有很多“如果”?我假设您的意思是,您将解析顺序,然后必须根据您在那里找到的内容构造一个调用字符串。我在这里看到的问题是,Decorator需要编译时调用构造。此外,Decorator主要用于添加宿主类不需要知道的正交内容的情况。你所做的可能更符合责任链

    责任链的好处在于:

    • 您可以在运行时构造链,然后调用第一个项,它将通过处理程序序列级联
    • 此外,如果需要的话,你可以强制订购,例如,如果我订购洋葱和蘑菇,可能需要先装上洋葱

    或者,您可以将顺序解析建模为解释器,并将构造过程转换为访问者模式。(将AST的构造与其评估配对的常用方法。)

    这不是装饰模式,因此无法满足练习的要求?我怀疑只要将类
    Salami
    等重命名为
    SalamiPizza
    或类似的名称,就可以消除混淆。@只要它们实现相同的接口,Heran原始代码就可以了。也许正如CollinD Saidings所说,命名问题是,它们实现了相同的接口&我将使用反射从名称中修复它们的名称创建类实例。谢谢,看起来像我要找的