New answers tagged

0

But now I'm wondering isn't that too much of invariant checking? I think so. Fetching a given DriverId from the DB returns an empty set if it does not exist. So checking the return result makes asking if it exists (and then fetching) unnecessary. Then class design makes it unnecessary also If there is a requirement "a parked car may or may not ...


0

The way you're asking the question (and proposing two alternatives) it is as if the only concern is that the driverId is still valid at the time the car is created. However, you must also be concerned that the driver associated with driverId isn't deleted before the car is either deleted or given another driver (and possibly also that the driver isn't ...


0

Let's assume the aggregate Car has a reference to the aggregate Driver. This reference will be modeled by having Car.driverId. Yup, that's the right way to couple one aggregate to another. if I would talk to domain experts, they would never question the validity of such references Not quite the right question to ask your domain experts. Try ...


0

It might help to ask: Are you sure cars are constructed with drivers? I have never heard of a car composed of a driver in the real world. The reason why this question is important is because it might point you in the direction of independently creating cars and drivers and then creating some external mechanism which assigns a driver to a car. A car can exist ...


0

Miško Hevery writes often about Dependency Injection. video The usual answer is that you are going to instantiate your repository object when you connection your application to your persistence layer: ie, when you are assembling your object graph (in other words, during your initialization procedure, before you start processing requests). UserRepository ...


1

In retrospect, I think I was complicating the issue. In general, commands should either throw an exception or raise one or more events. If I could summarise the architecture of Event Sourcing it would be as follows: Commands are inputs representing instructions to do something. Events are outputs representing historical facts of what was done. Event ...


1

You'll get a system that is architecturally more loosely coupled if you only emit events from a command. Put another way, one command should not need to know what other external commands to issue; that should be the responsibility of the external party (who should subscribe to the event, and could be, as you mentioned, a saga manager having coordination ...


1

Recommended viewing: Udi Dahan on Reliable Messaging -- it's not quite what you are describing, but closely related. Now, is it common practice for a command to not emit any events, but rather to enqueue another command? I haven't seen anybody recommending that practice. Short answer: if you don't save some state, then you can't recover the enqueued ...


4

I think you're talking about multiple bounded contexts that all speak of the same conceptual entity, while each of the bounded context has different responsibilities around that entity, hence the different notions. For each type of entity, one of the bounded contexts should have the fundamental responsibility of being authoritative; the other contexts can ...


2

Whenever I describe something as being an "Implementation Detail," I am saying that the user doesn't need to know how it gets done, so long as it gets done. For example, in C a pointer actually points to a memory address in the computer, but you can't say the same thing about a reference in Java (even though pointers and references both perform essentially ...


0

If transactional correctness requires one aggregate knowing about the current state of another aggregate, then your model is wrong. In most cases, transactional correctness is not required. Businesses tend to have tolerance around latency and stale data. This is especially true of inconsistencies that are easy to detect and easy to remedy. So the command ...


1

Here's an example of how you might approach this from a functional perspective, and how it helps avoid the potential pitfalls. I'm working in Haskell, which I'll assume you don't know, so I'll explain it in detail as I go along. data Application = Applied ApplicationDetails | InReview ApplicationDetails | Approved ...


1

You could use the «command» pattern, and then ask to the Invoker to provide a list of valid functions according to the state of the receiver class. I used the same in order to provide functionality to different interfaces that were supposed to call my code, some of the options were not available depending of the current state of the record, so my invoker ...


1

One approach to this problem which has been extremely successful in the wild is hypermedia - the representation of the state of the entity is accompanied by hypermedia controls that describe the kinds of transitions that are currently allowed. The consumer queries the controls to discover what can be done. It's a state machine, with a query in its ...


1

You need to read Greg Young on set validation. Short answer: before you go too far down the rats nest, you need to make sure that you understand the value of the requirement from the business perspective. How expensive is it, really, to detect and mitigate the duplication, rather than preventing it? The problem with “uniqueness” requirements is that, ...


2

Considering domain layer is persistence ignorant and has no idea how to retrieve the data but only how to do operations on them, it cannot really touch the repositories itself. I would disagree with this part. Especially the last sentence. While it is true that domain should be persistence ignorant, it does know that there is "Collection of domain ...


0

I would make a class to save value objects and another to load each value object. Value objects here mean primitives only. Also, validate and try immutability so no thread locking is needed (can't data data race if immutable). Builder pattern may help. Then for agretes named Foo make a persist Foo class. It holds all value objects in Foo as final and ...


1

You need a data-cleansing exercise. You don't have a chance in hell of writing decent code that will work if the existing data breaks the rules you're trying to establish. Your code is not at fault if it enforces rules on new data, but can't handle old data that - from the sound of it - wouldn't know a rule if one walked up to it and said hello. Your code ...


1

This is a common issue when implementing aggregates. It usually gives rise to separating aggregate state onto a another object. That object can be a pure data bucket with public getters/setters for convenience. Outside callers could be aware of the aggregate's state class, but it remains private to the aggregate (as a private field, for instance). The ...


5

How should I deal with this legacy data that "breaks the rules". So the starting point is to talk to your domain experts. What do they do with the "invalid" data in the legacy system today? Also, is the legacy system the book of record? or does it describe entities that are actually controlled somewhere else? A mix of both? You may need to consider ...


8

Perhaps it is too naive, but did you consider making a fresh database for your fresh application and writing some converter from the old (badly designed) database to the new one? That converter would be hard to code, but you'll get some more cleaner data from it.


4

This could be solved by using event driven programming and a few observers. How many things does this method do? public void submitThing(Thing thing, SubmitData data) { thing.setStatus(SUBMITTED); thing.setData(data); documentService.doSomething(); mailService.doSomething(); } Three. It does three things. Submits the thing. Does ...


1

REST is a protocol and convention that sits on top of HTTP. It is neither the Application Layer nor the Presentation Layer. It isn't considered part of the OSI model at all. HTTP is considered the Application layer. Don't confuse the Application Layer in DDD with the Application Layer in the OSI Model; they are not the same thing. DDD does not appear to ...


0

In the OSI model? your REST api is running in a user application that talks to the application layer (layer 7). In REST, the primary role of your api is hypermedia data transfer, which is to say converting domain concepts to/from hypermedia representations. That's probably best described as an application concern, rather than a presentation concern. Put ...


2

So, is the Command design pattern the way to go here or are there better patterns for splitting up a class that has several actions into smaller pieces? It's going to depend somewhat on how tightly the actions are coupled to each other. On possibility is to combine the idea of the Command pattern with that of Composite. Each individual, isolated ...


1

Beyond @Ewan's fine answer, to get more insight, we need to look more into what is suggested when saying: "service/application" layer. The terminology of services, Services in Domain-Driven Design (DDD), is applicable to many things in DDD. However, the notion of a domain service, or by some, just service: When a significant process or transformation ...


5

Technically, you are free to design the layers in your architecture however you want, but keep in mind transactions express some kind of business logic. If you put business logic into the UI, you make it much harder to write automatic tests for it, since you restrict yourself to tests you can create with an UI testing tool. This typically means ...


1

I assume you mean something like .nets TransactionScope. Using(var t = new TransactionScope()) { DAL.Add(obj1) //dal automatically finds the transaction scope and enlists. Transaction created DAL.Remove(obj2) // sql executes in transaction t.Complete() //any db transactions are committed } While it is possible to use the transaction scope ...


3

It seems to me your question is split into two parts. The first revolves around duplication of interfaces. The second on dependencies. First, duplication of interfaces. You probably want to duplicate them in the case you are describing. A good rule of thumb when breaking up a monolith is to keep your boundaries clearly defined. If you have two domains, it ...


0

One of the advantage of microservices is that each microservice can evolve relatively independently from the other, due to a looser coupling. Keeping the monolith library and reusing it in all the microservices would not fit into the logic, because you'd have many more dependencies that you'd ought to have. The only advantage that would gain from such a ...


2

I think you want dependency inversion, where "higher level" code (like the Domain) defines interfaces that it will work against, and then demands that whoever uses it will somehow supply suitable implementations. Metaphorically, you're hiring a prima-donna celebrity: They'll perform, but they stipulate that at the airport they expect to be greeted by a ...


11

The way the "anemic model" problem is described doesn't translate well to FP as is. First it needs to be suitably generalized. At it's heart, an anemic model is a model which contains knowledge about how to properly use it that isn't encapsulated by the model itself. Instead, that knowledge is spread around a pile of related services. Those services should ...


4

To a large degree, immutability makes it unnecessary to tightly couple your functions with your data as OOP advocates. You can make as many copies as you like, even making derivative data structures, in code far removed from the original code, without fear of the original data structure unexpectedly changing out from under you. However, a better way to ...


-3

I'd like to know how DDD fits into FP paradigm I think it does, but largely as a tactical approach to transitioning between immutable Value Objects or as a way to trigger methods on entities. (Where most of the logic still lives in the entity.) and whether term 'anemic model' still exists in that case. Well, if you mean "in a way analogous to ...


-2

I think the essence of the matter is that an anemic model with all domain logic in services that operate on the model is basically procedural programming - as opposed to "real" OO programming where you have objects that are "smart" and contain not just data but also the logic that is most closely tied to the data. And the same contrast exists with ...


1

You can counter this problem and solve some others by 'snapshotting' your object. When you do this you build an object to its current state via events and then save that state as the new first event. Discarding or moving to an archive events which occurred before the snapshot. This enables you to limit the size of an object at the cost of losing its ...


4

REST maturity levels and DDD are orthogonal concerns. Your Ubiquitous Language doesn't care whether it's reflected deep down in the payload of a SOAP message, in a resource URI, or in a domain-specific content type, as long as it remains pervasive and coherent throughout its Bounded Context. If your Bounded Context includes both the client and server ...


0

If we consider that you're doing the server side and your "client" the client-side. A DDD would be something at least of HATEOAS approach but even probably more : adding new HTTP method relevant to the domain. Example DELETE could fit for a disabling and a reenabling could have a verb RESTAURE. (Yes this can be done with PUT but this is less domain ...


0

I feel like you were really close, but just missed it order = orderRepository.Get(123) OrderService.AddOrderLine(order: order, product: "Chocolate Cake", amount: 3)) orderRepository.Save(order) What you were looking for is more like this: order = orderRepository.Get(123) order.AddOrderLine(orderService: orderService, product: "Chocolate Cake", amount: ...


3

Typically, you would handle this sort of thing in the application, rather than in the domain. For example, a rate limiter to restrict the number of edits per BlogPost, maybe another on the edit command itself. This sort of thing comes up in authentication security, so you might look there. A second approach would be to treat up or down votes as events, ...


1

In my understanding, primary function of a bounded context is to encapsulate a common language used by a group of users. This is the main tool that enables reflecting already used terminology in software abstractions instead of creating unnatural abstractions to satisfy all users. IMO primary guideline for drawing context boundaries would be to not think ...


1

"Bounded context should be relatively small, but large enough only to capture the complete ubiquitous language of the isolated business domain, and no larger"


1

A bounded context contains a domain model. So typically, a bounded context represents an application or micro/service. A large application such as an ERP suite, could have multiple bounded contexts representing the different applications in the suite, e.g. CRM, Accounting, Procurement, HR. If modifying part of an existing application, it can be common to ...


0

The concepts you mention (Clients, Products, Orders, Billing) are typically represented in a single Domain Model and hence Bounded Context. I suggest you are understanding these concepts incorrectly.



Top 50 recent answers are included