DDD how to handle value objects without repository - domain-driven-design

I need some help with a value object. Consider the following example.
I have entity Card which has pan currency(USD, EUR, GBP) and card type (Visa, Visa Electron, Mastercard). I think currencies and card types are value objects and they are stored in the source code. According to DDD value objects don't have repositories.
The question is how to fill the dropdowns of currencies and a card
types in the interface when creating new Card entity.
Where to put that classes in Application, Domain or Infrastructure layer
and how to retrieve data from them.
A simple example would be priceless"
UPDATE1
That was my first approach but..
I use currencies in other entities like MoneyTransfer there i use EUR USD GBP and a few more so i have to create one more enum
public enum MoneyTransferCurrency{
USD, EUR, GBP and a few other
}
This way i duplicate some currencies and if we stop processing payments in USD i have to find all enums and delete the USD currency.

Don't try to make simple things complicated.
If you know a-priori all the possible values of these VO, you can have them as enum.
public enum Currency{
USD, EUR, GBP
}
And then from the code:
Currency.values()
Ask yourself, how often these values changes? (how often a new kind of currency is used by the system?)
Is the cost of developing and maintaining a system (like db tables) to add remove these values dynamically without restart the application less than using an enum and recompile the project when there is a change?
A lot of times I was critizied for this solution with arguments like "I need a description of the value", like in a view writing "Euro" when you have the EUR value, if you have a table you can have a description column.
This can be easily solved using a properties file like:
labels.currency.EUR=Euro
labels.currency.USD=Dollars
Check also this:
- Loading a Value object in List or DropdownList, DDD
- Simple aggregate root and repository question

You misunderstood VOs, read some more info about them, i think easy way to understand them is to look up Person / Addres example.
What about your case, just create 3 tables, don't try to make simple things complicated:
Card (CardID, CurrencyID, CardTypeID)
Currency (CurrencyID, CurrencyName)
CardType (CardTypeID, CardTypeName)
For DropDowns you will just query Currency & CardType tables. And in future if you will add new Currency or CardType it will be easy to do.

Currency and CardType aren't necessarily sensible value objects. Value objects model a conceptual whole containing related attributes. Value objects can be compared by comparing all of their attributes.
Think for example of an MonetaryValue value object that consists of a numerical value together with a currency:
public class MonetaryValue {
private BigDecimal value;
private Currency currency;
public Amount(BigDecimal value, Currency currency) {
// validations:
assertNotNull(value);
assertNotNull(currency);
this.value = value;
this.currency = currency;
}
[...]
}
Value (e.g. 100) and currency (e.g. eur) together describe the worth of a thing. The thing isn't worth just "100" and not just "eur", but "100 eur".
Comparing of value objects is also important. When talking about monetary values, both attributes, value and currency, need to be compared. Comparing the value without the currency wouldn't help much, since 100 usd isn't the same as 100 eur. This is a further indication that MonetaryValue could be a sensible value object.

Related

Always valid domain model entails prefixing a bunch of Value Objects. Doesn't that break the ubiquitous language?

The principle of always valid domain model dictates that value object and entities should be self validating to never be in an invalid state.
This requires creating some kind of wrapper, sometimes, for primitive values. However it seem to me that this might break the ubiquitous language.
For instance say I have 2 entities: Hotel and House. Each of those entities has images associated with it which respect the following rules:
Hotels must have at least 5 images and no more than 20
Houses must have at least 1 image and no more than 10
This to me entails the following classes
class House {
HouseImages images;
// ...
}
class Hotel {
HotelImages images;
}
class HouseImages {
final List<Image> images;
HouseImages(this.images) : assert(images.length >= 1),
assert(images.length <= 10);
}
class HotelImages {
final List<Image> images;
HotelImages(this.images) : assert(images.length >= 5),
assert(images.length <= 20);
}
Doesn't that break the ubiquitous languages a bit ? It just feels a bit off to have all those classes that are essentially prefixed (HotelName vs HouseName, HotelImages vs HouseImages, and so on). In other words, my value object folder that once consisted of x, y, z, where x, y and z where also documented in a lexicon document, now has house_x, hotel_x, house_y, hotel_y, house_z, hotel_z and it doesn't look quite as english as it was when it was x, y, z.
Is this common or is there something I misunderstood here maybe ? I do like the assurance it gives though, and it actually caught some bugs too.
There is some reasoning you can apply that usually helps me when deciding to introduce a value object or not. There are two very good blog articles concerning this topic I would like to recommend:
https://enterprisecraftsmanship.com/posts/value-objects-when-to-create-one/
https://enterprisecraftsmanship.com/posts/collections-primitive-obsession/
I would like to address your concrete example based on the heuristics taken from the mentioned article:
Are there more than one primitive values that encapsulate a concept, i.e. things that always belong together?
For instance, a Coordinate value object would contain Latitude and Longitude, it would not make sense to have different places of your application knowing that these need to be instantiated and validated together as a whole. A Money value object with an amount and a currency identifier would be another example. On the other hand I would usually not have a separate value object for the amount field as the Money object would already take care of making sure it is a reasonable value (e.g. positive value).
Is there complexity and logic (like validation) that is worth being hidden behind a value object?
For instance, your HotelImages value object that defines a specific collection type caught my attention. If HotelImages would not be used in different spots and the logic is rather simple as in your sample I would not mind adding such a collection type but rather do the validation inside the Hotel entity. Otherwise you would blow up your application with custom value objects for basically everything.
On the other hand, if there was some concept like an image collection which has its meaning in the business domain and a set of business rules and if that type is used in different places, for instance, having a ImageCollection value object that is used by both Hotel and House it could make sense to have such a value object.
I would apply the same thinking concerning your question for HouseName and HotelName. If these have no special meaning and complexity outside of the Hotel and House entity but are just seen as some simple properties of those entities in my opinion having value objects for these would be an overkill. Having something like BuildingName with a set of rules what this name has to follow or if it even is consisting of several primitive values then it would make sense again to use a value object.
This relates to the third point:
Is there actual behaviour duplication that could be avoided with a value object?
Coming from the last point thinking of actual duplication (not code duplication but behaviour duplication) that can be avoided with extracting things into a custom value object can also make sense. But in this case you always have to be careful not to fall into the trap of incidental duplication, see also [here].1
Does your overall project complexity justify the additional work?
This needs to be answered from your side of course but I think it's good to always consider if the benefits outweigh the costs. If you have a simple CRUD like application that is not expected to change a lot and will not be long lived all the mentioned heuristics also have to be used with the project complexity in mind.

Should Value Objects Contain Technical Validation For Input Parameters?

As DDD practitioner advise, business rule's validations must be implemented inside domain objects (Entities, Value Objects and Domain Services) and follow their own context also somewhere i've read that we should put technical validations (such as check length, correct input formats, correct data type, ...) out of domain model and somewhere like application layer to keep domain object clear.
Now
my question is this:
If we had a Value Object for credit card number, should we still keep technical validation out of our Value Object?
In other words the "Self Validated" term is not involved with technical validations when we deal with Value Objects?
When an incorrect debit card's number or even an email address has a potential to break business rules, what then?
For more clarity please notice this Value Object which represent an Debit Card Number:
public class DebitCardNumber : ValueObject
{
public string Number { get;private set; }
public CreditCardNumber(string number)
{
Validation(number);
this.Number = number;
}
private void Validation(string number)
{
if (String.IsNullOrWhiteSpace(number))
{
throw new CardNumberCanNotBeEmptyException();
}
if (number.Length != 16)
{
throw new CardNumberLengthMustBeSixteenDigitException();
}
int sum = 0;
for (int i = 1; i <= 16; i++)
{
if (!char.IsDigit(number[i - 1]))
{
throw new ValueContainsSomeNonDigitCharacterException();
}
int m = (i % 2 == 0 ? 1 : 2);
int a = (int.Parse(number[i - 1].ToString()) * m);
while (a > 9)
{
a -= 9;
}
sum += a;
}
if ((sum % 10) > 0)
{
throw new ValueIsNotCorrectAsACardNumberException()
{ Message = "Perhaps some digits has been entered in wrong order or they are incorrect." };
}
}
}
According to this code there is a Validation method that carry out an algorithm to find out either is it Card Number's format correct or not?
do you think is it right place for this type of validations?
as DDD practitioner advise, business rule's validations must be implemented inside domain objects (Entities,Value Objects and Domain Services)
Yes.
also somewhere I'd read that we should put technical validations (such as check length,correct input formats,correct data type,...) out of domain model and somewhere like application layer to keep domain object clear.
A little bit confused here; the main point is that the entities shouldn't need to be worrying about a bunch of input validation, that isn't their job (separation of responsibilities). So instead of passing raw data (strings, primitives) to the entities in our model, we first use the primitives to construct value types that the entity will recognize, and then pass those entities in.
The rules for which primitives can be used to create a well formed value type are properly implemented within the value type itself (constructor) or in a dedicated factory provided for that purpose). The application component has the responsibility to create the value type from the message/DTO it has received before passing that value to the model.
So in your example, the DebitCard validation logic looks like it is in the right place.
A caution - your model evolves over time; when the model changes, you'll still need to be able to read the data written by the earlier version of your model. Adding validation rules that treat your current data as invalid can get messy - so you want to make sure that the validation rules have business motivation. Are you saving money/cutting costs by ensuring that a debit card number has a valid checksum?
(Example: suppose a customer submits a purchase order with an invalid card number. Does the business want to reject that order, or accept that order but defer acting on it until a valid form of payment is provided? If it's the latter choice, you want to make sure that your validation logic doesn't get in the way of accepting the order).
I don't consider your example to be a technical validation rule - I think it is a domain rule of a debit card - if, in the domain of banking, a debit card number must follow a certain pattern, then this is a domain rule that needs to be enforced.
so I think your solution is correct.
if we had a Value Object for credit card number and so on,still we
should keep technical validation out of our Value Object? in other
words the "Self Validated" term is not involved with technical
validations when we deal with Value Objects?
Correct. The domain (entities, domain services, vos, etc) should be modelled such that they enforce business rules, not technical concerns. Your domain may need to distinguish between DebitCards and CreditCards, but I doubt the business cares about the format of the card numbers themselves. The format & correctness of the card number is important for infrastructure purposes, so the formatting rules can be enforce in that layer.
In my opinion your approach is right most cases.
If the number is not valid it's not really a debit card number.
Let's say you have a debit card number that does not validate. Either you have a boolean valid set to false, or your code is lying to you: it's not a debit card number.
If you still want to store the number, maybe for security or UX purposes, you should do that in a different object, maybe inside an Entered Form value object.

DDD repositories, and REST

Should DDD Repository always return aggregate and all it's value objects and entities?
For an example, I have Invoice object which has it's type and items.
Invoice
--Id
--Issuer
--InvoiceType
--Items
Data are persisted in 4 SQL Tables.
Invoices (FK to invoice type, FK to issuers),
InvoiceTypes
Items(fk to Invoice)
Issuers
If a repository should always return aggregates in it's full state, is it a bit of overkill to include InvoiceType and Items if i need to fetch 50 invoices, and display only ID and IssuerName.
Example for
InvoiceRepository
{
//should this also fetch InvoiceTypes and items from SQL, or i need separate invoice model for this
public List<Invoice> FetchForListing(int page, int take);
}
Should DDD Repository always return aggregate and all it's value objects and entities?
No. In use cases where you are going to be performing a write, you should load everything, because you need the full internal state to ensure that your change satisfies the invariant.
But if you are only going to perform a read, the full state isn't necessary at all -- it's reasonable to limit to the data you pull out.
(For example: when using the cqrs pattern, reads tend to not touch the aggregate at all, but instead copy data from "projections" of aggregate state into a more suitable representation.)
InvoiceRepository
{
// should this also fetch InvoiceTypes and items from SQL,
// or i need separate invoice model for this
public List<Invoice> FetchForListing(int page, int take);
}
So in this case, you wouldn't return a List<Invoice>, since that isn't what you want, and you might not use the same interface to represent the repository
InvoiceSummaryRepository
{
public List<InvoiceSummary> readSummary(int page, int take);
}
Check in your own ubiquitous language to figure out what InvoiceSummary is actually called, to determine whether List<InvoiceSummary> is actually a thing with a name of its own (likely is you are using it to build the representation of a resource in your REST api), and so on.

How to structure classes, apply business rules when couple value objects depend on each other?

Basically I have two value objects each representing price. Rule goes one price cannot be greater than other. There might be case when only one of them are specified.
How to enforce this rule and where? Keep two separate objects and when one gets constructed pass other to it? Sounds a bit weird because inverse rule must be applied to other. I do not want to keep both values in one object because I do not need them to be coupled when I use those values.
Value objects rarely exists on their own and are usually aggregated within an entity which is responsible for enforcing it's invariants.
"I do not want to keep both values in one object because I do not need
them to be coupled when I use those values"
If there is a business rule that spans these values then they probably should be part of the same aggregate. The values themselves will not be directly coupled one to the other, but the aggregate would hold both.
Rule goes one price cannot be greater than other. There might be case when only one of them are specified.
If those two prices go really together and change together like price-from / price-to it is also possible to have PriceRange value object that can check those rules.
public class PriceRange
{
public PriceRange(Price from, Price to)
{
// Check all rules here
From = from;
To = to;
}
public Price From { get; }
public Price To { get; }
}
Checking rules in the Aggregate Root can be better
if AR state enforces price rules
if those two prices change separately

Naming suggestion for a class containing a timestamp and a float value?

I need to name this structure:
struct NameNeeded
{
DateTime timestamp;
float value;
}
I will have arrays of this struct (a time-series).
I'd like a short and suggestive name. The data is financial (and Tick is not a good name).
The best one I can think of is DataPoint, but I feel that a better one exists :)
How would you name it?
Since you have a data value and an associated timestamp, the first thing that popped into my head was DataSample. I pictured a series of these, as if you were taking a digital sampling of an analog signal (the two values were like x- and y-coordinates on a graph).
My old scientist neurons are telling me that this is a Measurement. A measurement is an instrument reading associated with some context - time, position, experimental conditions, and so on.
The other metaphor that springs to mind is a Snapshot, or a moment in an evolving scene illuminated by a strobe light - an Instant, perhaps.
Given that we can't associate a specific concept with the float value structure member, only vague names such as "Value", "Number", "Float" or "Data" come to mind.
The DateTime timestamp member suggests to me that the name should have a time related suffix such as "When", "AtTime", "Instant" or "Moment"
So, combining these name fragments and you could have
ValueWhen
ValueAtInstant
NumberWhen
DataAtTime
etc.
When stuck on a naming problem, consulting a dictionary or thesaurus can sometimes help. It's pleasing to see well chosen type names, and gratifying to come up with them - good luck with your quest.
I would personally include "Float" in the name, to leave open the possibility of providing other time-stamped types. For example, you could provide a timestamped int or enum for analyst recommendation.
If you want the time-stamping to be implicit, consider "FloatValue." Making it implicit might be desirable if other attributes might someday join the timestamp (e.g., source of data, confidence level, or uncertainty).
If you want to be explicit, one possibility would be "RecordedFloat."

Resources