Doing a bit of reading around domain driven design and it seems that you're supposed to access all entities within an aggregate by traversal from the aggregate root.
However, at the same time you should really try and encapsulate your data so that the properties/fields are protected or private.
Therefore my question is: If the fields are protected/private how are you supposed to traverse the aggregate?
The way I have set it up at the moment is as follows: I mark all the properties of my domain model as internal with the methods for "setting" marked as protected. This way, at least nothing outside the model can access the properties, but objects within the model can access other objects properties and I still only allow setting of the properties from within the object itself.
Even though I've done this, I still feel as if this should only apply for properties for other aggregate entities (I mean, a Customer's "name" would still be private, but their "Orders" should be marked as internal to allow for the traversal from Customer -> Orders -> etc.)
Does anyone have any guidance on this?
EDIT:
Let me try and give a more concrete example for the question:
I have a two objects in my object graph: Bookshelf and Book. Let us say for the sake of this example that Bookshelf is the aggregate root, and that Books are stored on a bookshelf so are just entities within the aggregate (Bookshelf has a collection of books).
I want to write a method to add a new book to the bookshelf. Following DDD best practices, I believe I should write a method on the Bookshelf class such as AddBook(Book book).
However, what if there is a business requirement that no book with the same title can be added to the bookshelf. I want some logic within the Bookshelf.AddBook method to check the collection of books to make sure this book doesn't already exist.
The problem now is that I can't do that as I've written the Book object in a nicely encapsulated way and its "Name" property is not publicly accessible.
I understand this is a fairly contrived example, but I hope that it better illustrates the problem. I also now realise that this isn't just a DDD problem, but an OO encapsulation one in reality. I'm sure that there must be a very common, easy way of solving what I'm trying to do and I'm massively overthinking it.
There is nothing wrong in exposing properties in case of storng, composition-like relation between parent and its children. Child properties are exposed to the parent, but because their strong relationship and interdependenace it doean't break encapsulation.
In other words, there is nothing wrong in exposing Book's name property to the Bookshelf, but it would be wrong (in sense of DDD best practices) to expose Book's name to other aggregates. It would be also wrong to expose modifiable collection of books. Exposing read-only collection should be done with caution -- it can be sign of breaking of encapsulation.
Does this answer your question?
The Visitor pattern is the typical traversal mechanism.
Related
I have a question about keeping track of objects in different layers of a software application. In my application, I have objects in the domain layer (e.g. LineShape) that are used to represent business entities, and I have corresponding objects in the presentation layer (e.g. System.Windows.Shapes.Line) that are used to display these entities on the screen.
My question is, how do I keep the correspondence between the domain objects and the presentation objects, so that I can identify which domain object is represented by a given presentation object?
For example, if the user clicks on a System.Windows.Shapes.Line in the user interface, how can I determine which LineShape in the domain layer this object represents?
I have thought of a few potential solutions, but none of them seem ideal, especially for larger and more complex object models.
One solution is to use a dictionary that maps presentation objects to domain objects. In this case, when the user clicks on a System.Windows.Shapes.Line, I could look up the corresponding LineShape in the dictionary.
Another solution is to use an ID for both the presentation and domain objects. This approach has the advantage of being simple, but it seems strange to me to use IDs for every object in a domain-driven design, as IDs are typically used only for entities.
Are there any best practices or established patterns for solving this problem?
Use an Id for objects both in Presentations and Domain. This sounds a
bit strange to me, because as far as I am aware, we are not supposed
to use Id for every object in DDD, just for entities.
Perhaps you would be looking at an address rather than an ID. Even values must somehow be addressed so they can be replaced. Such an address may be a class property's name, an array's index, etc.
If you see the whole drawing as a collection of shape values then you could always use the shape's index as the address allowing to replace that specific shape value in the collection.
However, note that the address is only valid as long as you are working against the expected drawing's version.
Furthermore, you could also use the combination of all shape's properties to identify a given shape to modify. If you have two identical shapes (same shape, position, layer, etc.), does it matter which one you re-shape? The final drawing would look exactly the same.
In the end if it makes your life easier to model shapes as entities and given them an ID then perhaps that's the right model too even though you may not care about the specific shape's entire lifecycle.
Finally, note that if shapes are values then you can't possibly keep a reference to them in view models since values are immutable. Also, if shapes are entities, but the drawing is the Aggregate Root then shape entities shouldn't be accessible outside the root. Therefore it most likely only makes sense to reference a domain's Shape in the view model if it's an AR (unless you violate the visibility rule, but still enforce invariants through root-handled events). Also note that address/ID references may be the only option if your domain model lives on another tier.
You've asked a somewhat broad question, so I will give what I think is a correct but general answer.
In WPF, one way or another, the on-screen controls will have a DataContext. The DataContext generally speaking should be the object you want to get a hold of.
This should be the case more or less regardless of what method you use to populate all the screen controls.
It may suit your program to create special viewmodel classes which bridge between your "native" data objects, in which case those viewmodel classes will be set as the DataContext objects. If you don't need the viewmodel then the native data objects will play that role.
If you are using events, then in the code-behind for the event you can directly access the DataContext property, cast it to the expected type, and off you go.
If you are using commands then generally they are part of the viewmodel object in the first place, so they can just act directly on the object which owns them.
This is a question that I've been asking myself for quite some time so I decided to just ask you guys here.
Let's assume I have a Shop-object which contains a ProductList-object as an instance variable. Core functionality of my Shop-object is of course the ability to add a Product.
What should the public interface for adding products to the shop look like?
shop.AddProduct(product)
or
shop.Products.Add(product) ?
Thank you for your thoughts and your help.
This is really a question about whether or not to expose Products as a property, or whether to use methods. And there are already many questions on SO regarding this. For example:
Properties vs Methods
I personally prefer properties in most cases when they are not a functional part of the container object. By that, I mean that products are not an integral part of a store. A store is still a store, even if it has no products.
Products are simply objects that live within the store. As such, they make perfect sense as a collection property. Although I would probably have an Inventory property, of which Products are a property of the inventory.
In any event, methods tend to make more sense when they do something. Not simply containing something. For instance store.PurchaseProduct(product) would remove items from the products collection, but it also does something (adds money to the till, does inventory management, etc..).
Another reason to use methods is when you need to do several things when you manipulate the collection. For instance, suppose you don't want objects removed from products without also ensuring that money goes into the till, or that breakage is recorded. Then, I would still use a property, but I would make that property private and only access it via methods that perform the actions.
This is, however, largely a philosophical argument. People will have opinions either way. What matters is your own opinion.
The repository pattern seems to work well when working with an initial project with several large main tables.
However as the project grows it seems a little inflexible. Say you have lots of child tables that hang off the main table, do you need a repository for each table?
E.g.
CustomerAddress Record has following child tables:
-> County
-> Country
-> CustomerType
On the UI, 3 dropdown lists need to be displayed, but it gets a bit tedious writing a repository for each of the above tables which selects the data for the dropdowns.
Is there a best practice/more efficient way of doing this?
As an example say you have a main CustomerAddress repository which I guess is the 'aggregate root' which inherits the main CRUD operations from the base repo interface.
Previously I have short-cutted the aggregate root and gone straight to the context for these kinds of tables.
e.g.
public Customer GetCustomerById(int id)
{
return Get(id);
}
public IEnumerable<Country> GetCountries()
{
return _ctx.DataContext.Countries.ToList();
}
etc...
But sometimes it doesn't feel right, as countries aren't part of the customer, but I feel like I need to tack it onto something without having to create zillions of repos for each table. A repo per table definately doesn't seem right to me either.
First the code you posted is not the repository pattern. Where is the collection like interface? If it is an aggregate it should only be returning the aggregate type.
Repository pattern doesn't offer up much flexibility when it comes being able to select different types. Repository pattern follows a collection interface (insert/add/update/delete/get/etc), mirroring an in memory thing, and it generally only retrieves on type. So if you were to use the repository pattern you would need to select all CustomerAddresses and then* filter the countries out. I would suggest you move to a different pattern, that allows for more flexibility aka DAO.
If these things are always going to be maintained through CustomerAddress, then switch patterns and create a DAO class that offers some other getters for the other types of things you need.
On a more generic note, build for need.
Never just blindly create repository classes, its a maintenance nightmare. The only time I would argue for a repo per table is when you are doing CMS like things, and need to be able create everything.
Example:
So you have a CustomerAddress which ties together a Customer and a Country, but you have some other process that needs to be able to CRUD the Country. As a result you need* the repository to manipulate Country and if you are following DRY you dont want to have duplicate logic to manipulate Countries. What you would have is a Customer Respotitory that uses the Country repository.
I'm answering my own question here because while the suggestions are certainly useful, I feel I have a better solution.
While I don't have to phsyically create the underlying repository for each and every table as I have a generic repository base class with interface (Get, Add, Remove), I still have to:
1) write the interface to access any specialised methods (generally these are queries)
2) write those implementations
I don't necessarily want to do this when all I want to retrieve is a list of countries or some simple type for populating a dropdown. Think of effort required if you have 10 reference type tables.
What I decided to do was create a new class called SimpleRepo with ISimpleRepo interface which exposes 1-2 methods. While I don't normally like to expose the IQueryable interface out of the repo i/f class, I don't mind here as I want the provided flexibility. I can simply expose a 'Query()' method which provides the flexibility hook. I might need this for specialising the ordering, or filtering.
Whenever a service needs to make use of some simple data, the ISimple< T > interface is passed in, where T is the table/class.
I now avoid the need to create an interface/class for these simple pieces of data.
Thoughts anyone?
Responding to the questioner's own answer: This doesn't make sense to me; though it's possible you still had a good use case, I'm not following. Points 1 and 2 ... if you need specialized methods, then looks like they belong in their own repo. Point 2: yes, that needs an implementation.
Sharing between repos, with the smaller repo being the question (is that one needed), I do appreciate that question / problem, but guys' on this thread steered me to being okay with 1 repo per table, including the possibility of having a 'service layer', though they didn't give any examples of that, and I haven't tried this out yet (currently my practice, for good or ill, has been to have the bigger repo share or instantiate the smaller one it needs):
One repository per table or one per functional section?
Suppose we want to model a doctor's patient: a patient has a prescription history, an appointment history, a test results history... Each of these items is itself a list.
What's the best way to create the patient class?
class MyPatient{
List<Prescription> Prescriptions {get;set;}
List<Appoints> Appoints {get;set;}
...
}
class Prescription{
string PrescripName {get;set}
int Dosage {get;set}
}
class PatientAppoint{...}
This is what I have in mind; please let me know if you have some suggestions.
There are a lot of things to take into account when designing your classes:
Inheritence vs Composition -- Use "Is A" and "Has A".
For example, a Car is a Vehicle. A Car has a Engine.
Don't throw in a bunch of junk into a class to try to make it work for another class.
For example, if you want a Prescription history you'll probably need a Prescription and a Date. But, don't throw a Date into Prescription if it doesn't fit in, instead, extend it to a new PrescriptionHistoryItem class which inherits from Prescription.
Start off with an abstract representation or contractual representation and build off of that. You don't need to end up keeping any abstract classes or interfaces if they are unnecessary, but they might help you on the way there.
Basically, there are a lot of things to consider and this question is pretty open ended. There are way too many design patterns and topics to consider and that are debatable. Overall, your class hierarchy/design looks fine though.
Instead of keeping all classes in a file , i would create a separate file for each class with the same name. It will be easy for future programmer to debug or it will be very clean to understand.
Yes, that is a pretty standard way of representing those objects in OOP. Your patients have a one to many relationship with both prescriptions and appointments, so you patient class has a collection of each. You may want to keep how you are going to persist you data (database I assume) in mind as you design your class structures and layout.
This is a good example of where the model can become problematic at runtime. As you start to draw this out, you may end up with a collection of patients at somepoint. If you have data adapters building patients, and stuffing the prescription, visit, test, etc. histories into the patient classes, then a collection of Patients can end up being quite large. Now if this large collection is being transported over a network, say, between a WCF service and a client, it could become burdensome. For example, if you are just displaying a list of patients...
So in my opinion, I would look at the system from a slightly higher level, and consider some of the things I mentioned above. If you are going to be passing around collections with 500 patients in them, then I might consider a model that allows me to associate patients and "item" histories when necessary, but also be able to have them separated when desired...
This would affect the model, in my opinion, because I don't like to design a class where when the data adapter builds the instance, the population of fields is arbitrary, that is, sometimes it populates them sometimes it doesn't... But I have done that before... ;)
Not sure what the best title would be for this question, or even if I am being clear, but here it is:
What is the best way to setup complex objects so as to not have to retrieve the entire object graph when the parent object is first being accessed?
For example:
Order
has a customer
order lines (many)
product
price
pricing details (discounts, etc)
order status
status
fulfilment date
Would you create the Order with all its dependent objects as properties or would you provide accessor method for the dependent objects?
example:
Option 1:
class Order
public property Customer
public property List of Order Lines
Option 2:
class Order
- public GetCustomer():Customer
- public GetOrderLines():List of order lines
The way I see it each has its own advantages and disadvantages:
Option 1: Class diagrams show the relationship between different objects. The disadvantage is that when you are getting the Order object, you need to get the entire object graph (which could get expensive and in many cases might be unnecessary).
Option 2: Because each object is retrieved through a Get call, you can defer the actual retrieval to when the object is needed. Disadvantage, at least in Visual Studio class diagrams, you can no longer get nice relationships between the different objects.
Are there any other design patterns that can accomplish what I am trying more efficiently?
Would you consider using an ORM such as Entity Framework or NHibernate? That way, you'll get Lazy Loading support without having to go through a lot of trouble implementing it yourself.
The choices of Property vs getter method and lazy loading vs full object graph are orthogonal, you can pretty much have any combination of them.
I'd probably choose a Property here since it's more idiomatic to C#. As for deferring the object retrieval, it depends on your context - like anon wrote, when drawing from database data lazy loading can be appreciable.