2012-08-15 70 views
3

我有一个代码重复的情况(或是否?),我不知道如何避免它,但仍然保持清晰的代码。代码重复(或不) - JAVA

让我巨大的过于简单化的情况:

// let's say I have a interface Entity 

interface Entity { 

    public Entity add (Entity operand); 

} 

// And two classes that implement this interface 

class MyInteger implements Entity { 

    private int value; 

    public Entity add (Entity operand) 
    { 
     // here I have to manage the situation distinctly if operand is a MyInteger or MyString 

    } 

} 

class MyString implements Entity { 

    private String value; 

    public Entity add (Entity operand) 
    { 

    } 
} 

现在,我的问题是,该方法MyString中添加是bassicly一样的方法加入MyInteger。请记住,我有比这里提到的两种类型更多的类型,并且对于某些方法add来说是不一样的。

此代码是否重复?如果是这样,有没有办法避免它?因为我似乎无法想到一个。

另外,在add方法中,如何在不使用if(instanceof)语句的情况下在各种类型操作数之间切换?

+2

您是否听说过仿制药? – SiB 2012-08-15 08:59:20

回答

1

查找模板模式。您可以重构并为任何重复的代码添加一个Abstract类。如果这是特定于两个类的,那么您可以让这两个类扩展Abstract类。

为了避免instanceof我不确定什么是最好的,但是你可以链接一个特定于实体类的额外方法,然后在必要时调用超类/抽象类。最后,调查泛型提供了什么样的可能性。

1

听起来像你需要visitordouble-dispatch机制。

add(Entity operand)方法决定基于传递操作数做什么,所以你可以通过调用操作数回实现这一目标。例如

// in MyInteger 
public Entity add(Entity operand) { 
    operand.addInteger(this); 
} 

// in MyString 
public Entity add(Entity operand) { 
    operand.addString(this); 
} 

请注意,上述更改的实现类型称为。通过重定向回操作数,您的呼叫路径由最初使用的操作数所确定。

每个实体将不得不实施addInteger(MyInteger p),addString(MyString p)等,但在这个阶段你有具体的类型来处理,可以平凡地确定做什么。

请注意,您不必使用instanceof或类似的。以上是类型安全且完整的。例如添加新的操作数类型将导致一组显着的重构。

+0

这是一个干净的回调方式。但我不清楚这是如何取代'instanceof'的。纠正我,如果我错了,但这里的想法是让一个实体类型处理特定? – 2012-08-15 09:19:32

+1

如果添加MyDouble,则会在操作符上调用addDouble。每个操作人员都必须决定如何向自己添加双倍(不是不合理的) – 2012-08-15 09:22:32

+0

我不认为这有帮助。实体是一个接口,因此您不能将addInteger/addString作为方法调用,直到它在实体中实现。正如其他答案所说的那样,您需要一个抽象超类或实用方法。 – 2012-08-15 10:44:49

1

您可以使用抽象类并为其提供具体的添加方法。

+0

我不确定我关注。没有具体的添加方法。结果根据操作数的不同而不同。说我添加两个MyInteger,我的结果也是一个MyInteger,但如果我添加一个MyInteger到一个MyString,结果是一个MyString。你能给我一个你是什么意思的代码示例吗? – user1550876 2012-08-15 11:10:44

1

到目前为止,我在您的方法中看不到问题。

由于实体是一个实例,你可以解决重复代码:

  • 根本无视它,做重复的,因为它会给你一个干净的解决方案。 如果您只有少数情况下发生此类重复,可能会更好地以这种方式实施它。

  • 如前所述,实现一个抽象类,例如AbstractEntity一次将所有 方法实现为受保护的成员方法,并将MyInteger和MyString声明为子类。

  • 请继续进行子类化,考虑需要哪些方法来为哪个实体和 构建一个子类树。小心:如果你不能仔细设计,这将妨碍进一步的调整。

  • 使用实用类:具有公共静态方法的类和具有 的私有构造函数实现需要的功能。

如何找出实体类型:

  • 使用的instanceof(好吧,这是丑陋的)
  • 实现该接口的返回或属性类型枚举测试 方法: getType()== STRING或isString()
  • 在接口中实现您希望执行的方法:checkIfStringAndAddIt()。