我应该把我的第一种方法放在哪里

时间:2023-01-13 10:35:36

I've a need to add method that will calculate a weighted sum of worker salary and his superior salary. I would like something like this:

我需要添加一个方法来计算工人工资和他的高薪的加权和。我想要这样的东西:

class CompanyFinanse
{
      public decimal WeightedSumOfWorkerSalaryAndSuperior(Worker WorkerA, Worker Superior)
      {
           return WorkerA.Salary + Superior.Salary * 2;
      }
}

Is this a good design or should I put this method somewhere else? I'm just staring designing project and think about a good, Object Oriented way of organize methods in classes. So I would like start from beginning with OOP on my mind. Best practice needed!

这是一个很好的设计还是我应该把这个方法放在其他地方?我只是盯着设计项目并思考一种良好的,面向对象的方法来组织类中的方法。所以我想从头开始考虑OOP。需要最佳实践!

5 个解决方案

#1


So it may be impossible to give you a complete answer about "best practices" without knowing more about your domain, but I can tell you that you may be setting yourself up for disaster by thinking about the implementation details this early.

因此,在不了解您的域名的情况下,可能无法为您提供有关“最佳实践”的完整答案,但我可以告诉您,您可能会通过早期考虑实施细节来为自己做好准备。

If you're like me then you were taught that good OOD/OOP is meticulously detailed and involves BDUF. It wasn't until later in my career that I found out this is the reason so many projects become egregiously unmaintainable later on down the road. Assumptions are made about how the project might work, instead of allowing the design to emerge naturally from how the code is actually going to be used.

如果你像我一样,那么你就会被告知,好的OOD / OOP是精心细致的,并且涉及到BDUF。直到我职业生涯的后期才发现这是因为很多项目在未来之后变得异常难以维持。关于项目如何工作的假设,而不是允许设计自然地从代码实际使用的方式出现。

Simply stated: You need to being doing BDD / TDD (Behavior/Test Driven Development).

简单说明:你需要做BDD / TDD(行为/测试驱动开发)。

  1. Start with a rough domain model sketched out, but avoid too much detail.
  2. 从草拟的粗糙域模型开始,但要避免太多细节。

  3. Pick a functional area that you want to get started with. Preferably at the top of the model, or one the user will be interacting with.
  4. 选择您想要开始使用的功能区域。优选地在模型的顶部,或者用户将与之交互的一个。

  5. Brainstorm on expected functionality that the unit should have and make a list.
  6. 集思广益,了解该单位应具备的预期功能并列出清单。

  7. Start the TDD cycle on that unit and then refactor aggressively as you go.
  8. 在该单元上启动TDD循环,然后在您进行时积极地进行重构。

What you will end up with is exactly what you do need, and nothing you don't (most of the time). You gain the added benefit of having full test coverage so you can refactor later on down the road without worrying about breaking stuff :)

你最终会得到的就是你所需要的,而你没有(大部分时间)。你可以获得全面测试覆盖的额外好处,这样你就可以在以后的路上进行重构,而不必担心破坏东西:)

I know I haven't given you any code here, but that is because anything I give you will probably be wrong, and then you will be stuck with it. Only you know how the code is actually going to be used, and you should start by writing the code in that way. TDD focuses on how the code should look, and then you can fill in the implementation details as you go.

我知道我这里没有给你任何代码,但那是因为我给你的任何东西都可能是错的,然后你会被它困住。只有你知道代码实际上是如何使用的,你应该首先以这种方式编写代码。 TDD侧重于代码的外观,然后您可以随时填写实现细节。

A full explanation of this is beyond the scope of this post, but there are a myriad of resources available online as well as a number of books that are excellent resources for beginning the practice of TDD. These two guys should get you off to a good start.

对此的完整解释超出了本文的范围,但是在线提供了大量资源以及许多书籍,这些资源是开始TDD实践的极好资源。这两个家伙应该让你有一个良好的开端。

#2


I would either put it in the worker class, or have a static function in a finance library. I don't think a Finance object really makes sense, I think it would be more of a set of business rules than anything, so it would be static.

我要么把它放在工人类中,要么在财务库中有静态功能。我不认为财务对象真的有意义,我认为它将更多地是一组业务规则而不是任何东西,所以它将是静态的。

public class Worker {
     public Worker Superior {get;set;}
     public readonly decimal WeightedSalary {
         get {
              return (Superior.Salary * 2) + (this.Salary)
         }
     }
     public decimal Salary {get;set;}
}

or

public static class Finance {
     public static decimal WeightedSumOfWorkerSalaryAndSuperior(Worker WorkerA, Worker Superior) {
         return WorkerA.Salary + Superior.Salary * 2; }
}

#3


For your design to be Object Oriented, you should start by thinking of the purpose of the entire application. If there is only one method in your application (weighted sum), then there isn't too much design to go on.

为了使您的设计成为面向对象,您应该首先考虑整个应用程序的目的。如果您的应用程序中只有一种方法(加权和),那么设计就不会太多了。

If this is a finance application, maybe you could have a Salary class which contains a worker's salary and some utility functions.

如果这是一个财务应用程序,也许您可​​以拥有一个Salary类,其中包含worker的工资和一些实用程序功能。

For the method you pointed out, if the Worker class has a reference to his Superior, you could make this method part of the Worker class.

对于您指出的方法,如果Worker类具有对其Superior的引用,则可以将此方法作为Worker类的一部分。

Without more information on the purpose of the application, it's difficult to give good guidance.

如果没有关于申请目的的更多信息,很难给出良好的指导。

#4


Following up on the answer by brien, I suggest looking at the practice of CRC cards (Class-Responsibility-Collaboration). There are many sources of information, including:

根据布里恩的回答,我建议看看CRC卡的实践(Class-Responsibility-Collaboration)。有许多信息来源,包括:

  • this tutorial from Cal Poly,
  • 来自Cal Poly的本教程,

  • this orientation on the Agile Modeling web site, and
  • 这个方向在敏捷建模网站上,和

  • The CRC Card Book, which discusses the practice and its use with multiple languages.
  • CRC卡片书,讨论了多种语言的实践及其使用。

Understanding which class should "own" a particular behavior (and/or which classes should collaborate in implementing a given use case), is in general a top-down kind of discussion driven by the overall design of what your system is doing for its users.

了解哪个类应该“拥有”特定行为(和/或哪些类应该在实现给定用例时协作),通常是由系统为其用户执行的操作的整体设计驱动的自上而下的讨论类型。

#5


It is easy to find out whether your code needs improvement. There is a code smell in your snippet. You should address that.

很容易发现您的代码是否需要改进。您的代码段中有代码味道。你应该解决这个问题。

It is good that you have very declarative name for the method. But it is too long. It sounds like if you keep that method in this Finanse class it is inevitable that you have to use all those words in the method name to get the sense of what that method is intended to do.

你有这个方法的非常声明的名称是很好的。但它太长了。听起来如果你将这个方法保留在这个Finanse类中,你不可避免地必须使用方法名称中的所有单词来了解该方法的用途。

It basically means that this method may not belong to this class.

它基本上意味着此方法可能不属于此类。

One way to address this code smell is to see if you could get a shorter method name if we have the method on other class. I see you have Worker and Salary classes.

解决这种代码味道的一种方法是,如果我们在其他类上使用该方法,您是否可以获得更短的方法名称。我看到你有工人和工资班。

Assuming those are the only classes left and you don't want to add up more classes, I would put this on Salary. Salary knows how to calculate weighted salary given another salary (Superior salary in this case) as input. You don't need more than two words for the method name now.

假设这些是剩下的唯一类,你不想添加更多类,我会把它放在Salary上。工资知道如何计算加权工资给出另一个薪水(在这种情况下是高薪)作为输入。现在,方法名称不需要两个以上的单词。

@Shawn's answer is one variation of addressing this code smell. (I think you can call it as 'long method name' code smell)

@ Shawn的答案是解决这种代码气味的一种变体。 (我想你可以把它称为'长法名'代码味)

#1


So it may be impossible to give you a complete answer about "best practices" without knowing more about your domain, but I can tell you that you may be setting yourself up for disaster by thinking about the implementation details this early.

因此,在不了解您的域名的情况下,可能无法为您提供有关“最佳实践”的完整答案,但我可以告诉您,您可能会通过早期考虑实施细节来为自己做好准备。

If you're like me then you were taught that good OOD/OOP is meticulously detailed and involves BDUF. It wasn't until later in my career that I found out this is the reason so many projects become egregiously unmaintainable later on down the road. Assumptions are made about how the project might work, instead of allowing the design to emerge naturally from how the code is actually going to be used.

如果你像我一样,那么你就会被告知,好的OOD / OOP是精心细致的,并且涉及到BDUF。直到我职业生涯的后期才发现这是因为很多项目在未来之后变得异常难以维持。关于项目如何工作的假设,而不是允许设计自然地从代码实际使用的方式出现。

Simply stated: You need to being doing BDD / TDD (Behavior/Test Driven Development).

简单说明:你需要做BDD / TDD(行为/测试驱动开发)。

  1. Start with a rough domain model sketched out, but avoid too much detail.
  2. 从草拟的粗糙域模型开始,但要避免太多细节。

  3. Pick a functional area that you want to get started with. Preferably at the top of the model, or one the user will be interacting with.
  4. 选择您想要开始使用的功能区域。优选地在模型的顶部,或者用户将与之交互的一个。

  5. Brainstorm on expected functionality that the unit should have and make a list.
  6. 集思广益,了解该单位应具备的预期功能并列出清单。

  7. Start the TDD cycle on that unit and then refactor aggressively as you go.
  8. 在该单元上启动TDD循环,然后在您进行时积极地进行重构。

What you will end up with is exactly what you do need, and nothing you don't (most of the time). You gain the added benefit of having full test coverage so you can refactor later on down the road without worrying about breaking stuff :)

你最终会得到的就是你所需要的,而你没有(大部分时间)。你可以获得全面测试覆盖的额外好处,这样你就可以在以后的路上进行重构,而不必担心破坏东西:)

I know I haven't given you any code here, but that is because anything I give you will probably be wrong, and then you will be stuck with it. Only you know how the code is actually going to be used, and you should start by writing the code in that way. TDD focuses on how the code should look, and then you can fill in the implementation details as you go.

我知道我这里没有给你任何代码,但那是因为我给你的任何东西都可能是错的,然后你会被它困住。只有你知道代码实际上是如何使用的,你应该首先以这种方式编写代码。 TDD侧重于代码的外观,然后您可以随时填写实现细节。

A full explanation of this is beyond the scope of this post, but there are a myriad of resources available online as well as a number of books that are excellent resources for beginning the practice of TDD. These two guys should get you off to a good start.

对此的完整解释超出了本文的范围,但是在线提供了大量资源以及许多书籍,这些资源是开始TDD实践的极好资源。这两个家伙应该让你有一个良好的开端。

#2


I would either put it in the worker class, or have a static function in a finance library. I don't think a Finance object really makes sense, I think it would be more of a set of business rules than anything, so it would be static.

我要么把它放在工人类中,要么在财务库中有静态功能。我不认为财务对象真的有意义,我认为它将更多地是一组业务规则而不是任何东西,所以它将是静态的。

public class Worker {
     public Worker Superior {get;set;}
     public readonly decimal WeightedSalary {
         get {
              return (Superior.Salary * 2) + (this.Salary)
         }
     }
     public decimal Salary {get;set;}
}

or

public static class Finance {
     public static decimal WeightedSumOfWorkerSalaryAndSuperior(Worker WorkerA, Worker Superior) {
         return WorkerA.Salary + Superior.Salary * 2; }
}

#3


For your design to be Object Oriented, you should start by thinking of the purpose of the entire application. If there is only one method in your application (weighted sum), then there isn't too much design to go on.

为了使您的设计成为面向对象,您应该首先考虑整个应用程序的目的。如果您的应用程序中只有一种方法(加权和),那么设计就不会太多了。

If this is a finance application, maybe you could have a Salary class which contains a worker's salary and some utility functions.

如果这是一个财务应用程序,也许您可​​以拥有一个Salary类,其中包含worker的工资和一些实用程序功能。

For the method you pointed out, if the Worker class has a reference to his Superior, you could make this method part of the Worker class.

对于您指出的方法,如果Worker类具有对其Superior的引用,则可以将此方法作为Worker类的一部分。

Without more information on the purpose of the application, it's difficult to give good guidance.

如果没有关于申请目的的更多信息,很难给出良好的指导。

#4


Following up on the answer by brien, I suggest looking at the practice of CRC cards (Class-Responsibility-Collaboration). There are many sources of information, including:

根据布里恩的回答,我建议看看CRC卡的实践(Class-Responsibility-Collaboration)。有许多信息来源,包括:

  • this tutorial from Cal Poly,
  • 来自Cal Poly的本教程,

  • this orientation on the Agile Modeling web site, and
  • 这个方向在敏捷建模网站上,和

  • The CRC Card Book, which discusses the practice and its use with multiple languages.
  • CRC卡片书,讨论了多种语言的实践及其使用。

Understanding which class should "own" a particular behavior (and/or which classes should collaborate in implementing a given use case), is in general a top-down kind of discussion driven by the overall design of what your system is doing for its users.

了解哪个类应该“拥有”特定行为(和/或哪些类应该在实现给定用例时协作),通常是由系统为其用户执行的操作的整体设计驱动的自上而下的讨论类型。

#5


It is easy to find out whether your code needs improvement. There is a code smell in your snippet. You should address that.

很容易发现您的代码是否需要改进。您的代码段中有代码味道。你应该解决这个问题。

It is good that you have very declarative name for the method. But it is too long. It sounds like if you keep that method in this Finanse class it is inevitable that you have to use all those words in the method name to get the sense of what that method is intended to do.

你有这个方法的非常声明的名称是很好的。但它太长了。听起来如果你将这个方法保留在这个Finanse类中,你不可避免地必须使用方法名称中的所有单词来了解该方法的用途。

It basically means that this method may not belong to this class.

它基本上意味着此方法可能不属于此类。

One way to address this code smell is to see if you could get a shorter method name if we have the method on other class. I see you have Worker and Salary classes.

解决这种代码味道的一种方法是,如果我们在其他类上使用该方法,您是否可以获得更短的方法名称。我看到你有工人和工资班。

Assuming those are the only classes left and you don't want to add up more classes, I would put this on Salary. Salary knows how to calculate weighted salary given another salary (Superior salary in this case) as input. You don't need more than two words for the method name now.

假设这些是剩下的唯一类,你不想添加更多类,我会把它放在Salary上。工资知道如何计算加权工资给出另一个薪水(在这种情况下是高薪)作为输入。现在,方法名称不需要两个以上的单词。

@Shawn's answer is one variation of addressing this code smell. (I think you can call it as 'long method name' code smell)

@ Shawn的答案是解决这种代码气味的一种变体。 (我想你可以把它称为'长法名'代码味)