加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程开发 > Java > 正文

java – 处理这个问题的正确设计是什么?

发布时间:2020-12-14 19:21:56 所属栏目:Java 来源:网络整理
导读:我正在开发一个遗留的Java应用程序,它可以解决“水果”和“蔬菜”问题. 它们在内部被视为不同的东西,因为它们没有共同的所有方法/属性,但是很多东西都完全类似于它们. 所以,我们有很多方法doSomethingWithAFruit(Fruit f)和doSomethingWithAVegetable(Veg v)

我正在开发一个遗留的Java应用程序,它可以解决“水果”和“蔬菜”问题.
它们在内部被视为不同的东西,因为它们没有共同的所有方法/属性,但是很多东西都完全类似于它们.

所以,我们有很多方法doSomethingWithAFruit(Fruit f)和doSomethingWithAVegetable(Veg v),即使用正确的doOtherStuffWithAFruit(Fruit f)/ doOtherStuffWithAVeg(Veg v).这些非常相似,只不过用水果做事的方法只能用水果做方法,对蔬菜做同样的事情.

我想重构这个以减少重复,但我不确定实现这一目标的最佳方法是什么.我已经阅读了一些关于某些设计模式的内容,但我不知道它是否让我更清楚. (我可以识别我使用的代码中的一些模式,但我真的不知道何时应该使用模式来改进周围的事情.也许我应该阅读更多有关重构自身的内容……)

我在考虑这两个选项:

1.创建一个可以具有Fruit或Vegetable实例的类,并将其传递给方法,尝试最小化重复.它会是这样的:

public void doSomething(Plant p) {
   // do the stuff that is  common,and then...
   if (p.hasFruit()) {
       doThingWithFruit(p.getFruit());
   } else {
       doThingWithVegetable(p.getVegetable());
   }
}

这会让事情变得更好,但我不知道……它仍然感觉不对.

我想到的另一种选择是在水果和蔬菜中加入一个与它们相同的东西,然后用它来传递它.我觉得这是更清洁的方法,虽然我需要使用instanceof并在需要特定于他们的东西时施放到Fruit / Vegetable.

那么,我还能在这做什么呢?这些方法的缺点是什么?

更新:请注意,问题有点简化,我正在寻找使用“植物”做事的方法,即主要“使用”它们而不是对它们做事的代码.话虽如此,我所指的那些类似方法不能在“Plants”类中,并且它们通常有另一个参数,如:

public void createSomethingUsingFruit(Something s,Fruit f);
public void createSomethingUsingVegetable(Something s,Vegetable v);

也就是说,除了水果/蔬菜之外,这些方法还有其他问题,并且不适用于任何水果/蔬菜类.

更新2:这些方法中的大多数代码只从Fruit / Vegetable对象中读取状态,并根据相应的类型创建其他类的实例,存储在数据库中等等 – 从我对回答中的问题回答我认为这很重要.

最佳答案
您可以使用的另一个选项,或者可能包含它作为解决方案的一部分,是询问消费者是否可以管理您传递的对象.此时,消费者有责任确保它知道如何处理发送它的对象.

例如,如果您的消费者被称为Eat,您可以执行以下操作:

Consumer e = new Eat();
Consumer w = new Water();
if( e.canProcess( myFruit ) )
   e.doSomethingWith( myFruit );
else if ( w.canProcess( myFruit ) )
   w.doSomethingWith( myFruit );

.... etc

但是你最终得到了很多/其他类,所以你自己创建一个工厂来确定你想要的消费者.您的工厂基本上执行if / else分支以确定哪个消费者可以处理您传递的对象,并将消费者返回给您.

所以它看起来像

public class Factory {
   public static Consumer getConsumer( Object o ){
    Consumer e = new Eat();
    Consumer w = new Water();
    if( e.canProcess( o ) )
       return e;
    else if ( w.canProcess( o ) )
       return w;
   }
}

然后你的代码变成:

Consumer c = Factory.getConsumer( myFruit );
c.doSomethingWith( myFruit );

当然,在消费者的canProcess方法中,它基本上是一个instanceof或一些其他函数,你可以确定它是否可以处理你的类.

public class Eat implements Consumer{
   public boolean canProcess(Object o ){
     return o instanceof Fruit;
   }
}

因此,您最终将责任从类转移到Factory类,以确定可以处理哪些对象.当然,诀窍在于所有消费者都必须实现通用接口.

我意识到我的伪代码是非常基本的,但它只是指出了一般的想法.根据您的类的结构,这可能会或可能不会在您的情况下工作和/或变得过度,但如果设计得很好,可以显着提高您的代码的可读性,并真正保持每个类型的所有逻辑自包含在他们自己的类中没有instanceof,if / then散布在各处.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读