2013-11-02 92 views
0

我正在设计一个我必须做的项目。为此,我曾想过使用装饰设计模式。但是,我必须将我的设计调整到项目的现有实施。然后,我无法完全保留装饰设计模式。java中的装饰设计模式

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

然后,我有额外的funcionality添加到这些类。为此,我创建了一个用于类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具有受保护方法,只有可以从自己的类或子类进行访问。由于我需要访问这些方法,我不能使用装饰设计模式。

第二替代

我可以与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) 
    } 

我的问题是,如果有可能实现继承A1,A2,... 每次调用BMaker.get(的)一个匿名类应该创建一个不同的匿名类,如果第一个参数deppending上的BMaker.get()为A1,A2,A3,...

真的,我不知道这是否是可能做到这一点,还是有其他更好的办法。

任何帮助,将不胜感激!

+1

你在* decorator *与* delegator *混淆。你试过委托人,但是*想*装饰者。搜索维基百科的条款。 – Bohemian

回答

2

回答第一个问题:

  1. 要么穿上这样的接口我你的装饰/委托可以实现相同的接口,或者

  2. 创建一个接口I(相当于A的API)和一个封装类AW,它封装了A并通过将所有调用直接传递给它来实现I。

将您的客户端代码中使用我,而不是一个,然后你就可以高高兴兴地着手建设使用具有“包起来”的老旷课在AW新界面装饰/或代表。

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


第二个问题:装饰子类型。

这里的问题是这些子类型是否需要暴露为不同的装饰类型 - 或者是否可以暴露一个统一的修饰符,(可能的话,如果需要的话)内部知道A子类型的类型系统它可以包装。

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

我的问题是为什么你需要外部访问(从装饰)到受保护的方法?如果你这样做,这些方法应该是公开的和原始设计破碎/不够可扩展。

也许你可以在同一个包中创建一个静态辅助类(如果不是改变A类本身),它会让你从装饰器中正确访问这个遗留的crunk。


有一定的点这里,这里适当做你的工作有时的确涉及与&工作可能升级的遗留代码。如果没有高效的可维护设计替代方案,那不应该是一个总的问题。加倍类型系统(创建两个并行的heirarchies)绝对不是你应该做的。

如果没有一个好的方法来做到这一点,你应该做其他事情(不同的功能/要求),而不是让代码库变得更糟。