Your article illustrates a problem that is hard to model nicely in classic OO, requiring a bunch of nuanced code to overcome these shortcomings. I'd argue that inter-mixing data and "process" is a consequence of these shortcomings.
Since you're using C#, I'll illustrate how this problem would be more appropriately modeled in F#. We'll start by modeling a type that encodes the activity date:
type ActivityDate =
| ArbitraryDate of DateTime
| Today
Here we've declared a sum type (aka discriminated union) that encodes all the information necessary to determine if the activity date is EITHER an arbitrary date, OR a value that indicates that the user is filtering on today's activity. Now we'll define the actual domain model:
type ActivityFilter = { activityDate : ActivityDate; /* Hiding the other properties */ }
As you can see, we require one fewer properties than the C# example in order to convey the same amount of information.
Take a moment to consider how much code was required in the C# examples to determine the actual date we need to filter on. Here's how that would look in F#:
let getFilterDate activityDate =
match activityDate with
| ArbitraryDate date -> date
| Today -> DateTime.Now.Date
In a grand total of 8 lines of code, we've modeled the same problem in a much cleaner, more straightforward way. Debating where the methods that operate on our domain models should live is largely an exercise in bike shedding. Instead, we should be asking if the languages and paradigms we use are anemic.
For further actions, you may consider blocking this person and/or reporting abuse
We're a place where coders share, stay up-to-date and grow their careers.
Your article illustrates a problem that is hard to model nicely in classic OO, requiring a bunch of nuanced code to overcome these shortcomings. I'd argue that inter-mixing data and "process" is a consequence of these shortcomings.
Since you're using C#, I'll illustrate how this problem would be more appropriately modeled in F#. We'll start by modeling a type that encodes the activity date:
Here we've declared a sum type (aka discriminated union) that encodes all the information necessary to determine if the activity date is EITHER an arbitrary date, OR a value that indicates that the user is filtering on today's activity. Now we'll define the actual domain model:
As you can see, we require one fewer properties than the C# example in order to convey the same amount of information.
Take a moment to consider how much code was required in the C# examples to determine the actual date we need to filter on. Here's how that would look in F#:
In a grand total of 8 lines of code, we've modeled the same problem in a much cleaner, more straightforward way. Debating where the methods that operate on our domain models should live is largely an exercise in bike shedding. Instead, we should be asking if the languages and paradigms we use are anemic.