以下OOP设计是否有更好的替代方案?

时间:2016-06-13 09:57:36

标签: java oop design-patterns

我有一组类,称之为Derived1, Derived2, ..., Derived6,每个类都是基类Base的子类。这些类在第三方Java包中定义。

我正在写一个类,它会写出这些对象的人类可读表示。我按如下方式解决了问题:为每个String transform(Derivedi object)i=1,2,...,6定义方法String transform(Base object)

例如,当Base obj = new Derived3(...)和我想要计算obj的表示时,会出现问题。表达式transform(obj)调用带有签名String transform(Base)的方法,该方法必须调用“正确”方法(在这种情况下是具有签名String transform(Derived3)的方法)。

方法String transform(Base object)委托通过if (obj instanceof Derivedi)形式的i=1,2,...,6形式的条件语句为每个String toReadable()工作到适当的方法。 (如果我控制了包,我会在基类上有一个抽象方法String transform(Base),每个派生类都必须实现;不幸的是在这种情况下我无法控制包。)

我不喜欢这个解决方案(很容易理解为什么)。 ngOnInit(){ if(this._vehicleService.isAuth()) { this.shownavBar=true; this._router.navigate('/characters') //how can i get this } }

的这种实现的替代方案是什么?

2 个答案:

答案 0 :(得分:1)

您可以尝试为每个类提供变换器(包含transform(...)的对象)。然后维护一个映射,将变换器映射到那些类(假设变换器本身是无状态的)。

示例:

class Transformer {
  Class<? extends Base> getTransformableClass() { ... }
  String transform( Base obj ){ 
    //check and cast obj to the actual type then create the string
  }
}

Map<Class<?>, Transformer> transformers = ...;
Transformer base = new BaseTransformer(); //the same for derived
transformers.put( base.getTransformableClass(), base );

请注意,使用CDI / Reflection可以稍微自动执行查找(即查找实现某个接口的所有类或使用某个注释进行注释)。

然后像这样使用它:

public String transform( Base obj) {
  //add null checks etc.

  return transformers.get(obj.getClass()).transform(obj);
}    

进一步注意,在实现变换器时,泛型可能会有所帮助,但是在地图中使用它们会使一些演员表/原始类型变得必要,因为您不知道从地图中获得的实际类型,即您作为开发人员知道transformers.get( Derived1.class )应该返回一个能够处理Derived1个实例的转换器,但是编译器不知道这个,因此需要你处理它并进行适当的转换。

答案 1 :(得分:0)

您可以使用getSimpleName()来获取类的名称,并在名称上使用switch语句。您仍然需要在transform(Base object)中完成此委派,但是会比几个if语句和instanceof检查更清晰。