DDD - How to enforce invariants on collections across aggregates - c#

Let's say we sell cars, customizable cars.
A customer chooses a CarModel and then starts configuring the CarModel. In our shop, she can only choose the color of the Steeringwheel.
Some CarModels can have more types of SteeringWheels than others.
Therefore, we have a Catalog which contains CarModels and SteeringWheels.
A customer can create a CarConfiguration. She chooses the model and then from the available steering wheels for that model she chooses the color steering wheel she likes.
class Catalog
{
public IReadonlyCollection<int> CarModels { get; }
public IReadonlyCollection<int> SteeringWheels { get; }
public void RemoveSteeringWheel(int steeringWheelId)
{
...
}
}
class SteeringWheel : AggregateRoot
{
public int Id { get; }
public string Color { get; }
public decimal Price { get; set; }
}
class CarModel : AggregateRoot
{
public int Id { get; }
public decimal Price { get; set; }
public IReadonlyCollection<int> SteeringWheels { get; }
public void AddSteeringWheel(int steeringWheelId)
{
...
}
public CarOrder CreateCarOrder(int steeringWheelId)
{
return new CarOrder(...);
}
}
class CarOrder : AggregateRoot
{
public int Id { get; set; }
public CarConfiguration CarConfiguration { get; set; }
}
class CarConfiguration : ValueObject
{
public int CarModelId { get; set; }
public int SteeringWheelId { get; set; }
}
For this to work there is an invariant that the available steering wheels for a car model must always be present in the catalog. To enforce this invariant, we must guard (at least) two methods:
AddSteeringWheel on CarModel; we can only add a SteeringWheel if it is available in the Catalog
RemoveSteeringWheel on Catalog; we can only remove a SteeringWheel if it is not configured on any CarModel.
How to enforce this invariant? CarModel does not know about the SteeringWheel collection on Catalog and Catalog doesn't know anything about CarModel's steering wheels either.
We could introduce a domain service and inject repositories into that. That service would be able to access the data from both aggregates and be able to enforce the invariants.
Other options are to create navigation properties and configure the ORM (Entity Framework Core in my case) to explicitly load those relations.
And probably many more, which I can't think of right now…
What are the most elegant/pure-ddd/best practice options to achieve this?

How to enforce invariants on collections across aggregates
Fundamentally, what you have here is an analysis conflict. When you distribute information, you give up the ability to enforce a combined invariant.
For example:
For this to work there is an invariant that the available steering wheels for a car model must always be present in the catalog
So what is supposed to happen when one person is updating a CarConfiguration concurrently with another person modifying the catalog? What is supposed to happen with all of the existing configurations after the catalog is changed?
In many cases, the answer is "those activities are both to be permitted, and we will clean up the discrepancy later"; ie we'll attempt to detect the problem later, and raise an exception report if we find anything.
(If that answer isn't satisfactory, then you need to go back into your original decision to split the information into multiple aggregates, and review that design).
Pat Helland has a lot of useful material here:
2009 Building on Quicksand
2010 Memories Guesses and Apologies
2015 Immutability Changes Everything
In effect, your local calculation include stale (and possibly outdated) information from somewhere else, and you encode into your logic your real concerns about that.

Well first of all, it might be that CarModel knows something of SteeringWheels, as I assume that if you add a SteeringWheel with a Price, the Price of CarModel changes?!
So there probably should be a Value Object or Entity as part of the CarModel aggregate that represents that.
Furthermore, I think you need a command handler, that knows of both, and decides if the provided SteeringWheel is valid, before trying to add that to the CarModel, that on its own has to decide if adding the SteeringWheel is allowed, trusting the command handler that the reference of the SteeringWheel is valid.

Invariants between aggregates can't be transitionally consistent, only eventually. So when you add a steering wheel to your carModel, you raise an event saying steeringWheelUsedbyCarModelEvent, you catch that event in Domain event handler and update the steering wheel. Steering Wheel aggregate holds an id(or collection if can be used by multiple car configurations) of the carmodel it is assigned to.

Related

where to put the checking function for the model (asp.net mvc5)

i know the model should not have any logic , but i don't know where is the good place to put the checking or the update function for a particular model
ex.
public class GuestBook
{
public int money { get; set; }
[Required]
public string name { get; set; }
[Required]
public string email { get; set; }
public DateTime content { get; set; }
public bool rich()
{
if (this.money <3000)
return false;
else
return true;
}
public void earn(GuestBook b)
{
this.money += b.money;
}
}
the function rich() and earn() is only use for this module(GuestBook)
if i didn't put it in this module , then where i should put?
Following good OOP design principles, the only way to really protect your classes' invariants (and not have a maintainability nightmare) is by not allowing them to be changed by anyone other than the class. Typically this is done by NOT exposing public setter methods (public auto properties are evil), making your fields readonly (wherever possible), and initializing them from the constructor.
The whole point of having classes is to group data with behavior. A simple data structure containing ints and strings is not a class in the OOP sense, it's just a struct.
In some cases you are stuck with an even more evil ORM that FORCES you to make all properties public. This is not an issue with Entity Framework (and some others too) though, EF can magically reflect in and access private setters if needed, you just gotta make sure there's also a private default constructor.
According to your class rich method is validating and earn method is applying business logic. You can create AdditionalMetadataAttribute for rich method logic that can fire on ModelState.IsValid and for earn method you need to create BO class that apply your all business logic.
here a link for AdditionalMetadataAttribute

From anemic domain to domain driven

I was trying to find a clear and simple example of what an anemic domain really means. There is a lot of theory around, and also many well answered questions. Still, I could not get a clear picture about to what extent "anemic domain" meaning really goes. Therefore, I believe it would be simpler to see a dummy practical example of an anemic domain design and than ask you how could this be evolved to a domain driven one...
So, let's say we have a data entity of type TaskData:
public class TaskData
{
public Guid InternalId { get; set; }
public string Title { get; set; }
public string Details { get; set; }
public TaskState ExplicitState { get; set; }
public IEnumerable<TaskData> InnerTasks { get; set; }
}
And there is the need of an additional property called "ActualState", which is a computed state: if the Task has inner sub-tasks, the value strictly depends of the children, otherwise, the "ActualState" is equal to "ExplicitState"
If I write this logic in a separate service class (I call them "engines") we have:
internal class TaskStateCalculator
{
public TaskState GetState(TaskData taskData)
{
if (taskData.InnerTasks.Any())
{
if (taskData.InnerTasks.All(x => this.GetState(x) == TaskState.Done))
{
return TaskState.Done;
}
if (taskData.InnerTasks.Any(x => this.GetState(x) == TaskState.InProgress))
{
return TaskState.InProgress;
}
return TaskState.Default;
}
return taskData.ExplicitState;
}
}
The first question is:
Does the code above reflect an anemic domain design, even if the TaskStateCalculator service/engine is part of my Domain Layer?
If yes, in order to avoid it, we'll need to move the logic inside the TaskData class (and rename TaskData to Task). Am I right?
The second question is (actually a chain of them):
What if we have a more difficult situation? Let's say there is the need for a property called ComputeSomething inside Task entity, and the logic of this property needs to access the entire Task's repository. In this case, the Task class would have a dependency on TaskRepository. Would this be ok? How would EF construct an instance of such class? What is the alternative?
I was trying to find a clear and simple example of what an anemic domain really means
It's in fact really easy to go from an anemic domain model to a rich one.
Set all property setters to private and then add methods if you want to change state of a model.
Evaluate all Law of Demeter violations and add methods where suitable.
Eventually you will have a correct model.
In your case I would encapsulate that logic inside TaskData as your TaskStateCalculator violate Law of Demeter
public class TaskData
{
public Guid InternalId { get; private set; }
public string Title { get; private set; }
public string Details { get; private set; }
public TaskState ExplicitState { get; private set; }
public IEnumerable<TaskData> InnerTasks { get; private set; }
public TaskState GetState()
{
if (!InnerTasks.Any())
return ExplicitState;
if (InnerTasks.All(x => this.GetState(x) == TaskState.Done))
{
return TaskState.Done;
}
if (InnerTasks.Any(x => this.GetState(x) == TaskState.InProgress))
{
return TaskState.InProgress;
}
return TaskState.Default;
}
}
another thing is that I would probably not expose InnerTasks collection at all to the outside world (just have it as a member field). But it's hard to say as I do not know how the class is used in other scenarios.
Why private setters
Every time you have to change more than one property it's often better to describe the behavior with a method, as it's then impossible to forget to change all required properties. A method also describes better what you are trying to do than changing a set of properties.
Even if you just change a single property, that property can set the class in an invalid state as the change may not be compatible with the rest of the information in the class. Don't forget that encapsulation is one of the core principles in OOP

c# Naming Convention

Im starting a new project and i have some problem trying to implement some naming conventions.
I used to work with Classes starting with Uppercase and Singular, like Car or User, and my variables starting with lower case, so if I needed to declare a class that had some variables of type Car and User i would do it like this:
public Car car;
private User user;
Now im trying to use some properties and as i see they should also be PascalCase , wich mean if i need to declare the same examples i would be:
public Car Car { get; set; }
private User User { get; set; }
And you can all see what would the problem be here, or you don't see it as a problem?
So what should i do? what am i missing here?
The C# naming convention recommends everything that is public as well as classes, interfaces etc., to start with an uppercase letter. The rest should start lower case.
There is no problem with:
private User User { get; set; }
... since the position of each name (word) defines what is what.
The English language works the same way.
e.g.: "I love love." (pronoun, verb, noun)
What you're run into is called the Color Color problem, because the most common way it crops up is "I need a property called Color of a type called Color". C# has been specifically designed to manage Color Color situations elegantly.
For details, read section 7.6.4.1 "Identical simple names and type names" in the C# 4 specification.
The rules for Color Color situations are a bit complicated (believe me, they do not make the compiler implementer's life any easier!) and they can lead to some interesting corner cases. If this subject interests you then you should read my article on it:
http://blogs.msdn.com/b/ericlippert/archive/2009/07/06/color-color.aspx
I think in many cases the context means you'd have a specific name - e.g. Car customersCar, etc.
Saying that, many people don't have an issue with the name/type being the same - see this link:
Should a property have the same name as its type?
For naming conventions in general, following MS isn't a bad start -
http://msdn.microsoft.com/en-gb/library/vstudio/ms229045(v=vs.100).aspx
There is no issue here; As #NDJ suggested you can apply context to add additional prefix to the property if you do not feel comfortable; but this will not generally add additional meaning to the context.
As a general Microsoft style guide encourages the use of Pascal Case for properties.
For a more complete guide on capitalization see the following MSDN article
There is no problem there.
Because in the context where you would use the class it can not be misstaken for the property and vice versa.
Edit: Ok, Im going to assume you have the Userclass inside the carclass like this:
public class Car
{
private class User
{
}
private User User
{
get;
set;
}
}
Which indeed would create problems. Move out your user and the problem is solved.
public class Car
{
private User User
{
get;
set;
}
}
public class User
{
}
Barring the internal class problem that #Evelie pointed out you should not have any issue naming a property the same as the type - in fact this is not an uncommon practice. .NET has public Color Color properties all over the place.
As the following program illustrates the compiler can distinguich between instance calls and static calls:
void Main()
{
Car c = new Car();
c.Test();
}
public class Car
{
public Car()
{
User = new User();
}
public void Test()
{
User.Static(); // calls static method
User.Instance(); // implies this.User
}
public User User { get; set; }
}
// Define other methods and classes here
public class User
{
public static void Static()
{
Console.WriteLine("Static");
}
public void Instance()
{
Console.WriteLine("Instance");
}
}

Best design pattern for refactoring a class that does calculation based on many parameters

I'm refactoring a set of classes as below which does some price calculations.
the calculation is done based on many parameters.
The code is :
public interface IParcel {
int SourceCode { get; set; }
int DestinationCode { get; set; }
int weight{get;set;}
decimal CalculatePrice();
}
public abstract class GeneralParcel : IParcel {
//implementation of inteface properties
//these properties set with in SourceCode & DestinationCode
//and are used in CalculatePrice() inside classes that inherit from GeneralParcel
protected SourceProvinceCode{get; protected set;}
protected DestinationProvinceCode{get;protected set;}
//private variables we need for calculations
private static ReadOnlyDictionary<int, List<int>> _States_neighboureness;
private static ReadOnlyCollection<City> _Citieslist;
private static ReadOnlyCollection<Province> _Provinceslist;
protected ReadOnlyCollection<City> Citieslist {get { return _Citieslist; }}
protected ReadOnlyCollection<Province> ProvincesList {get { return _Provinceslist; }}
protected ReadOnlyDictionary<int, List<int>> StatesNeighboureness {get {return _States_neighboureness; }}
//constructor code that initializes the static variables
//implementation is in concrete classes
public abstract decimal CalculatePrice();
}
public ExpressParcel : GeneralParcel {
public decimal CalculatePrice() {
//use of those three static variables in calculations
// plus other properties & parameters
// for calculating prices
}
}
public SpecialParcel : GeneralParcel {
public decimal CalculatePrice() {
//use of those three static variables in calculations
// plus other properties & parameters
// for calculating prices
}
}
Right now, the code uses "Strategy pattern" efficiently.
my question is that those three static properties, really are not part of parcel object, they are need only for price calculations, so which design pattern or wrapping(refactoring), is suggested?
Is having another interface as below necessary (& then wrap those static properties inside it?, even make static that class, because it is basically only some calculations), then how to connect it to IParcel?
Doing so, how to implement CalculatePrice() in SpecialParcel & ExpressParcel classes?
public interface IPriceCalculator {
decimal CalculatePrice();
}
EDIT: the above was only a big picture of all system, there is also other consideration that in comments, we discus about them, and i write them here again for clearing things .
there is BulkDiscount for all of ParcelTypes. bulk post happens when customer send more than 10 parcels(or any threshold), also there is special discount when one customer send more than 10 parcel to a unique destination(there is only one receiver). now this type of discounts are managed in each parcel type's CalculatePrice(). even there are discount for blinds for under 7Kg parcels.
also right now there are 3 parceltype, i show only 2 of them here. but we need to add other type in future(TNT & DHL support).
each type has many services that customer can select and pay for it.
for example, sms service or email service & so on.
Personally, while others might say that a Parcel shouldn't know how to calculate its own shipping cost, I disagree. Your design already identifies that there are three different kinds of parcel with three different calculations, so to my (naive?) eyes it's entirely appropriate that the object should have a method e.g. CalculatePrice().
If you really want to go that way, then you'd need two implementations of IParcelPriceCalculator (or whatever you call it) and an abstract factory method on the GeneralParcel to create the concrete ExpressParcelPriceCalculator or SpecialParcelPriceCalculator classes. Which, personally, I'd consider overkill, not least as that code will then be tightly coupled to each GeneralParcel implementation anyway.
I would however consider making the static collections of City and Province public static properties of City and Province respectively. That's just tidier, and it's where I'd expect to find them if I were maintaining the code. StatesNeighbourliness should probably go into Province, or it might even justify its own class.
The way in which you calculate a price for a given parcel is a responsibility that shouldn't belong to a data object.
Given what you've told me, here is how I would implement, to try and account for future considerations:
public interface IParcel {
int SourceCode { get; set; }
int DesinationCode { get; set; }
int Weight { get; set; }
}
public class PricingCondition {
//some conditions that you care about for calculations, maybe the amount of bulk or the date of the sale
//might possibly be just an enum depending on complexity
}
public static class PricingConditions {
public static readonly PricingCondition FourthOfJulyPricingCondition = new PricingCondition();
public static readonly PricingCondition BulkOrderPricingCondition = new PricingCondition();
//these could alternatively come from a database depending on your requirements
}
public interface IParcelBasePriceLookupService {
decimal GetBasePrice(IParcel parcel);
//probably some sort of caching
}
public class ParcelPriceCalculator {
IParcelBasePriceLookupService _basePriceLookupService;
decimal CalculatePrice(IParcel parcel, IEnumerable<PricingCondition> pricingConditions = new List<PricingCondition>()) {
//do some stuff
}
decimal CalculatePrice(IEnumerable<IParcel> parcels, IEnumerable<PricingCondition> pricingConditions = new List<PricingCondition>()) {
//do some stuff, probably a loop calling the first method
}
}
The IPriceCalculator would be best practice for Single Responsibility Principle.
But change the method's signature to decimal CalculatePrice(IParcel parcel);
The method is calling IParcel's CalculatePrice() method to get base price for each parcel.
The advice I'd offer would depend to a degree on how you go about generating and using the Parcel polymorphs. What I mean is, we can't see what criteria are used to determine whether something is "Express" or "Special" and whether those criteria have to do with the properties of the parcel itself or some external factor.
Having said that, I think your intuition is a good one about separating the price calculation from the Parcel object itself. As kmkemp pointed out, a parcel shouldn't be figuring out how to calculate the price of a parcel depending on what type of parcel it is. A parcel is a data transfer/POCO type object, at least as indicated in your giving it a weight, source, etc.
However, I'm not clear on why you're using these interfaces. Don't get me wrong -- interfacing is nice for decoupling and testability, but why is there a parcel interface in addition to an abstract base class with an abstract method. Personally, going on just the information that I have, I'd do this:
public class Parcel
{
int SourceCode { get; set; }
int DestinationCode { get; set; }
int weight { get; set; }
}
public abstract class GeneralCalculator
{
//Statics go here, or you can inject them as instance variables
//and they make sense here, since this is presumably data for price calculation
protected static ReadOnlyDictionary<int, List<int>> _States_neighboureness;
protected static ReadOnlyCollection<City> _Citieslist;
protected static ReadOnlyCollection<Province> _Provinceslist;
//.... etc
public abstract Decimal CalculatePrice(Parcel parcel);
}
public class ExpressCalculator : GeneralCalculator
{
public override decimal CalculatePrice(Parcel parcel)
{
return 0.0M;
}
}
public class SpecialCalculator : GeneralCalculator
{
public override decimal CalculatePrice(Parcel parcel)
{
return 0.0M;
}
}
But, again, I don't know how the parcels are actually being processed. You may need some kind of modification to this concept depending on how you generate and then process the parcels. For instance, if the kind of parcel it is depends on the property values of the parcel, you might want to define a factory method or class that takes a parcel and returns an appropriate instance of the calculator.
But, however you modify it, I'd definitely cast my vote for your thought of decoupling the definition of the parcel from the scheme for calculating its price. Data storage and data processing are separate concerns. I'd also not vote in favor of a static class somewhere containing global settings, but that's my own personal taste -- that kind of thing too easily acquires a setter and becomes a global variable down the road.
Like you say, those static properties aren't really part of the GeneralParcel class. Move them to a static "ListsOfThings" class.
Then you can use code that refers to ListsOfThings.ProvincesList, etc.

game design improvement

I was having a discussion with my developer mate on following game design.
I have a collection of Move in the Game class. my developer mate is asking me to remove the collection and only have the current move information there.
what is your suggestions?
public class Game
{
public String Id { get; set; }
public String CreatorId { get; set; }
public List<Player> Players { get; set; }
public List<Move> Moves { get; set; }
}
public class Player
{
public String Id { get; set; }
public String Name { get; set; }
}
public class Move
{
public String Id { get; set; }
public String PlayerId { get; set; }
public String PlayerName { get; set; }
public String NextMoveId { get; set; }
public String NextPlayerId { get; set; }
public String Position { get; set; }
}
Edit:
my developer mate suggests me to only have a single Move object in the Game class.
There's no really correct approach that any of us can provide for your design. It isn't a cut-and-dry situation; there's no "right" or "wrong" answer. And it's especially difficult for us to make suggestions given that we don't know all of the details behind your game's design. For example, as I asked in a comment and several of the other answers have hinted towards, if you have an "Undo" or "Replay" feature, you will need to store a history of all the moves. If not, and you have no desire to implement such a feature, there is no need to store information about all of the moves.
This is the kind of design decision that you need to learn how to make as a programmer. Consider all of the possible benefits of one approach and the benefits of the other approach, then decide which one best suits your application. Make a "T" chart if you find it helpful. Something like:
Keeping List of All Moves | Storing Only Last Move
---------------------------------------|------------------------------------
- Allows you to implement Undo | - Simplifies your game's design
or Replay feature |
- Consumes more memory | - Saves memory by only storing the
| minimum amount of data
|
|
...etc.
In the end, you (and your colleague) are the ones in the best position to make this decision. Making sure that you've armed yourself with a careful comparison of the advantages and disadvantages is the best way to ensure that you've made the right one.
A game often consists of a set of moves performed by one or more players. Between each move, the game is in a certain state.
If you have the current state, and no need to playback or undo any moves, you would never access the previous moves. Future moves are not known yet, so with just the information you provided, I'd say Game should not have any Move, just a State and a ProcessMove(Move move) method to change the Game's State. The Move is generated by one of the Players.
public class Game
{
public String Id { get; set; }
public String CreatorId { get; set; }
public List<Player> Players { get; set; }
public String PlayerId { get; set; }
}
public class Player
{
public String Id { get; set; }
public String Name { get; set; }
public String Position { get; set; }
public Move(string NewPosition);
public event EventHandler onMoved;
}
This would be my prefered option, although without knowing what type of game it it it's hard to know. Either way, a player should encapsulate its own position, and the Game should know the current player.
As for moves, its game dependant, but move will change the players position, and this may or may not effect other players, so I'd probably implement move on the player and have a onMoved event on the players, which the game is subscribed to..
I think having the collection could be useful in implementing an 'undo move' feature in your game. The list of Move objects could be an implementation of commands, and you could save/restore the state of your game using information in the commands.
I see nothing wrong with having a collection of moves in there. You can expose the current move with another property, then both, you and your mate are statisfied.
That's all I can say with the information you provided. I do not know your game logic. The Collection of Moves can be an advantage when you need to have a history of moves (e.g. a replay function) or you want to plan several moves ahead. I see nothing wrong there besides the fact that you probably do not necessarily need it.
By the way: List<T> is meant for implementations, not for ObjectModels. I'd wrap the List in a class called MovesCollection. And Move should implement an interface (an abstract contract) in case you need many different moves implementations (e.g. AttackMove, Fortify-Move, Retreat-Move ...)
From my point of view. If you don't want that UNDO feature then placing list of MOVES is useless because you already mentioned that no we do not have Undo feature, nor we think about having it . then why having this list here ?
think this as, you have declare lots of variables in your code and not using them. It is good practice that keeping code clean and simple =)

Categories