Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/design-patterns/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
java中的装饰器设计模式_Java_Design Patterns_Inheritance_Anonymous Class - Fatal编程技术网

java中的装饰器设计模式

java中的装饰器设计模式,java,design-patterns,inheritance,anonymous-class,Java,Design Patterns,Inheritance,Anonymous Class,我正在设计一个我必须做的项目。为此,我考虑使用decorator设计模式。然而,我必须调整我的设计以适应项目的现有实施。那么,我不能完全保留装饰设计模式 该项目有一个抽象基类(称为A)和一组子类(称为A1、A2、A3、A4等)。我不能修改这些类的代码 然后,我必须为这些类添加额外的函数性。为此,我创建了一个用于类A(装饰器)的抽象类(称为B)。我还创建了用于类A1、A2、A3、A4等的混凝土装饰器 注意:如您所见,我不使用任何接口,因为类A不使用任何接口,我无法修改此代码 但我看到了这个设计中的

我正在设计一个我必须做的项目。为此,我考虑使用decorator设计模式。然而,我必须调整我的设计以适应项目的现有实施。那么,我不能完全保留装饰设计模式

该项目有一个抽象基类(称为A)和一组子类(称为A1、A2、A3、A4等)。我不能修改这些类的代码

然后,我必须为这些类添加额外的函数性。为此,我创建了一个用于类A(装饰器)的抽象类(称为B)。我还创建了用于类A1、A2、A3、A4等的混凝土装饰器

注意:如您所见,我不使用任何接口,因为类A不使用任何接口,我无法修改此代码

但我看到了这个设计中的一些问题:

1) B1类、B2类、B3类、B4类,。。。必须添加A1、A2、A3、A4类的所有方法,。。。用于调用类A1、A2、A3、A4的方法。。。例如,在B1类中:

    class B1 {
      public A1 objectA1;

      B1() {
          objectA1 = new A1();
      }

      public void add(int value) {
          objectA1.add(value);
          // extra funcionality
      } 
    }    
这可能是一个问题,因为如果其他开发人员修改类a、A1、A2、A3、A4的代码,。。。他们还需要修改代码B,B1,B2,B3,B4,。。。 我想防止这种情况发生

2) 此外,类A、A1、A2、A3、A4具有仅可从自己的类或子类访问的受保护方法。因为我需要访问这些方法,所以我不能使用decorator设计模式

第二种选择

我可以用B1、B2、B3、B4扩展A1、A2、A3、A4类。例如:

    class B1 extends A1 {

      B1() {
          objectA1 = new A1();
      }

      public void add(int value) {
          super.add(value);
          // extra funcionality
      } 
    }    
通过这种方式,我解决了第二个问题,并避免重写A1的所有方法,只重写必要的方法。即使如此,每次创建a的子类时,都需要创建相应的类B。 我想防止这种情况发生,因为只需要类B(B1,B2,…)重写类a(A1,A2,…)的方法

第三种选择

那么,我认为我可以把B类(B1,B2,……)看作是类A(A1,A2,…)的包装器。这样,将创建一个B实例,如下所示:

    new BMaker.get(A1, params_of_constructor_A1)
    new BMaker.get(A2, params_of_constructor_A2)
    new BMaker.get(A3, params_of_constructor_A3)
    new BMaker.get(A4, params_of_constructor_A4) or 
    ...
    new BMaker.get(AN, params_of_constructor_AN)
其中BMaker.get是一个静态方法

    public static <T extends A> A get (T objectA, params ) {
        // return anonymous class (*1)
    }
publicstaticaget(T objectA,params){
//返回匿名类(*1)
}
我的问题是,是否有可能实现一个继承A1,A2。。。 如果BMaker.get()的第一个参数是A1、A2、A3,…,则对BMaker.get()的每次调用都应该创建一个不同的匿名类depending on

真的,我不知道是否有可能做到这一点,或者是否有其他更好的方法


任何帮助都将不胜感激

对第一个问题的回答:

  • 或者将接口I放在一个上,这样您的装饰者/代理就可以实现相同的接口,或者

  • 创建一个接口I(相当于A的api)和一个包装类AW,它通过将所有调用直接传递给A来包装A并实现I

  • 将您的客户机代码转换为使用I而不是A,然后您就可以愉快地继续使用新接口构建decorators/或委托,并将旧的crunk“包装”到AW中

    出现的一个值得注意的问题是,某些使用A(IdentityHashMaps,persistence)的代码样式可能需要引用“底层”A。如果出现这种情况,可以在接口
    getunderyinga()
    中放置一个方法。尽量避免使用太多,因为它显然绕过了所有的装饰


    第二个问题:装饰子类型

    这里的问题是,子类型是否需要作为不同的装饰器类型公开——或者是否可以公开一个统一的装饰器,即(可能,若必要的话)在内部知道它可以包装的子类型的类型系统

    如果子类型是众所周知且稳定的,则可以在接口中实现“句柄样式”api。例如,对于文件系统实体,您可以提供单一类型的句柄,但提供用于查询类型的
    isFile()
    isDirectory()
    isDevice()
    isDrive()
    isRaw()
    等方法。可以使用
    listFiles()
    方法来使用目录子类型

    我的问题是,为什么需要外部访问(从装饰程序)受保护的方法?如果您这样做,这些方法应该是公共的,并且原始设计被破坏/扩展不足

    也许您可以在同一个包中创建一个静态帮助器类(如果不更改a类本身的话),这样您就可以从装饰器中正确地访问这个遗留的crunk


    这里有一个特定的点,正确地完成您的工作有时确实涉及到使用和潜在地升级遗留代码。如果没有一个高效且可维护的设计方案,那就不应该是一个完全的症结所在。将类型系统加倍(创建两个平行的继承人)绝对不是您应该做的事情

    如果没有一个好的方法可以做到这一点,那么你应该做其他的事情(不同的特性/需求),而不是让代码库变得更糟。

    你把decorator和delegator搞混了。你试过委托人,但想要装饰人。在维基百科上搜索这些术语。