问题
I have to develop a class, part of a financial application, which receives two properties and returns two results. Before you think that it is not a class, but method(s), I have to say that I have to persist both: the two user-provided parameters and the two outputs. Let's illustrate like follows in this mock:
----------------
|PetWash |
|----------------|
|petWeight |<- user provided
|petHeight |<- user provided
|ammountSoapUsed |<- system calculated
|price |<- system calculated
----------------
Should I do calculations in model classes? eg., the same model class that represents this entity should enclose the methods that do these calculations? Or should I create a kind of "calculation Engine" that would return data and store it in calculated fields?
If the first case, should I invoke calculations in the getter methods or just create a "calculate" method which would update the value for ammountSoapUsed and price? In this sense, should I just store petWeight and petHeight and calculate ammountSoapUsed and price everytime that they are needed (remember that in the real-life case calculation is much more complex)?
In truth, I'm not interested in what I could do, but in what OOP best practices recommend to do. Can you help me?
回答1:
The ideal object oriented approach starts with an analysis of the problem domain. PetWash
does not sound like a problem-domain concept, it sounds like the record of a pet washing event that occurred, or an estimate for a pet washing that you will offer to a customer. Which is it? Be clear.
Model the problem domain to better understand the information and operation requirements. Classes must resonate with the real world of the problem domain.
CalculationEngine
certainly doesn't fit this criterion. Classes can certainly do calculations, but they should provide business value recognizable to a non-technical business person. Assuming the purpose is to provide an estimate for a potential customer, what makes sense to me is an instance of aCustomer
class that links to multiple instances of anAnimal
class, where each has aheight
andweight
. Linked to an instance of aCustomer
class might be instances of anEstimate
class that links to instances of theAnimal
to be washed. And so on.Your question is too low-level. You should neither invoke calculations in getters nor provide a
calculate()
operation. Focus on operations that would make sense to a non-technical business person. Again, assuming you are providing an estimate, provide operations on an instance of aCustomer
that add or update his or herAnimals
. Provide an operation that provides anEstimate
when given one or more of the customer'sAnimals
. ThatEstimate
encapsulates the rules and calculations. If aCustomer
agrees to anEstimate
, you can use that to manage your soap inventory or whatever. Keep the implementation hidden behind this problem-domain facade so you can swap out a bad implementation when (not if) you need to.
Most of the OO code I've seen these days dismisses the problem domain altogether and seems to build applications out of chewing gum and duct tape while trying to be agile. A good model of the problem domain is relatively durable. In stark contrast, a focus on the solution domain (a duct-taped design de jour) is not durable and is the cause of much cost overrun, expensive re-work, and canceled projects. Don't make your project one of those!
来源:https://stackoverflow.com/questions/37173654/how-to-model-classes-that-do-calculations-and-store-them