domain driven design – Obtaining application generated ID from repostory or from entity constructor?

In the Book “Implementing Domain-Driven Design” the author suggests to implement a repository method to provide the next application-generated (not database-generated) ID. Like so:

class MyRepo {
  public MyId nextId() {
    return new MyId(UUID.fromRandom());
  }
}

That would lead to code like this:

var id = repository.nextId();
var entity = new MyEntity(id, ...);

But although I can see the point that providing IDs is somehow the responsibility of a repository, I don’t see an actual benefit of this implementation. Why not assiging the ID directly on object construction?

@Entity
public class MyEntity {
  @Id
  private MyId id = new MyId(UUID.fromRandom());
}

One could also argue that the identity is a central part of the entity itself.

But apart from this philoshophical difference, I see the benefit of creating the ID directly in the entity that no additional call to the repository is needed.

Do you see any advantage of providing the ID by the repository?

domain driven design – Primitive obsession, value objects, Commands, Events and where to convert

I don’t think there’s a good, authoritative answer for this — the literature is kind of a mess.

My suggestion is to start by trying to understand the problem from a domain modeling perspective alone; after that, take those ideas and try to see how the event sourcing patterns fit.

Very broad picture: what we are trying to do is express the dynamics of our domain using the domain’s own vocabulary, but the tools that we are using to do that are general purpose.

The information coming to us over the network is, at one level of detail, just a sequence of bytes. We take that sequence of bytes, and start parsing it into more specialized forms (is it an HTTP request? does it have a UTF-8 document in the payload? Does that document conform to the json standard? do the fields in that json document conform to our more specialized schema, and so on). And eventually we can say “this is a Refund request for Order 12345”.

To understand the dynamics of that request – we are generally going to need to consult other information about Order 12345 that we have somewhere else. So our information, in its specialized form, needs to be turned into some more general purpose thing that is, in effect, a query for the data. We send that off to our data store, and get a general purpose message back, that also has to run through a parser obstacle course until we have Order.

Once we have all of the information in its domain representation, we can now apply the domain rules to it. At the top level, this is expressed in the vocabulary of the domain. But what we are really doing is manipulating information, which is captured in data structures. It’s not turtles all the way down, but again a transition from domain concepts to general purpose data structures and primitives.

These transitions are normally handled by parsers. (Note: this is one of the places where I think the literature is weak, as it tends to emphasize checking in constructors — which isn’t a bad idea, but it is a different idea, it serves a different purpose).

So, where do we parse? The usual answer is that we want to parse out near the boundaries, where things aren’t object oriented anyway. After all, parsing isn’t a domain concern – it’s a compensation for the fact that we’re changing the information we need into different shapes.

Thus, the general rule is that you are parsing information into its modeled form before the dynamics are invoked.


the conversion could fail.

Yes, it could, but you need to be really careful about what you mean by that. Being strict about untrusted information is a good idea. If you want to say that your automated happy path should only permit the introduction of new email addresses that are RFC 822 compliant addr-spec, that’s probably fine. But if the admin updates your trusted store to deliberately introduce a non-compliant address, your automation probably shouldn’t be vetoing that decision. But if the data and the checksum don’t match, you might want to put a full stop on the entire world until things get fixed, because the admin shouldn’t ever do that on purpose, and so on.


Event sourcing… well, event sourcing adds a second layer of bad literature on top of the mess we already have.

RefundApproved is a domain concept, and should therefore be modeled in your domain. Because the decision to approve the refund is coming out of your domain dynamics, the interface to create that event should be expressed in the domain language, not in general purpose language. When you query RefundApproved to get an Amount, you are getting a domain value, not a primitive.

Because domain values are interchangeable (nobody cares which 10 USD the refund amount is), you’ve got some freedom to decide whether RefundApproved is a facade in front of a general purpose data structure, or if it is a facade in front of a graph of domain values.

When you parse the event, to turn it into a representation that you can store, you will eventually need to get to some general purpose representation of the information.

domain driven design – Proper way to interact with child entities through aggregate root

In a DDD implementation, I am trying to design my domain model and the way to properly interact with child entities of an Aggregate through the Aggregate root.

Imagine the following two classes in an Aggragate called “Basket”.

class Basket
{
    string Id;
    int TotalPrice;
    List<Item> Items;
}

class Item
{
    string Id;
    string BasketId;
    int Price;
}

The Basket is the Aggregate root and the Item is a child entity, with one-to-many relationship.

Now, at some point the price for a specific Item might change, so I want to update the Price for this Item and also update the TotalPrice of the Basket that contains that item. I am following the rule that any “change” on a child entity should “pass” through the Aggregate root. So, imagine that Basket has a UpdateItemPrice(string itemId, int newPrice) method and Item has a UpdatePrice(int newPrice) method, that each does what their name describes. My question is, which of the following implementations is more proper?

Approach 1:

In class Basket:

void UpdateItemPrice(string itemId, int newPrice)
{
    var itemToUpdate = Items.Where(i => i.Id.Equals(itemId)).FirstOrDefault();

    if(itemToUpdate != null){
        var oldPrice = itemToUpdate.Price;
        itemToUpdate.UpdatePrice(newPrice);
        TotalPrice = TotalPrice - oldPrice + newPrice;
    }
}

And in class Item:

void UpdatePrice(int newPrice)
{
    Price = newPrice;
}

Approach 2:

In class Basket:

void UpdateItemPrice(string itemId, int newPrice)
{
    var itemToUpdate = Items.Where(i => i.Id.Equals(itemId)).FirstOrDefault();

    if(itemToUpdate != null){    
        itemToUpdate.UpdatePrice(newPrice);
    }
}

In class Item:

void UpdatePrice(int newPrice)
{
    var oldPrice = Price;
    Price = newPrice;
    if(Price != oldPrice)
    {
        // raise a ItemPriceChangedDomainEvent
    }
}

In the first approach, what is happening is obvious. In Basket.UpdateItemPrice method, we update the Item’s price through the Item.UpdatePrice method, and then we immediately calculate the new TotalPrice of the Basket there.

In the second approach, “changes” between the entities are propagated in a more “eventual” way. In Basket.UpdateItemPrice method we also update the Item’s price through Item.UpdatePrice method, but then inside there we also raise an ItemPriceChangedDomainEvent, and do no TotalPrice calculation in Basket.UpdateItemPrice. What would happen next is that an ItemChangedDomainEventHandler will be invoked, that will find the Basket that contains the Item which’s Price has changed through the repository, and then call a CalculateTotalPrice() method on the Basket (note: Domain Event handler and Basket.CalculateTotalPrice() method are not shown for simplicity).

The first approach is much simpler and straight forward than the second one, especially for my case where I only want to calculate a new TotalPrice after the Item’s Price update. But, the second approach might be more scalable and flexible for future extension of the application, if for a example besides calculating the new TotalPrice, I also wanted to check if the Item’s new price exceeds a theshold and then also raise an ItemPromotedForDiscountDomainEvent, which when handled will apply also a discount on the Basket’s TotalPrice.

So, after all this talking, could someone give me a thought on which of these two approaches is more suitable/appropriate for me to follow?

Thanks in advance.

python – Rigorously checking whether 2 floating point numbers are close in VBA – Exercise in Test Driven Development

I’m testing performance regression of some code I wrote (this is not that code) by timing its execution in Unit tests. I would like to see if execution time equals some expected value within a given degree of accuracy, e.g. <1% change. VBA doesn’t have this built in as far as I’m aware, so I wrote this function, inspired by Python’s math.isclose function (but translating to VBA may have introduced some bugs/ required a few nuances):

TestUtils.bas

'@NoIndent: Don't want to lose our description annotations
'@IgnoreModule UnhandledOnErrorResumeNext: Just noise for one-liners
'@Folder("Tests.Utils")

Option Explicit
Option Private Module

'Based on Python's math.isclose https://github.com/python/cpython/blob/17f94e28882e1e2b331ace93f42e8615383dee59/Modules/mathmodule.c#L2962-L3003
'math.isclose -> boolean
'    a: double
'    b: double
'    relTol: double = 1e-09
'        maximum difference for being considered "close", relative to the
'        magnitude of the input values
'    absTol: double = 0.0
'        maximum difference for being considered "close", regardless of the
'        magnitude of the input values
'Determine whether two floating point numbers are close in value.
'Return True if a is close in value to b, and False otherwise.
'For the values to be considered close, the difference between them
'must be smaller than at least one of the tolerances.
'-inf, inf and NaN behave similarly to the IEEE 754 Standard.  That
'is, NaN is not close to anything, even itself.  inf and -inf are
'only close to themselves.
'@Description("Determine whether two floating point numbers are close in value, accounting for special values in IEEE 754")
Public Function IsClose(ByVal a As Double, ByVal b As Double, _
                        Optional ByVal relTol As Double = 0.000000001, _
                        Optional ByVal absTol As Double = 0 _
                        ) As Boolean
                        
    If relTol < 0# Or absTol < 0# Then
        'sanity check on the inputs
        Err.Raise 5, Description:="tolerances must be non-negative"

    ElseIf a = b Then
        'short circuit exact equality -- needed to catch two infinities of
        'the same sign. And perhaps speeds things up a bit sometimes.
        IsClose = True
        Exit Function
        
    ElseIf IsInfinity(a) Or IsInfinity(b) Then
        'This catches the case of two infinities of opposite sign, or
        'one infinity and one finite number. Two infinities of opposite
        'sign would otherwise have an infinite relative tolerance.
        'Two infinities of the same sign are caught by the equality check
        'above.
        IsClose = False
        Exit Function
    
    Else
        'Now do the regular computation on finite arguments. Here an
        'infinite tolerance will always result in the function returning True, 
        'since an infinite difference will be <= to the infinite tolerance.
         
        'This is to supress overflow errors as we deal with infinity.
        'NaN has already been filtered out in the equality checks earlier.
        On Error Resume Next                     
        Dim diff As Double
        diff = Abs(b - a)

        If diff <= absTol Then
            IsClose = True
            Exit Function
        End If
        
        'VBA requires writing the result of Abs(relTol * x) to a variable
        'in order to determine whether it is infinite
        Dim tol As Double
        
        tol = Abs(relTol * b)
        If diff <= tol Then
            IsClose = True
            Exit Function
        End If
           
        tol = Abs(relTol * a)
        If diff <= tol Then
            IsClose = True
            Exit Function
        End If
        
    End If

End Function

'@Description("Checks if Number is IEEE754 +/-inf, won't raise an error")
Public Function IsInfinity(ByVal Number As Double) As Boolean
    On Error Resume Next                         'in case of NaN
    IsInfinity = Abs(Number) = PosInf
End Function

'@Description("IEEE754 -inf")
Public Static Property Get NegInf() As Double
    On Error Resume Next
    NegInf = -1 / 0
End Property

'@Description("IEEE754 signaling NaN (sNaN)")
Public Static Property Get NaN() As Double
    On Error Resume Next
    NaN = 0 / 0
End Property

'@Description("IEEE754 +inf")
Public Static Property Get PosInf() As Double
    On Error Resume Next
    PosInf = 1 / 0
End Property

As you can see, I’ve decided to handle +/- inf and NaN for (I think) more complete coverage, although for my purposes of timing code these values of course have no physical interpretation.

Usage is simple:

?IsClose(1, 1.1, 0.1)  '-> True; 10% relative tol
?IsClose(1, 1.1, 0.01) '-> False; 1% relative tol
?IsClose(measuredSeconds, expectedSeconds, absTol:= 1e-6) 'μs accuracy

Feedback on edge cases/ approach would be great – e.g. not sure if it’s better design to allow for overflow errors in the diff calculation Abs(b-a) since on the one hand IEE754 says that double overflow should result in infinity, and therefore IsClose will always be False since diff is infinite. But what if absTol is also infinite (or relTol>1 and a or b are inf)? Then we expect True regardless of diff.

Also line by line style things would be fantastic – especially comments, naming and other hard stuff.

Finally, here are my unit tests, I’d like feedback on these too if possible; I’ve lumped many into one, but the message is sufficient granularity to identify failing tests so I don’t think splitting tests up would help:

IsCloseTests.bas

Option Explicit
Option Private Module

'@TestModule
'@Folder "Tests.Utils.Tests"

Private Assert As Rubberduck.PermissiveAssertClass

'@ModuleInitialize
Private Sub ModuleInitialize()
    'this method runs once per module.
    Set Assert = New Rubberduck.PermissiveAssertClass
End Sub

'@ModuleCleanup
Private Sub ModuleCleanup()
    'this method runs once per module.
    Set Assert = Nothing
End Sub

'@TestMethod("Uncategorized")
Private Sub IsCloseTestMethod()
    On Error GoTo TestFail
    
    Assert.IsTrue IsClose(1, 1, 0), "Same zero relTol"
    Assert.IsTrue IsClose(1, 1, absTol:=0), "Same zero absTol"
    Assert.IsTrue IsClose(1, 1, 0.1), "Same positive tol"
    Assert.IsTrue IsClose(1, 1.1, 0.2), "Close within relTol for a"
    Assert.IsTrue IsClose(1, 1.1, relTol:=0.099), "Close within relTol for b not a"
    Assert.IsTrue IsClose(1, 1.1, absTol:=0.2), "Close within absTol"
    
    Assert.IsFalse IsClose(1, 1.1, 0.01), "Outside relTol"
    Assert.IsFalse IsClose(1, 1.1, absTol:=0.01), "Outside absTol"
    
    Assert.IsTrue IsClose(PosInf, PosInf, 0), "PosInf same zero tol"
    Assert.IsTrue IsClose(NegInf, NegInf, 0), "NegInf same zero tol"
    
    Assert.IsFalse IsClose(PosInf, 0, absTol:=PosInf), "Nothing close to PosInf"
    Assert.IsFalse IsClose(NegInf, 0, absTol:=PosInf), "Nothing close to NegInf"
    
    Assert.IsTrue IsClose(IEEE754.GetIEEE754SpecialValue(abDoubleMax), _
                          IEEE754.GetIEEE754SpecialValue(abDoubleMin), _
                          absTol:=PosInf), "Finite a, b with infinite diff still close when infinite tolerance"
                          
    Assert.IsTrue IsClose(IEEE754.GetIEEE754SpecialValue(abDoubleMax), _
                          IEEE754.GetIEEE754SpecialValue(abDoubleMin), _
                          relTol:=1.1), "Overflowing infinite relTol always close for finite a, b"
    
    'reversed a,b
    Assert.IsTrue IsClose(1.1, 1, 0.2), "Reversed Close within relTol for a"
    Assert.IsTrue IsClose(1.1, 1, relTol:=0.099), "Reversed Close within relTol for b not a"
    Assert.IsTrue IsClose(1.1, 1, absTol:=0.2), "Reversed Close within absTol"
    
    Assert.IsFalse IsClose(1.1, 1, 0.01), "Reversed Outside relTol"
    Assert.IsFalse IsClose(1.1, 1, absTol:=0.01), "Reversed Outside absTol"
        
    Assert.IsFalse IsClose(0, PosInf, absTol:=PosInf), "Reversed Nothing close to PosInf"
    Assert.IsFalse IsClose(0, NegInf, absTol:=PosInf), "Reversed Nothing close to NegInf"
    
    Assert.IsTrue IsClose(IEEE754.GetIEEE754SpecialValue(abDoubleMin), _
                          IEEE754.GetIEEE754SpecialValue(abDoubleMax), _
                          absTol:=PosInf), "Reverse Finite a, b with infinite diff still close when infinite tolerance"
                          
    Assert.IsTrue IsClose(IEEE754.GetIEEE754SpecialValue(abDoubleMin), _
                          IEEE754.GetIEEE754SpecialValue(abDoubleMin), _
                          relTol:=1.1), "Reverse Overflowing infinite relTol always close for finite a, b"
TestExit:
    Exit Sub
TestFail:
    Assert.Fail "Test raised an error: #" & Err.Number & " - " & Err.Description
    Resume TestExit
End Sub

'@TestMethod("Bad Inputs")
Private Sub IsCloseNaNraisesOverflowErr()
    Const ExpectedError As Long = 6
    On Error GoTo TestFail

    '@Ignore FunctionReturnValueDiscarded: Just testing error raising
    IsClose NaN, 0

Assert:
    Assert.Fail "Expected error was not raised"

TestExit:
    Exit Sub
TestFail:
    If Err.Number = ExpectedError Then
        Resume TestExit
    Else
        Resume Assert
    End If
End Sub

'@TestMethod("Bad Inputs")
Private Sub NegativeTolRaisesArgError()
    Const ExpectedError As Long = 5
    On Error GoTo TestFail

    '@Ignore FunctionReturnValueDiscarded: Just testing error raising
    IsClose 1, 1, -1

Assert:
    Assert.Fail "Expected error was not raised"

TestExit:
    Exit Sub
TestFail:
    If Err.Number = ExpectedError Then
        Resume TestExit
    Else
        Resume Assert
    End If
End Sub

… which uses a modified version of the GetIEEE754SpecialValue function given in this answer – link to modified version not for review. This was retrospective test driven development as I already had most of the code written from python, however a few additions were made to make it more VBA-idiomatic (e.g. throw error on NaN, python does not).

domain driven design – Uniqueness in Aggregate Root – DDD

This is a fairly common problem and im sure if you search here you’ll find other questions around invoice numbers and the fact that the legal requirements around them don’t play nice with software design.

The problem is that incremental invoice numbers are specifically designed to force the company accounts to be the “Aggregate Root” or in accounting terms, the yearly accounts have to have ALL the invoices, no extra secret ones, no deletions, no changed ones!

But when your eCommerce system generates an invoice, you obviously cant load in a whole financial years worth of invoices! It doesnt make technical sense to have the company as the AR.

So you just have to break the rules, as Robert notes, a database is quite capable of generating an acid compliant incremental number on write and you can hack together methods to make it work. The only problem is knowing what to call the resultant code in DDD. maybe Domain Service? yeah that sounds like it would work on a power point.

domain driven design – DDD – How should a model be updated from an [HttpPut] rout in a RestAPI?

I’m learning DDD so apologies if the question is too naive. Assume an application that manages user publications developed following DDD and using a RestAPI for external interaction (for whatever front-end layer for instance).

Looking at the Publication model we would have behaviors like ApplyLike, RemoveLike, Comment and so on.

Now assume we are asked to implement the (not yet implemented nor designed) functionality of updating an existing publication through a http-put request from our RestAPI. The author of a publication should be able to modify most of its fields (like title, body text, attachments, etc).

How should I design this behavior of updating an existing publication inside the Publication model?

The solutions I can think of seems clearly wrong to me, which are A: create an Update method with all just set all the updatable fields of the model (which will end up with a huge parameter list and will just expose a meaningless public unique setter accessor for almost all the model fields) B: accept the defeat from option A and just expose public setters for the model fields so the user can modify as they want, and finally C: violate layer separations and just assume that update DTO as part of our domain and create an Update(PublicationDTO) method (which is wrong because our premise is just not right – this DTO doesn’t belong to the domain).

I think this is probably more a OO question than a DDD question, but how should I tackle that problem? Maybe I should have different separate behaviors like ChangeTitle, ChangeBodyText?

domain driven design – Can “backend” be a subdomain?

Let’s imagine an application where users can work collaboratively on projects. There’s a project listing where a user can subscribe to a project, and a coworking screen where multiple users can work on a project.

So far I have identified the core domain, “coworking”, and a subdomain, “collaboration project listing”.

Both project and user need some sort of backend, where user settings can be edited and projects can be created/edited. I haven’t really got a clue, so I identified this as a subdomain “backend”, which seems too abstract, because it doesn’t describe any sort of business domain. Data from backend is needed by both domains that I mentioned above, so I’m hesitant to attach the backend to either of those.

Is it legitimate to have a “backend” subdomain or is it an indication that my domains are not clearly defined?

domain driven design – DDD Aggregate reference differences

I’ve been reading about DDD a lot lately and something I can’t find too much about is the following scenario:

Let’s say we have a Customer aggregate root and a Contract aggregate root.
The reason they are both aggregate roots could be that contract could be accessed directly. A contract expects a Customer in the Create method to be valid, since it cannot exist without a customer.

However, there’s two possibilities:

  1. Save the CustomerId on the Contract
  2. Save a list on the Customer with all the ContractId references for that given customer

Are both of these correct? If so, what’s the main difference and when to choose one above the other?

When downvoting: please comment on what is wrong with this question instead of being silent.