I am trying to wrap my head around the domain driven design concept of the service layer, both application services and domain services. Virtually all of the examples I've come across have to do with CRUD applications with databases. I'm having trouble understanding how these concepts map to graphical applications like the example application I've chosen for this question, a clone of Microsoft Paint developed in .NET/C#.
I read the basic concept of a service layer in DDD and an expanded explanation. I have chosen the following application layers:
Infrastructure (cross-cutting)
Logging
Data (filesystem)
BitmapImage, PngImage, etc.
Domain
Canvas, Image, Selection, Shape, Brush, etc.
Application
Presentation (local client WPF)
Views
ViewModels
One use case I'm trying to design is the user drawing a rectangle on the canvas. From what I've read, since the use case requires the cooperation of several domain objects a domain service, DrawingService, would make sense.
Another use case would be the user loading a file to be displayed. Again, from what I've read, since this use case is a command and a workflow, an application service, FileLoadingService, would make sense.
As Martin Fowler describes, I believe Microsoft Paint is complex enough to warrant a service subsystem, here based on thematic behaviors. However, as the application grows, the service layers could be refactored to fall into partitions of the domain model, e.g. CanvasService, SelectionService, etc. Would than then necessitate another layer of abstraction, perhaps an application facade, now that multiple services must cooperate?
Update 1:
Initial comments suggest DDD architecture is not a good fit for a drawing application. Any suggestions for an alternative?
imho a drawing application is not a very good fit for DDD. It would use something else
Related
I have an onion architecture like this:
http://i.stack.imgur.com/qvyS5.png
I need to create an importer that will monitor a folder and import files to database.
This importer will run on a Windows Forms application .
The component importer (class) is part of my infrastructure or my domain?
Otherwise how it should be represented following the DDD principles?
Application service(maybe domain service if i didn't understand your application intents). The intent of your software is monitoring files, so you probably have "file" class in your domain, IFileWatcher as an abstraction to the folder watcher and IFileRepository for storege...
the "importer" will use those interfaces. this is a better image of the onion architecture.
2 more things;
The bottom line of onion architecture is a way (an architecture way) to keep your domain clean from non domain concerns(for example the application runs in linux or windows, save data in oracle, sql server or file system, UI won't change your domain models and etc...).
I'm a huge DDD fan but i don't feel that your problem worth it(maybe data centric architecture will be better). as #Didaxis said: keep it simple. develop your software as much as simple you can, apply the SOLID principles then you will be alright. when your application growth, you always can to reorganize the project structure(by the way, onion architecture has heavy DI use). so i advice you to keep your application simple and apply SOLID.
Edit:
here some articles about when to use DDD and when not:
Do Either DDD or DDD But Not DDD
When To Use Domain-Driven Design
Any integration should be implemented in the application layer and not in the domain. So according to the onion architecture (or anything else) it would be infrastructure.
I tend to think of the domain as I would a physical calculator. A calculator has input (keypad) and it has output (screen). So the domain would never physically interact with resources outside of the domain. Everything the domain needs would be passed to it from the application layer and the results would be handled by the application layer.
So even though actual database access, using persistence-oriented repository for instance, and file access may be in infrastructure the application layer is what would perform the calls to get the objects, or put them together, before they are acted upon by the domain.
When I use the term layer it is more of a logical concern than a physical layer. The physical structure will depend on a couple of factors and include a good dose of preference :)
So in your case your Windows form may very well act as the application layer. It certainly is the integration point. However, the physical implementation should ideally rely on some re-usable assembly that may be used from, say, a Windows service or even a web site.
I've builded an N-Tier application for CRUD operation with 3rd party libraries.
This is my app design packaging:
List item
Core - with domain models and entities.
DataAccessLayer - with 3rd party libs NHibernate and IOC container Ninject
Ui - Wpf app or Asp.net MVC app
Now i want to separate UI from DAL, exposing my CRUD repositories via WCF Tcp services.
This choice was made for client-server design:
Server: WCF -> DAL with all 3rd party softwares for Database Connection (a lot of driver are very bigs and expensive to install in 100+ clients).
Client: My WPF or SilverLight UI.
I've builded MVC and WebForms APP, a lot of people think that this is a better solution!
But with wpf I have many possibilities to play with graphics and development is faster for me.
All my repositories extending an Interface (for Dependency Injection with Ninject) and i want to add this to my WCF services without create others Interfaces. A lot of my repo's function returning list of NHibernate objects, how to add Attribute "DataMember" to a non WCF project?
But my simple question is, "WHAT IS THE BEST WAY OF DOING THIS,maintaining a good design?"
Thanks for patience!
Ideally you want all of your business logic in the WCF service with the UI as dumb as possible. That way you can create any number of User Interfaces (WPF, Silverlight, MVC, iPhone even) and they are all small and simple with all the common logic in the WCF.
You need to keep things as loosely coupled as possible so following on from that you don't want to pass database things to the front end. Instead you want to send POCOs or DTOs to the front-end that do just enough for the job. Avoid sending a whole database item to the front-end because ideally your front-end should have no knowledge of what database is being used or how it is structured.
As far as your UI is concerned ONLY the WCF contract is important and the DTOs etc. The WCF should be split into several different layers (or tiers), this depends on your approach but you could have facade, business logic, data access layers (do some research into what fits your situation best). You might want to use repository pattern etc, etc, but that will be in the WCF service and the UI will have no knowledge of what is happening in this "Black box".
Ultimately what you want is for all the components to fit together with the least amount of "coupling" where you should be able to swap one component out for another without everything else "depending" on it and breaking.
This is a DEEP subject and I have scratched the surface but hopefully get your thoughts on the right track!
I am trying to use the Model View Presenter (MVP) pattern for a software that I am writing. I am using C# and Windows Forms, althought that should not matter for answering my question.
I have multiple "MVP-structures". One, for example, is handling retained mode graphics where I can draw geometric shapes on a canvas. Another one is taking these shapes, doing some analysis on them and putting the result somewhere else. There are potentially many events that cause controllers to manipulate data somewhere which then causes cascading manipulation of data in yet another place and so forth.
My fear is that I will eventually loose track of what is changing what if I do not organise my software properly. I can think of two ways to organise the interactions between programm parts occuring in my software: either hierarchical or switch board-like.
My question is: Are there any well known approaches or patterns, that I should look up to organise my software? I would need a starting point for my web search.
I think your intuition is right. If you create many events that cascade you are going to end in trouble. I've seen many times over-complex applications due to out of control eventing. This makes the code very difficult to debug and improve.
First thing it came to my mind was the mediator pattern. Elaborating a bit more I would have central classes that manage parts of the business logic. I would have the model in each of the MVP lightweight , basically being a client that asks the server (one of this controller classes) for more complicated business logic. The idea is to have every model of the MVP classes interacting with as few classes as possible (core business logic) and avoid interacting with other MVPs (which will have more specific business logic)
In any case I would limit as much as possible the classes that throw and listen to events and would centralize this in as few places as possible. The observer pattern can help here. Also having a client-server architecture with a service layer containing the heavy business logic can help making this decoupled and maintanable in the future.
The pattern service layer from the fowler classic "patterns of enterprise application architecture" could be good reading too.
The reason for asking this question is that I've been wondering on how to stitch all these different concepts together. There are many examples and discussions on i.e. DDD, Dependency Injection, CQRS, SOA, MVC but not so many examples on how to put them all together in a flexible way.
My goal:
Develop modules that with little or no modification can stand on their own
Changing or reworking the UI should be as easy as possible (i.e. the UI should do as little as possible, and be "stupid"
Use documented patterns and principles
To make it easier to ask a concrete question, the main arcitecture now looks like this:
The example shows how to add a note to an employee. Employee Management is one bounded context. Employee has several properties, among those an ICollection<Note>.
The bound context is in my understanding the logic place to seperate code. Each BC is a module. Most of the time I find each of them can warrant their own UI if needed (i.e. some modules might be made available for Windows phone).
The Domain holds all business logic.
The infrastructure holds repository implementation, and services to send mail, save files and utilities that does not belong in the domain. I'm thinking of making some of the common service feautures that I have to use in several domains (like send e-mail) as a sort of an API that I could reference to save some code implementing the same things across several BC's.
The query layer holds all Querys except GetById that I need in the repository to fetch an object. The query layer can query other persistence instances, and will probably need to change some for each UI.
The Wcf or Web Api is kind of my Application layer, it might belong in infrastrucure and not on the outside. This service also sets up the dependencies, so all UI need to do is to ask for information and send commands.
The process starts with the blue arrows. Read the model since that has most of the information.
In step 1 the EmployeeDto in this example is just some of employee properties to show the user information about the employee they need to make a note on (like a note about new experience or something like that).
So, the questions are:
Does implementing a layered arcitecture like this really involve so much mapping, or have I missed something?
Is it recommended (or even smart) to use a Wcf service to run the main logic like this (it practically is my Application Service)
Are there alternatives to Wcf without having my domain objects in my UI layer?
Is there anything wrong with this implementation. Any fall pits to look out for?
Do you have any good examples to recommend looking at that can help me to understand how all these concepts are supposed to work together.
Update:
I've read through most of the articles now (quite a bit of reading) except for the paid book (requires a bit more time to do). All of them are very good pointers, and the way of thinking of the Wcf of more as an adapter seems to be a good answer to question 2. JGauffins work on his framework is also very interesting if I'm planning to go the that route.
However, as mentioned in some of the comments beneath I feel some of the examples tends towards recommending or implementing event and/or command sourcing, message buses and so on. To me it is overkill to plan for that level of scaling right now. As many business applications this is a "large" (in terms of an internal application, think max a few thousand) number of users working on a large set of data, not a highly collaborative domain in the sense of needing to implement event and command queues often assosiated with CQRS to cope with that.
Based on the answers below, the approach I'll start with will be based on the model above and the answers like this:
I'll just have to cope with mapping. Thoe pros outweighs the cons.
I'll pull application services back to the infrastructure and
consider Wcf as an "adapter"
I'll use command objects and send to application service. Not
polluting my domain with domain objects.
To keep complexity down I try to manage without event/command
sourcing, message buses etc for now.
In addition I just wanted to link to this blog post by Udi Dahan about CQRS, I think things like this keeps complexity down unless they are really needed.
There is a trade-off between mapping and layers. One reason certain mappings exist is because appropriate abstractions aren't available or feasible. As a result, it is often easier to just explicitly map between layers than trying to implement a framework that infers the mappings, but I digress; this hinges on a philosophical discussion of the issue.
The WCF or WebAPI service should be very thin. Think of it as an adapter in a hexagonal architecture. It should delegate everything to an application service. There is conflation of the term service which causes confusion. Overall, the goal of WCF or WebAPI is to "adapt" your domain to a specific technology such as HTTP. WCF can be thought of as implementing an open host service in DDD lingo.
You mentioned WebAPI which is an alternative if you want HTTP. Most importantly, be aware of the role of this adapting layer. As you state, it is best to have the UI depend on DTOs and generally the contract of a service implemented with WCF or WebAPI or anything else. This keeps things simple and allows you to vary implementation of your domain without affecting consumers of open host services.
You should always be on the lookout for needless complexity. Layering is a trade-off and sometimes it can be overkill. For example, in an app that is primarily CRUD, there is no need to layer this much. Also, as stated above, don't think of WCF services as being application services. Instead, think of them as adapters between a transport technology and application services. In turn, think of application services as being a facade over you domain, regardless of whether your domain is implemented with DDD or a transaction script approach.
What really helped me understand is the referenced article on the hexagonal architecture. This way, you can view your domain as being at the core and you layer things around it, adapting your domain to infrastructure and services. What you have seems to already follow these principles. A great, in-depth resource for all of this is Implementing Domain-Driven Design by Vaughn Vernon, specifically the chapter on architecture.
Does implementing a layered architecture like this really involve so much mapping, or have I missed something?
Yes. The thing is that it's not the same object. It's different representations of the same object, but specialized for each use case. A view model contains logic to update the GUI, a DTO is specialized for transfer (might get normalized to ease transfer). etc. etc. They might look the same, but they really aren't.
You could of course try to put all adaptations into a single class, but that would not be very fun to work with when your application grows.
Is it recommended (or even smart) to use a Wcf service to run the main logic like this (it practically is my Application Service)
You need some kind of networking layer. I wouldn't let all client applications touch my database. It would create a maintenance nightmare if you mess with the database schema (if some of the clients still run the old version).
By using a server it's much easier to maintain version differences.
Do note the a WCF service definition should be treated as constant once being used. Any changes should be defined in a new interface (for instance MyService2).
Are there alternatives to Wcf without having my domain objects in my UI layer?
You could take a look at my framework. Start post: http://blog.gauffin.org/2012/10/writing-decoupled-and-scalable-applications-2/
Is there anything wrong with this implementation.
Not that I can see. Looks like you have a pretty good grasp of the concepts and how they should be used.
Any fall pits to look out for?
Don't try to be lazy with the queries and commands. Don't make them a bit more generic to fit several use cases. It will come back and bite you when the application grows. Smaller classes is easier to maintain.
Do you have any good examples to recommend looking at that can help me to understand how all these concepts are supposed to work together.
The my linked blog post and all other articles in that series.
Okay people, here's another one for ya'll:
I'm starting in the n-tier apps world. I've done some reading on the topic and general advice is that n-tier apps' objective is to abstract functionality tween layers. So, based on this, in a n-tiered app the regular model is:
Data Access -> Business Layer -> Presentation
Since I'm a .NET developer, I thought that to enhance integration with multiple client types (Silverlight, Web app or even a WinForms client) I should use WCF (Windows Communication Foundation) as data services at the business layer so clients can communicate to it regardless of its type. Also, I'm a huge fan of NHibernate as a ORM. So my structure goes like this:
Data Access (NHibernate) -> Business Layer (WCF) -> Presentation (WPF, ASP.NET, WinForms
Okay, so that is the setup. I'm a total newbie in this kind of approach, so I thought I could post here requesting for advice on this setup. Also, I'm very confused on how to setup this in a VS solution, I like to separate layers in different projects, but what about abstraction of data objects (like Customer, Order, etc.)? Do I put em in a separate library? And what about WCF? I know is a programmer's sin to transfer the data classes over the wire to the client. What's the professional's way to achieve this?
Thanks, any advice would be very appreciated.
That's pretty much on target. N-Tier is a bit more complex than N-Layer however, and can be contrasted by asking, "Are your layers actually living on separate physical servers?"
Depending on how complex your Business layer is, you might want to abstract it further between a Business and Service layer. Typically those two are tied very closely and live on the same physical server. The service layer often acts as a Facade to your BLL.
If you're Presentation layer is on the same server, than your ASP.NET or WinForms apps might want to communicate with the BLL without going through WCF services.
Read up on Microsoft Patterns & Practices - Application Architecture Guide.
Your Domain objects should live in their own assembly typically your domain model. According to Microsoft Framework Design Guidelines, it's good practice to name your project assemblies accordingly:
[Company].[ProductOrComponent].[...]
I happen to like this format of name-spacing and generally use:
[Company].[Product].[Layer].[SubLayer].[...]
Here is an example solution using solution folders to organize each project:
In this example, I have a BLL and Service layer. The Service layer provides the actual implementation in a WCF Library while the Presentation actually contains the WCF Web application to host the services. It's always good practice to split up implementation from interface.
The /Client folder can be ignored, I just use that as a sample console app for testing. Any Client applications that consume your service should probably have their own solution or you're going to be managing a huge solution.
As for your data object being transferred over the wire... I'm assuming you mean the classes from your ORM. (Domain Model) You're correct its generally considered bad practice. The solution is using Data-Transfer Objects. You can see from the picture I have a .Dto library. If you're able to use tools like AutoMapper, than I'm all for it, however, adding DTO's to your solution brings with it further complexity and maintenance. I believe Dino Esposito wrote a good article on the subject. Will try to find it for you.
Hope this helps.
[EDIT]
I should note, I'm unfamiliar with nHibernate's capabilities. There might be better solutions for using that ORM. I've only worked with Entity Framework.
[EDIT 2]
Check out Dino Esposito's - The Pros and Cons of Data Transfer Objects