Java 用于填充值对象的面向对象代码

Java 用于填充值对象的面向对象代码,java,oop,procedural-programming,Java,Oop,Procedural Programming,这是一个低级设计问题。我试图掌握面向对象编程 我正在用一个方法编写一个Java类,该方法设置值对象的数据成员的值。这些值是由我的类根据一些业务逻辑计算的。最后,我的类应该返回这样填充的值对象。最面向对象的方法是什么 一种可能的方法是,在我的Java类中为我需要设置的每个数据成员(VO)创建compute()方法,这似乎是我的方向。每个计算方法都返回我使用value对象的相应setter方法设置的所需值。 然而,我认为这种方法比面向对象的方法更程序化,因为我只是按顺序程序调用这些计算方法,并填充我

这是一个低级设计问题。我试图掌握面向对象编程

我正在用一个方法编写一个Java类,该方法设置值对象的数据成员的值。这些值是由我的类根据一些业务逻辑计算的。最后,我的类应该返回这样填充的值对象。最面向对象的方法是什么

一种可能的方法是,在我的Java类中为我需要设置的每个数据成员(VO)创建compute()方法,这似乎是我的方向。每个计算方法都返回我使用value对象的相应setter方法设置的所需值。 然而,我认为这种方法比面向对象的方法更程序化,因为我只是按顺序程序调用这些计算方法,并填充我的值对象

那么我可以使用/查看哪些设计(…设计模式,可能?)或最佳实践,从而使此代码成为面向对象的。

代表代码(我现在拥有的):


嗯,这真的取决于责任和计算方法。你应该记住SRP(http://en.wikipedia.org/wiki/Single_responsibility_principle)做你的OO设计。还有高内聚性和松耦合原则

如果computeA()、B和C不相关,则应拆分适配器类。如果它们是相关的,那么您的适配器类应该以不同的方式命名,以表达它真正的功能。例如:税务计算器

然后,您可以创建一个新类,该类接收一个TaxCalculator和一个MyValueObject,并执行应用。或者干脆把apply放在计算器里(尽管一个类有两个职责,这通常是不好的)。在后一种情况下,也许您可以调用类TaxCalculationSetter或类似的东西,并将计算方法设置为私有。瞧,你会再次满足SRP的要求

始终记住,“什么是责任”是一件有点主观的事情


我希望这澄清了一些事情。

对我来说没问题。您不应该总是寻找要使用的编程模式。最重要的是亲吻(保持它的愚蠢和简单)

<>我想考虑MyValueObjt对象是否可以是不可变的。< /P>
class Adapter {   // this is my Java class
    MyValueObject applyBusinessLogic(Input object){
        return new MyValueObject(computeA(),computeB(),computeC());
    }

    String computeA() { ...some logic... return a;}
    String computeB() { ...some logic... return b;}
    String computeC() { ...some logic... return c;}
}

class MyValueObject {
    final String a;
    final String b;
    final String c;

    public MyValueObject(String a, String b, String c){
        this.a=a;
        this.b=b;
        this.c=c;
    }

}

正如izaera已经提到的那样,这在很大程度上取决于您没有提供的细节或问题。但是,至少有一件事在我看来是不对的:

看来,构建您的价值对象需要一些逻辑。现在的问题是,它应该去哪里?您已经在适配器中完成了。但是,这可能是不对的,因为VO的构造属于VO而不是适配器。因此,我肯定会将这一逻辑转移到VO本身——作为其构造的一部分

因此,在我看来,将该逻辑移动到VO可以改进设计

...
MyValueObject vo = new MyValueObject(); 
vo.setA(required input);
vo.setB(required input);
vo.setC(required input);

class MyValueObject {
      String a;
      String b;
      String c;

      public void setA(required input)
      {  
          ... some logic
          this.a = result of logic
      }

      public void setB(required input)
      {  
          ... some logic
          this.b = result of logic
      }

      public void setC(Srequired input)
      {
             ... some logic
          this.c = result of logic
      }
}

显然,如果立即使用构造函数进行构造,整个过程会变得更好,除非您必须使用setter,比如说,您正在使用某种ORM等。

您可以查看构建器模式“什么是最面向对象的方法?”-没有最面向对象的方法。所以我想知道你为什么这么问。@hakre我的基本意思是,制作这个过程代码的方法是什么,面向对象的。顺便说一句:在一行中调用三个方法不是过程的,也不是面向对象的。只是:一个接一个地调用三个方法。我的值对象的一些数据成员是类本身的对象,我也需要计算它们。我相信尝试将我的适配器拆分为一些助手实用程序可能会有所帮助。有些只能创建这些子对象,我想我可以创建一些可以完成所有类似任务的子对象。我们将尽快尝试并更新这方面的工作方式。谢谢。你也应该试试TDD(如果还没有做的话),它会让你更容易、更自然地解决这类设计问题。很有趣。但是这难道不意味着MyValueObject类现在变得越来越复杂——它不再遵循SRP了吗?每个属性a、b、c等的计算都是复杂的,有些需要服务调用。仍然按照您建议的路线,我在考虑是否应该扩展MyValueObject类并重载子类中的setter/getter,在子类中我可以完成所有复杂的计算。这样,子类只对属性进行计算,而超类只是一个普通的旧值对象。最后,我可以返回子类的所有熟实例,但由超类MyValueObject的引用引用。那怎么样?不幸的是,我可以提供更多关于设计细节的信息,因为我没有足够的信息。但是,将逻辑移动到客户机类并不会降低其复杂性。如果您认为它太复杂,请考虑将其分解为模块的方法。但同样,模块应该具有逻辑意义,而不是代码的随机分解。
...
MyValueObject vo = new MyValueObject(); 
vo.setA(required input);
vo.setB(required input);
vo.setC(required input);

class MyValueObject {
      String a;
      String b;
      String c;

      public void setA(required input)
      {  
          ... some logic
          this.a = result of logic
      }

      public void setB(required input)
      {  
          ... some logic
          this.b = result of logic
      }

      public void setC(Srequired input)
      {
             ... some logic
          this.c = result of logic
      }
}