Should I restrict the construction of a domain object to an external service? - oop

Let's say I have the value object LicensePlate. It is part of a Car, which is an entity in my domain. However, the logic for building the plate doesn't belong to my domain, I simply obtain that from a domain service RegistrationAgency.obtainPlate(Car car), implemented in the infrastrucure layer as DMV.obtainPlate(Car car), which calls an external API.
Now, I feel like I should restrict the construction of the LicensePlate to the service, so I can be sure that any instance of LicensePlate is valid (i.e was made by a registration agency). Is that a justified concern?
Anyway, the solutions I can think of is making LicensePlate's constructor private and adding to the class a static factory method, let's say LicensePlate.build(car, licenseNumberFactory), with LicenseNumberFactory being the one responsible for calling the external API. How messy is that? What about the DDD? Am I respecting it? Should I just make LicensePlate public instead and avoid all of this?

Should I just make LicensePlate public instead and avoid all of this?
Yes
The value object LicensePlate should be able to enforce its own invariants, e.g. cannot be null / must contains numbers and letters / whatever else.
public class LicensePlate
{
public string RegNumber { get; init; }
public LicensePlate(string regNumber)
{
if (string.IsNullOrWhitespace(regNumber))
throw ArgumentOutOfRangeException(nameof(regNumber));
// perform other invariant checks;
RegNumber = regNumber;
}
}
Now you have a license plate that enforces its own invariants (within its sphere of knowledge, at least). Your car entity will look something like:
public class Car
{
public string Model { get; private set; }
public string Color { get; private set; }
public LicensePlate LicensePlate { get; private set; }
public Car(string model, string color, LicensePlate licensePlate)
{
Model = model;
Color = color;
LicensePlate = licensePlate;
}
}
so I can be sure that any instance of LicensePlate is valid (i.e was
made by a registration agency)
If registration agency means that the plate must have been created by a trusted service then that is up to the infrastructure to enforce.
You might think that any caller could have created a license plate to put on your car entity. This is true. But, if that caller does not have access to your infrastructure (database) then creating that entity does not cause any risks as the caller (infrastructure) that may have provided a spoof license plate cannot persist it in your infrastructure (database).
If the same infrastructure codebase that has access to your database is used to make the call to the license plate generation API, then all is good.
If a completely different infrastructure wishes to make use of the Car entity but with license plates created by a different service (or a mock service when testing), then that is up to the infrastructure / application layer. Indeed, this is a feature of DDD layering. The Car entity cannot be expected to enforce invariants that are outside of its control (e.g. whether the value object was acquired from a specific external service).
Anyway, the solutions I can think of is making LicensePlate's
constructor private and adding to the class a static factory method,
let's say LicensePlate.build(car, licenseNumberFactory)
You could do that, but you still don't know if the licenseNumberFactory itself is spoofed by the infrastructure layer.
And you don't want your entity model to have to know about infrastructure implementation.

Related

CustomConverter to compare to a property on the same class in web api

I've been writing a few customconverters, extending Newtonsofts JsonConverter and stumbled on a little problem. Say I have two properties on a class, but they cannot be the same value. Is it possible to find the value of another property in a converter... for example, say I have a model like so.
I'd want to be able to check the value of Surname in CustomCompareConverter to ensure its not the same value as Firstname
public class Person
{
[JsonConverter(typeof(CustomCompareConverter), "Surname")]
public string Firstname { get; set; }
public string Surname { get; set; }
}
```
You are trying to do multiple things with the json deserialization process that really should be separated
converting some external json into your domain object
validating the domain object.
The fact that the Surname cannot match the FirstName property is a business rule of your domain. So keep that within your domain. You can:
write a separate validator class that will check the state of your
person object and return a list of validation failures
implement IValidatableObject on your Person class and implement the
interface
write a custom validator like in this SO question
Use the JSON deserialization process as an anti-corruption layer to keep the details of external systems out of your your domain structure. Once you've take the extenal object and converted it to your domain object then use conventional means to validate that your domain object.

Enforcing invariants with scope on child entity of aggregate root - DDD

I´m trying to understand how to represent certain DDD (Domain Driven Design) rules.
Following the Blue Book convention we have:
The root Entity has global identity and is responsible for checking invariants.
The root entity controls access and cannot be blindsided by changes to its internals.
Transient references to internal members can be passed out for use withing a single operation only.
I´m having a hard time to find the best way to enforce the invariants when clients can have access to internal entities.
This problem of course only happens if the child entity is mutable.
Supose this toy example where you have a Car with four Tire(s). I want to track the usage of each Tire idependently.
Clearly Car is a Aggregate Root and Tire is an Child Entity.
Business Rule: Milage cannot be added to to a single Tire. Milage can only be added to all 4 tires, when attached to a Car
A naive implementation would be:
public class Tire
{
public double Milage { get; private set; }
public DateTime PurchaseDate { get; set; }
public string ID { get; set; }
public void AddMilage(double milage) => Milage += milage;
}
public class Car
{
public Tire FrontLefTire { get; private set; }
public Tire FrontRightTire { get; private set; }
public Tire RearLeftTire { get; private set; }
public Tire RearRightTire { get; private set; }
public void AddMilage (double milage)
{
FrontLefTire.AddMilage(milage);
FrontRightTire.AddMilage(milage);
RearLeftTire.AddMilage(milage);
RearRightTire.AddMilage(milage);
}
public void RotateTires()
{
var oldFrontLefTire = FrontLefTire;
var oldFrontRightTire = FrontRightTire;
var oldRearLeftTire = RearLeftTire;
var oldRearRightTire = RearRightTire;
RearRightTire = oldFrontLefTire;
FrontRightTire = oldRearRightTire;
RearLeftTire = oldFrontRightTire;
FrontLefTire = oldRearLeftTire;
}
//...
}
But the Tire.AddMilage method is public, meaning any service could do something like this:
Car car = new Car(); //...
// Adds Milage to all tires, respecting invariants - OK
car.AddMilage(200);
//corrupt access to front tire, change milage of single tire on car
//violating business rules - ERROR
car.FrontLefTire.AddMilage(200);
Possible solutions that crossed my mind:
Create events on Tire to validate the change, and implement it on Car
Make Car a factory of Tire, passing a TireState on its contructor, and holding a reference to it.
But I feel there should be an easier way to do this.
What do you think ?
Transient references to internal members can be passed out for use withing a single operation only.
In the years since the blue book was written, this practice has changed; passing out references to internal members that support mutating operations is Not Done.
A way to think of this is to take the Aggregate API (which currently supports both queries and commands), and split that API into two (or more) interfaces; one which supports the command operations, and another that supports the queries.
The command operations still follow the usual pattern, providing a path by which the application can ask the aggregate to change itself.
The query operations return interfaces that include no mutating operations, neither directly, nor by proxy.
root.getA() // returns an A API with no mutation operations
root.getA().getB() // returns a B API with no mutation operations
Queries are queries all the way down.
In most cases, you can avoid querying entities altogether; but instead return values that represent the current state of the entity.
Another reason to avoid sharing child entities is that, for the most part, the choice to model that part of the aggregate as a separate entity is a decision that you might want to change in the domain model. By exposing the entity in the API, you are creating coupling between that implementation choice and consumers of the API.
(One way of thinking of this: the Car aggregate isn't a "car", it's a "document" that describes a "car". The API is supposed to insulate the application from the specific details of the document.)
There should be no getters for the Tires.
Getters get you in trouble. Removing the getters is not just a matter of DDD Aggregte Roots, but a matter of OO, Law of Demeter, etc.
Think about why you would need the Tires from a Car and move that functionality into the Car itself.

Should there be one or multiple XXXRepository instances in my system, with DDD?

There's something that has been bothering from my DDD readings. From what I've seen, it seems as if there is only repository instance for each given aggregate root type in my system.
Consider, for instance, the following imaginary situation as an abstraction of a deeper domain model:
When coding in a "standard-style" I'd consider that each Owner in my system would have its own collection of cars, so there would be an equal number of Car collections (should I call it Repositories?) as there are Owners. But, as stated previously, it seems as if in DDD I should only have one CarRepository in the whole system (I've seen examples in which they are accessed as static classes), and to do simple operations such as adding cars to the Owner, I should make use of a domain-service, which seems to be, for the simple case, not very API friendly.
Am I right about only having one CarRepository instantiated in my system (Singleton), or am I missing something? I'd like to strive for something like
public void an_owner_has_cars() throws Exception {
Owner owner = new Owner(new OwnerId(1));
CarId carId = new CarId(1);
Car car = new Car(carId);
owner.addCar(car);
Assert.assertEquals(car, owner.getCarOf(carId));
}
but that doesn't seem to be possible without injecting a repository into Owner, something that seems to be kind of forbidden.
A repository does not represent a collection that belongs to another entity. The idea is that it represents the entire collection of entities.
So in your example Car is an entity and probably an aggregate. So your model is OK on a conceptual level but you need to split the tight coupling between Car and Owner since Owner is most definitely an AR and, in your current model, deleting it would mean all cars belonging to it should be deleted also.
What you are probably after is something like this:
public class Owner {
private IEnumerable<OwnedCar> cars;
}
public class OwnedCar {
public Guid CarId { get; set; }
}
Or, as an alternative to a VO:
public class Owner {
private IEnumerable<Guid> carsOwned;
}
So one AR should not reference another AR instance.
Another point is that you probably do not want to inject repositories into entities since that may indicate a bit of a design flaw (somewhat of a code smell).
To get the owned cars into the Owner would be the job of the OwnerRepository since it is part of the same aggregate. There would be no OwnedCarRepository since it is a value object.
100% for sure, you don't have to make a singleton CarRepository unless you're working in a legacy system which doesn't use any dependency inejction mechanism.
If you find you need to inject CarRepository to Owner to retrieve cars belong to a specific owner, maybe it's a hint that you should re-model there relationship like:
public class Owner {
}
public class Car {
private Owner owner;
}
And use CareRepository to achieve your goal:
public interface CarRepository {
List<Car> findBy(String onwer);
}
And just a speculation, the static part maybe refer to DomainEvents, like:
public class Owner {
public long quantityOfCarsOwned() {
return DomainEvents.raise(new SumCarsEvent(this));//static
}
}
public class SumCarsEventHandler {
private CarRepository carRepository;//inject this, SumCarsEventHandler should be a statless bean managed by container like spring
public long handle(SumCarsEvent event) {
return carRepository.countBy(event.getOwner());
}
}
In very simple case, it's just too complicated I think.

when one-to-one relation should I store everything in object or in dedicated storage?

Assume we have class Car which MAIN field is called VIN (Vehicle Identification Number). VIN gives us a lot of information such us:
owner
place of registration
country of production
year of production
color
engine type
etc. etc
I can continue and add more information:
last known GPS coordinates
fine list
is theft (boolean)
etc. etc.
It seems reasonable to store some of information (for example year of production and engine type) right inside Car object. However storing all this information right inside Car object will make it too complicated, "overloaded" and hard to manage. Moreover while application evolves I can add more and more information.
So where is the border? What should be stored inside Car object and what should be stored outside in something like Dictionary<Car, GPSCoordinates>
I think that probably I should store "static" data inside Car object so making it immutable. And store "dynamic" data in special storages.
I would use a class called CarModel for the base attributes shared by every possible car in your application (engine size, color, registration #, etc). You can then extend this class with any number of more specific subclasses like Car, RentalCar, or whatever fits your business logic.
This way you have one clear definition of what all cars share and additional definitions for the different states cars can be in (RentalCar with its unique parameters, for example).
Update:
I guess what you're looking for is something like this (although I would recommend against it):
public class Car
{
// mandatory
protected int engineSize;
protected int color;
// optional
protected Map<String, Object> attributes = new HashMap<String, Object>();
public void set(String name, Object value)
{
attributes.put(name, value);
}
public Object get(String name)
{
return attributes.get(name);
}
}
Why this is not a good solution:
Good luck trying to persist this class to a database or design anything that relies on a well known set of attributes for it.
Nightmare to debug potential problems.
Not a very good use of OOP with regard to type definitions. This can be abused to turn the Car class into something it is not.
Just because your Car class provide a property GPSCoordinates does not mean you need to hold those coordinates internally. Essentially, that's what encapsulation is all about.
And yes, you can then add properties such as "IsInGarageNow", "WasEverDrivedByMadonna" or "RecommendedOil".

Objects with two properties only

I am trying to decide on the best approach to the following problem:
I have a class called Desk. A desk has lots of properties. A Desk may have some objects on it. The current application specifies that it can have Pencils, Computers, or Cups on the desk. A few more objects may be added in the future. It can have one or none of each object. The Pencils have a property of Color, all of the objects have an ID and name. All of this information must be persistent so is stored in a database in some form.
Do I:
public class Desk {
public int property1;
public int property2;
...
public ISet<DeskObject> deskObjects;
}
public DeskObject {
public int deskObjectID;
public String name;
public DeskObject(name) {
this.name = name;
}
}
public Computer extends DeskObject {
DeskObject("Computer");
}
public Pencil extends DeskObject {
DeskObject("Pencil);
public Color color;
}
I also need to easily tell which objects a Desk contains in O(1) time. This means I will have to override hashcode and equals (probably by just returning the ID) for the DeskObjects so I can do set.contains(object). It seems like overkill and a misuse of objects. Surely there is a better solution?
If your domain is about desks and the objects they contain, then an object model like this is entirely warranted. The only question you need to ask yourself is this: Is this my domain model, or is it a computation model?
From the phrasing of your question, I would infer its rather the latter. Your objects do not contain any behavior (such as Desk.CleanNonRecentlyUsed()).
A domain model contains data and behavior (a true object model, I call this domain model), a computation model is data and separated behavior (procedural code).
If all your model needs to do is provide efficient lookups, you can chose any abstract representation that suits you. A lightweight object that captures just data is ok, but you could also use tuples (or to be .net specific since you mentioned GetHashCode: Annonymous classes) or just a Hashtable for the desk. Your computation model can be anything from an Index in your database (sounds reasonable in your example), a special object model, or dedicated algorithms over plain arrays.
Most of the time, it is not warranted to create a computation model when you already have a domain model. But sometimes it is.