I have a model made up of three objects, a base model object, a specific model object (generalStatus as an example) and an genericXML getter object. The getter object is passed into the model so I can drive test cases without a network. There is a specific controller (genstatusController as an example) for each model pulling data and update the view. The low level genericXML getter uses ASIHttp for its network work, there are run loops and the activity is async. The specific model has a genericXML getter, it will call the getter to update an XML document. There are many upper level models all using the same base model and then a common XML getter object. When the genericXML getter finishes a async request to update an xml data it post a NSNotification to the model. The model will then parse the XML and post a NSNotification to the controller letting it know the data is updated. I have a couple of protocols between the base objects and specific model. I like this level of enforcement, is there a way to enforce the NSNotification between the sets of objects?
BTW, the controller invokes the refresh of the data but needs to wait on an async event from the model to to tell it the update is done so it can update the view.
Related
Assume read model ProductCatalogueItem is built from aggregates/write-models, stored separately from write-models, and contains each product available for selling, and has following properties:
basics: product_code, name, price, number_of_available_stock,
documentation: short_description, description,...
product characteristics: weight, length, depth, width, color,...
And, there are two views:
product list containing list/table/grid of available product offers, and the view needs only following basic properties: product_code, name, price, number_of_available_stock,
product details showing all the properties - basics, documentation, product characteristics.
Naturally, there come two ViewModels in mind:
ProductCatalogueListItem containing only basic properties,
ProductCatalogueItemDetails containing all the properties.
Now,.. there two options (I can see).
ViewModels are 1:1 representation of ReadModels
Therefore the are two read models, not one, ProductCatalogueListItem and ProductCatalogueItemDetails. And, the read service will have two methods:
List<ProductCatalogueListItem> searchProducts(FilteringOptions),
ProductCatalogueItemDetails getProductDetails(product_code).
And, controllers return these models directly (or, mapped to dto for transport layer).
The issue here is filtering,.. should read service perform search query on a different read model, than is returned from the method call? Because, ProductCatalogueListItem doesn't have enough information to perform filtering.
ViewModels are another project of ReadModels
The read service will have two methods:
List<ProductCatalogueItem> searchProducts(FilteringOptions),
ProductCatalogueItem getProduct(product_code).
And, the mapping from ReadModels to ViewModels is done by upper layer (probably controller).
There is no issue with filtering,... But, there is another issue, that more data leave domain layer, than is actually needed. And, controllers would grow with more logic. As there might be different controllers for different transport technologies, then mapping code would probably get duplicated in those controllers.
Which approach to organize responsibilities is correct according to DDD/CQRS, or completely something else?
The point is:
should I build two read models, and search using one, then return other?
should I build single read model, which is used, and then mapped to limited view to contain only base information for view?
First of all, you do a wrong assertion:
...read model ProductCatalogueItem is built from aggregates/write-models...
Read model doesn't know of aggregates or anything about write model, you build the read model directly from the database, returning the data needed by the UI.
So, the view model is the read model, and it doesn't touch the write model. That's the reason why CQRS exists: for having a different model, the read model, to optimize the queries for returning the data needed by the client.
Update
I will try to explain myself better:
CQRS is simply splitting one object into two, based on the method types. There are two method types: command (any method that mutates state) and query (any method that returns a value). That's all.
When you apply this pattern to the service boundary of an application, you have a write service and a read service, and so you can scale differently the command and query handling, and you can have also two models.
But CQRS is not having two databases, is not messaging, is not eventual consistency, is not updating read model from write model, is not event sourcing. You can do CQRS wihtout them. I say this because I've seen some misconceptions in your assertions.
That said, the design of the read model is done according to what information the user wants to see in the UI, i.e., the read model is the view model, you have no mapping between them, they both are the same model. You can read about it in the references (3) and (6) bellow. I think this answer to your whole question. What I don't understand is the filtering issue.
Some good references
(1) http://codebetter.com/gregyoung/2010/02/16/cqrs-task-based-uis-event-sourcing-agh/
(2) http://www.cqrs.nu/Faq/command-query-responsibility-segregation
(3) "Implementing Domain Driven Design" book, by Vaughn Vernon. Chapter 4: Architecture, "Command-Query Responsibility Segregation, or CQRS" section
(4) https://kalele.io/really-simple-cqrs/
(5) https://martinfowler.com/bliki/CQRS.html
(6) http://udidahan.com/2009/12/09/clarified-cqrs/
As you already built your read model using data which arrived from one or more services, your problem is now in another space(perhaps MVC) rather in CQRS.
Now assume your read model is a db object and ProductCatalogueListItem and ProductCatalogueItemDetails are 2 view models. When you have a request to serve list of products you will make a query in your read db from read model (ProductCatalog table). May be you make queries for additional filters using additional where clauses. Now where do you put your mapping activities in your code after fetching db objects? Its a personal choice. You don't have to do it on uupper llayer aat aall. When I use dapper I fetch db objects using view models inside generic. So I can directly return result from my service method whose return type would be IEnumerable.
For a detail view I would use the same db object. I know CQRS suggests to have different read models for different views. But question yourself - do you really need another db object for detail view? You will need only an id to get all columns where in the first case you needed some selected columns. So I would design your case with a mixture of your 2 above mentioned methods - have 2 service methods returning 2 different objects but instead of having a 1:1 read model to view model have a single read db object and build 2 different view models from it.
I've created an NSManagedObject class that matches the corresponding Core Data entity. The class has an initializer so I can pass in property values and assign them.
Once the NSManagedObject class is initialized and ready to be saved to Core Data, how exactly do you save it?
The examples I've seen all start by creating a new class through NSManagedObjectContext. I don't want to go that route since I'm creating the class like any other class.
Is there some way to pass this object to NSManagedObjectContext and call its save() method.
It sounds like you're probably not properly initializing your managed objects. It's not enough to assign property values in an initializer-- you have to use the designated initializer. The examples you've seen all use an NSManagedObjectContext because the designated initializer for a managed object requires one. If you don't provide one, you're not using the designated initializer, and you won't be able to save your objects in Core Data.
This is one of the base requirements of Core Data. You must use managed objects, which must be initialized properly, and doing this requires a context.
You don't save a managed object-- you tell a context to save any changes it knows about, which includes changes to any of its managed objects. You can make that more fine-grained by creating a new context that only knows about one new object. But saving an object on one context doesn't automatically let other contexts know, so you end up adding some complexity to keep changes synced.
Apple's Core Data Programming Guide covers this in detail with sample code.
From what I've read and implemented, DTO is the object that hold a subset of value from a Data model, in most cases these are immutable objects.
What about the case where I need to pass either new value or changes back to the database?
Should I work directly with the data model/actual entity from my DAL in my Presentation layer?
Or should I create a DTO that can be passed from the presentation layer to the business layer then convert it to an entity, then be updated in the DB via an ORM call. Is this writing too much code? I'm assuming that this is needed if the presentation layer has no concept of the data model. If we are going with this approach, should I fetch the object again at the BLL layer before committing the change?
A few thoughts :
DTO is a loaded term, but as it stands for Data Transfer Object, I see it more as a purely technical, potentially serializable container to get data through from one point to another, usually across tiers or maybe layers. Inside a layer that deals with business concerns, such as the Domain layer in DDD, these little data structures that circulate tend to be named Value Objects instead, because they have a business meaning and are part of the domain's Ubiquitous Language. There are all sorts of subtle differences between DTO's and Value Objects, such as you usually don't need to compare DTO's, while comparison and equality is an important concern in VO's (two VO's are equal if their encapsulated data is equal).
DDD has an emphasis on the idea of rich domain model. That means you usually don't simply map DTO's one-to-one to domain entities, but try to model business actions as intention-revealing methods in your entities. For instance, you wouldn't use setters to modify a User's Street, City and ZipCode but rather call a moveTo(Address newAddress) method instead, Address being a Value Object declared in the Domain layer.
DTO's usually don't reach the Domain layer but go through the filter of an Application layer. It can be Controllers or dedicated Application Services. It's Application layer objects that know how to turn DTO's they got from the client, into the correct calls to Domain layer Entities (usually Aggregate Roots loaded from Repositories). Another level of refinement above that is to build tasked-based UIs where the user doesn't send data-centric DTO's but Commands that reflect their end goal.
So, mapping DTO's to Entities is not really the DDD way of doing things, it denotes more of a CRUD-oriented approach.
Should I work directly with the data model/actual entity from my DAL in my Presentation layer?
This is okay for small to medium projects. But when you have a large project with more than 5 developers where different layers are assigned to different teams, then the project benefits from using a DTO to separate the Data Layer from the Presentation Layer.
With a DTO in the middle, any changes in the presentation layer won't affect the data layer (vice versa)
Or should I create a DTO that can be passed from the presentation layer to the business layer then convert it to an entity, then be updated in the DB via an ORM call. Is this writing too much code? I'm assuming that this is needed if the presentation layer has no concept of the data model. If we are going with this approach, should I fetch the object again at the BLL layer before committing the change?
For creating a new entity, then that is the usual way to go (for example "new user"). For updating an existing entity, you don't convert a DTO to an entity, rather you fetch the existing entity, map the new values then initiate an ORM update.
UpdateUser(UserDto userDto)
{
// Fetch
User user = userRepository.GetById(userDto.ID);
// Map
user.FirstName = userDTO.FirstName;
user.LastName = userDTO.LastName;
// ORM Update
userRepository.Update(user);
userRepository.Commit();
}
For large projects with many developers, the disadvantage of writing too much code is minimal compared to the huge advantage of decoupling it provides.
See my post about Why use a DTO
My opinion is that DTOs represent the contracts (or messages, if you will) that form the basis for interaction between an Aggregate Root and the outside world. They are defined in the domain, and the AR needs to be able to both handle incoming instances and provide outgoing instances. (Note that in most cases, the DTO instances will be either provided by the AR or handled by the AR, but not both, because having one DTO that flows both ways is usually a violation of separation of concerns.)
At the same time, the AR is responsible for providing the business logic through which the data contained in the DTOs are processed. The presentation layer (or any other actor including the data access layer, for that matter) is free to put whatever gibberish it wants into a DTO and request that the AR process it, and the AR must be able to interpret the contents of the DTO as gibberish and raise an exception.
Because of this requirement, it is never appropriate to simply map a DTO back to its Entity counterpart.
The DTO must always be processed through the logic in the AR in order to affect changes in the Entity that may bring it to the state described by the DTO.
In a demo project I am setting up as a proof of concept I am finding myself with a lot of duplicated DTOs and fields. For instance considering 1 root object representing an item or inventory, I would have the following classes and properties
CreateItem [ Code, Description, Weight ]
Entity on aggregate root [ Code, Description, Weight ]
ItemCreated event [ Code, Description, Weight ]
Item read model [ Code, Description, Weight ]
Query request object [ Code, Description, Weight, Page, PageSize ]
Response DTO [ Code, Description, Weight ]
and so on
All these objects are a result of separating my app into the traditional Domain, Application, Presentation layers.
How are you managing all this duplication? Tools like AutoMapper and such help to convert between them, but if I wanted to add a new property to Item that would be used everywhere I would have to update all these models.
Because the domain model may not be exactly the same as the application read model, I understand the need for separate definitions, however this can very quickly become a maintenance nightmare.
Charles,
An approach that might help you get rid of some bits of duplication could be the following:
do not add public properties on the entity. As you are using event sourcing, the internal state of the entity will be restored by replaying the events associated with the entity in question. And nobody from outside the entity should know how the reconstructed state of the entity is represented - a series of private fields, an array of string objects, whatever. After all, you can choose to have no internal representation of its state, but implement all the behavior (all the methods) by simply replaying the events each and every time :) So, at one extreme, you may have 1 single field on the entity = a collection of events.
Item read model and Response DTO... Make them the same thing! As you are using cqrs, that is, you have already segregated the read model from the write model, there is no need to make a lasagna out of the read-side of the application. It is OK to have a minimum number of abstraction layers on the read-side. The read model is already behavior-less, it is data only. It's a DTO that gets constructed from events, gets persisted into a data storage with a (more or less) denormalized schema and, upon user request, is retrieved from the storage and presented on the UI or so. It's pure data that gets transferred from one place to another. Though, if, for some reason, you have to return to the end user (human or machine) some other data in addition to the data from the read model object, apply basic object composition. Compose two or more behavior-less objects into one such object. And send the latter on the wire.
speaking of composition, you may even define a (value) type such as ItemDescriptor [Code, Description, Weight] in a shared library and use it when defining the CreateItem command, the ItemCreated event, the read model, the query request object or so. If you are using a language that supports mixins, then mix that ItemDescriptor in :) Else, basic composition may be applied.
Furthermore, the "maintenance nightmare" can be ameliorated to some extent if packaging by feature would be used instead of packaging by layer.
Also, perhaps this post might help a bit.
In domain driven design, it appears to be a good practice to use Factories to create your domain objects in your domain layer (as opposed to using a direct constructor or IoC).
But what about using the domain object factories in a presenter layer. For instance, say that I was creating a domain object from user input obtained from the presenter.
Here's an example, say I have a Configuration domain object that has a number of decimal settings.
public class Configuration : PersistantObject
{
public decimal temperature {get;set;}
...(times 20)
public decimal gravity {get;set;}
}
In order to create this object in the domain layer, rather than the presenter layer, I would have to pass each of these decimal values as function parameters. Creating an unwieldy function definition and call.
ie ConfigurationService.CreateConfiguration(temperature, ...(x20), gravity);
The perhaps better solution would be to create the Configuration object in the presenter layer, and assign all the values of the configuration object directly from the user input, skipping a lengthy function call.
Configuration config = ConfigurationFactory.CreateNewConfiguration();
config.temperature = temperature;
..(x20).. = ...;
config.gravity = gravity;
ConfigurationService.SaveNewConfiguration(config);
But I'm wondering if this approach is wrong and why?
If both of these approaches are wrong, what is the best approach for creating a lengthy object from user input and why?
Thanks!
I'd advise against letting your domain objects out of the domain layer and into the presentation layer. Keep the presentation layer focused on presentation.
For this reason, I construct Data Transfer Objects to shuffle data to and from the domain and presentation layers. In your case, have the dialog populate a DTO that is passed to your service and translated into the corresponding domain object.
You wouldn't want to construct domain objects from DTOs every time, though. Consider the case where a DTO represents only a subset of a domain object. Re-constructing an existing domain object from such a DTO would give you a partial domain object. You'd probably want to maintain a light-weight cache that held the full domain object so you could do a proper update.
Essentially, you'd arrive at the DTO solution if you applied the Introduce Parameter Object refactoring.
There are two main ways I would handle this
1) If this is setup through a dialog I would create classes implementing the command pattern and bind a dialog with the object in question. For example CmdCreateConfigurationService, and CmdEditConfigurationService.
CmdCreateConfigurationService would rely on a factory class and minimum parameters you need to select the correct Configuration Service.
You setup a IConfigurationServiceEditor interface and pass that as one of the parameter to CmdEditConfiguration Parameters. With the IConfigurationServiceEditor interface you define as many methods as you need to make the transfer of information from and to the dialog easy and painless as possible. I recommend using a collection of keys and values.The Command Object knows how to setup up the Configuration Service from this collection. The Dialog know to expect this collection when setting up.
Regardless of the data structure you will do the work of filling out the Configuration Service in the command object. By having non dialog/form/screen object implement IConfigurationServiceEditor you can automate your testing and in certain circumstances make configuration of complex objects easiers.
I developed this method for a CAD/CAM softaware that has several dozen parametric shapes each having from 4 to 40 entries.