装饰器设计模式,用于向现有对象添加新方法和代码

时间:2016-05-04 11:54:43

标签: java design-patterns decorator

我是设计模式的新手。我正在尝试使用装饰器设计模式为我现有的应用程序添加新的代码和功能。

假设我有一类App,它有两个方法“Add”和“Multiply”。在某些时候(运行时),应用程序也需要计算平均值。 所以,我正在尝试使用装饰器设计模式来实现这一点。

到目前为止,我有:

public class App implements Code{
  public int a=2;
  public int b=3;

  @Override
  public int Add(int a, int b) {
    int add;
    add = a+b;
    return add;
  }

  @Override
  public int Multiply(int a, int b) {
    int mul;
    mul= a*b;
    return mul;
  }

} 

为了做到这一点,我定义了一个接口“Code”,如下所示:

public interface Code {
  public int Add (int a, int b);
  public int Multiply (int a, int b);     
}

然后是装饰者抽象类CodeExtention

public abstract class CodeExtention implements Code{
  protected Code extendedCode;

  public CodeExtention(Code extendedCode) {
    this.extendedCode = extendedCode;
  }

  @Override
  public  int Multiply(int a, int b){
    return extendedCode.Multiply(a, b);
  }

  @Override
  public  int Add(int a, int b){
    return extendedCode.Add(a, b);
  }

}

现在我定义一个从我的抽象类扩展的Concec类“AVG”,如下所示:

public class AVG extends CodeExtention{

  public AVG(Code extendedCode) {
    super(extendedCode);
  }

  public int AVGcalculator (int a, int b){
    return (a+b)/2;    
  }

  @Override
  public int Add(int a, int b) {
    return super.Add(a, b); 
  }

  @Override
  public int Multiply(int a, int b) {
    return super.Multiply(a, b); 
  }          
}

现在我希望我的应用程序可以计算平均值,这样我就可以使用我的主要内容:

  public static void main(String[] args) {
    Code app = new App();
    app = new AVG(app);
  }   
} 

我可以在这里:

System.out.println(app.Add(3, 4));
System.out.println(app.Multiply(3, 4));

我仍然不能:

System.out.println(app.AVGcalculator(3, 4));

我不知道出了什么问题,或者即使我可以在我的场景中使用这种设计模式!

2 个答案:

答案 0 :(得分:1)

该应用程序属于Code类型,因为AVGcalculator不是Code接口的一部分,如果你想调用AVGcalculator你不能调用它就可以这样做

System.out.println(((AVG)app).AVGcalculator(3, 4));

答案 1 :(得分:1)

装饰者模式对此非常糟糕。

装饰器履行与装饰对象相同的合同 - 相同的API。你想要的是改变合同。因此,该模式不适用(阅读this以获得何时使用装饰器的好例子。)

您可以使用命令模式:

interface BinaryIntOperation {
    int execute(int a, int b);
}

class AddOperation implements BinaryIntOperation {
    int execute(int a, int b) {
        return a + b;
    }
}

 class MultiplyOperation implements BinaryIntOperation {
    int execute(int a, int b) {
        return a * b;
    }
}

 class AverageOperation implements BinaryIntOperation {
    int execute(int a, int b) {
        return (a + b)/2;
    }
}

然后你可以从那里做很多事情:

BinaryIntOperation op = new AddOperation();
System.out.println(op.execute(3, 4));

op = new MultiplyOperation();
System.out.println(op.execute(4, 5));

你也可以这样写:

public int[] execute(int[] arr, BinaryIntOperation op, int a) {
    for (int i = 0; i < arr.length; i++)
        arr[i] = op.execute(a, arr[i]);
    return arr;
}

命令模式是一种行为模式,看起来更像你想要的(改变行为)。

请注意,在C#中,您可以使用扩展方法 完全所需的内容。但Java没有那些。