我正在开发一个遗留 Java 应用程序,它处理“水果”和“蔬菜”,比如说,为了这个问题。它们在内部被视为不同的事物,因为它们没有共同的所有方法/属性,但是很多事情都与它们非常相似。
所以,我们有很多方法doSomethingWithAFruit(Fruit f)和doSomethingWithAVegetable(Veg v),它们使用正确的doOtherStuffWithAFruit(Fruit f) / doOtherStuffWithAVeg(Veg v)。和那些非常相似,除了用水果做事情的方法只调用水果做事情的方法,蔬菜也一样。
我想重构它以减少重复,但我不确定实现这一目标的最佳方法是什么。我读过一些关于一些设计模式的文章,但我不知道它是否让我更清楚。(我可以在我使用的代码中识别出一些模式,但我真的不知道什么时候应该应用模式来改进周围的事情。也许我应该阅读更多关于重构本身的内容......)
我在考虑这两个选项:
1.创建一个类,该类可以有一个水果或蔬菜的实例,并将其传递给方法,尽量减少重复。它会是这样的:
public void doSomething(Plant p) {
// do the stuff that is common, and then...
if (p.hasFruit()) {
doThingWithFruit(p.getFruit());
} else {
doThingWithVegetable(p.getVegetable());
}
}
这会让事情变得更好,但我不知道......它仍然感觉不对。
2.我认为的另一种选择是在水果和蔬菜中放置一个界面,其中包含它们共有的东西,并使用它来传递它。instanceof
我觉得这是更清洁的方法,尽管当需要特定于它们的东西时,我将不得不使用并转换为 Fruit/Vegetable。
那么,我还能在这里做什么呢?这些方法的缺点是什么?
更新:请注意,这个问题有点简化,我正在寻找用“植物”做事的方法,也就是说,主要是“使用”它们而不是对它们做事的代码。话虽如此,我所指的那些类似方法不能在“植物”类中,而且它们通常还有另一个参数,例如:
public void createSomethingUsingFruit(Something s, Fruit f);
public void createSomethingUsingVegetable(Something s, Vegetable v);
也就是说,这些方法除了 Fruits/Vegetables 之外还有其他问题,并且不适合放在任何 Fruit/Vegetable 类中。
更新 2:这些方法中的大多数代码仅从 Fruit/Vegetable 对象读取状态,并根据适当的类型创建其他类的实例,存储在数据库中等等——从我对评论中问题的回答,我认为这很重要。