1
class Product...
public static Product newWordProcessor(String name) {
  return new Product(name, new CompleteRecognitionStrategy());
}

Martin Fowler presents this code in his book "Patterns of Enterprise Application Architecture" on page 122. Does this work in the real world? When is Product constructed? Where is this from? How would it know which strategy inject into it?

The great value of the strategies is that they provide well-contained plug points to extend the application. Adding a new revenue recognition algorithm involves creating a new subclass and overriding the calculateRevenueRecognitions method. This makes it easy to extend the algorithmic behavior of the application. When you create products, you hook them up with the appropriate strategy objects. I’m doing this in my test code.

Once everything is set up, calculating the recognitions requires no knowledge of the strategy subclasses.

Where would the following code live:

private Product word = Product.newWordProcessor("Thinking Word"); 
private Product calc = Product.newSpreadsheet("Thinking Calc");
private Product db = Product.newDatabase("Thinking DB");

If your entity is managed by a data mapper it would have to inject the dependency, but how would it know a particular entity holds a particular dependency? Do the strategies have ids in the database, or does the contract hold a attribute that isn't documented which references a particular Product? Or is the Product class completely independent from the database entities that represent records and the Tester class that translates the entities into the Domain model composed of the Contract which holds references to Product?

2
  • What does the rest of the chapter say about the persistence of Product?
    – Laiv
    Commented Oct 25, 2022 at 7:12
  • 2
    I suspect you've overly zoomed in on one part of a larger explanation, making it hard to answer without going and reading the book for ourselves.
    – Flater
    Commented Oct 25, 2022 at 7:44

2 Answers 2

2

In addition to Doc's answer (which I agree with)

Does this work in the real world?

Yes, but it's not for free.

Long story short, domain and persistence are conceptually different models, which makes necessary the transformation from one another. Two models and one layer of transformation. As you may guess, this kind of solution involves a lot of work. In general, segregation and decoupling involve it.

Strictly speaking about DDD, the persistence model is irrelevant and, as Doc has said, it's orthogonal to the domain. The domain is (ideally) agnostic either to the persistence or the data source. It relays on Repositories, but no implementation detail is leaked from them to the domain. In your case, the ORM (mapper) would be one of these details.

When is Product constructed?

When required by either the domain or the business. It might sound too naive, but it's like it's. The application layer is an envelope whose main purpose is to make certain knowledge accessible and usable. The application sends data to the business layer and the business uses the domain's knowledge to complete a task. Between the application layer and the business layer, there could be more layers and one of them will transform the inputs sent by the application to the business layer into Product.

Just in case you didn't notice, your question comes to say that you are mixing up two representations of Product. One is raw data (database records or application inputs) the other is data and behavior. In other words, knowledge.

The former is a long-living representation of the 2nd. It represents a state of the 2nd, at a given moment in the time.

The second is an ephemeral representation since it lives only in memory and lasts as long as it serves its purpose. Usually as long as the lifespan of an execution path.

Both representations have different life cycles and they are created in different moments and due to different causes. And yet they both are the same. Two faces of the same coin. 1

How would it know which strategy to inject into it?

Either by configuration or by the data itself. Nothing prevents you from storing the strategy (a name, an id, whatever) bound to a Product along with the Product's data. And nothing prevents you from evaluating Product's data to figure it out. The correlation between Product - Strategy must live somewhere.

The domain expects you to sort it out somehow. It tells you how to create a new Product but when and how is someone else's problem.

If you are lucky, your mapper will be configurable and extensible enough for you to create your own objects' instantiation. In such a case, Product will be created by the mapper. Most probably in a Repository.

Where would the following code live:

We often refer to this "where" as the indirection layer. It's the layer of transformations I mentioned early in the answer. In this layer, we implement the interaction between models meant to remain agnostic to each other.


1: It's important to keep in mind that the persistence model and the domain model are driven by different forces. Strictly speaking about the persistence model, we design the persistence that best fits the needs for querying and retrieving. The forces driving the persistence model are not necessarily the same as those driving the domain. For example, data structures in

2

This code appears in the context of a chapter which explains the pattern Domain Model.

What the chapter does not explain in detail is the applicational context where a domain model might play a role or where and when the domain model objects are created (for example, from some kind of data store). In fact, for understanding the pattern in that chapter, this does not matter.

Just assume some larger application which builds the model at some point in time when it makes sense. This can be a done, for example, by pulling some data from a database or file and using the Factory pattern to create the specific objects. Or, the domain model objects may be created by some complex logic at run time, without any persistence mechanics at all. Of course, there could be some ORM involved, though the use of those static method construction methods makes most sense when persistence model and domain model are separated (you can find a lot of Q&A on this site regarding this topic using search keywords "separating domain persistence model").

For the idea of a Domain Model, this is all irrelevant. Domain models, which encapsulate data together with behaviour and distribute responsibilities over several objects and classes, are a pattern which appears in many different kind of applications and systems. How and when the objects are created is a topic of its own, which is orthogonal to the Domain Model pattern.

2
  • What is the topic of creation called? Or is it just creational design patterns?
    – Ten Jones
    Commented Oct 26, 2022 at 1:42
  • 1
    @pepsi-maniac: "creational design patterns" is a common term, introduced by the classic GoF book "Design Patterns ...". However, don't believe the only correct way of creating objects is some pattern - more often simple, straightforward object creation by the "new" keyword is all what's required.
    – Doc Brown
    Commented Oct 26, 2022 at 8:34

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.