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.
Related
I consider myself quite amateur when it comes to designing a system's architecture, and I currently find myself in the process of doing just that.
Particularly, I am trying to come up with an efficient and maintainable way to re-implement all classes that have methods/functions that query the database to read data, then send it upstream for another layer to process it, and finally receive the processed data to write it back to the database.
Surely this generic problem has already been solved. I intend to follow a DDD approach, so that the methods accessing the database are part of an "Infrastructure" layer. Is there an optimal way of designing a system (or structure of classes) to accomplish this? Should I have just one gateway to read/write from the database that all classes should refer to, or should each components have its own way of communicating with the database? Is there a standard approach to do this?
I am mindful that the question might be a bit broad, but for the experts out there surely you have gone through this and are able to help.
There are following items to be considered:
DAO pattern - Create DAO layer leveraging DAO objects (for each domain object) where upper layer (such as service layer) can make use of it.
Architecture - If you are thinking about micro-services architecture, then UI, Service, DB access (DAO) & DB - all these will be single deployable unit. Hence, design pattern will be aligned to chosen architectural approach.
API Gateway - An API gateway (aligned with architectural approach). Think about functional use-cases while designing APIs rather than just providing CRUD operations or technology specific APIs.
As an accepted practice, your presentation layer, business logic and data access(some call it back end layer) should be fairly separated. Microst's MVC concept is just a sensible example of dedicated effort to achieve this. AngularJs from Google is another example of MVVM that is to write clean code on client side as opposed to Asp.net MVC server side. So what should be the best practices is clearly established here. As for your question, I would say to design something qualify for highly optimized designing paradigm does not require a certain way but an experience of knowing somany ways and wisdom to choose single or multiple ways or even mixing them to suit your needs. As for your question about gateway to data access, let me put it this way, maintain multiple connections is a very resource consuming job so ideally a single static instance data class in which a single connection is maintained is an appropriate approach and all the data serving, manipulating methods should be put in there. In web development, we are familiar with webservices exposing objects with operation / message contracts. Separation and encapsulation is the key here. But be sure nothing is perfect, though Asp.net MVC boasts the best methodology of separating all these layers, they have Razor to contradict it. But it's necessary. Hell with being paranoid with tightly coupled back and front end or spaghetti code. It all makes sense when it suits your needs. The key here only experience can teach us the optimize way or ways to do something. That's the returned value of my answer!
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.
I am working on a project that is responsible for creating a "job" which is composed of one or more "tasks" which are persisted to a database through a DAL. The job and task columns are composed of values that are set according to business rules.
The class, as it exists now, is getting complicated and unwieldy because the business rules dictate that it needs access to many databases across our system to decide whether a job can be created and/or how it should be set up.
To further complicate things it needs to be necessary to submit a list of jobs and it needs to be callable in a variety of ways (as a referenced assembly, via windows service, or via web service).
Here are some examples of the things it does:
Generate a job cost estimate
Take in an account and/or user to which assign the job
Emit an event for job submission progress tracking
Merge in data from an outside, user-defined list (.csv, .xls, ect.)
Copy files from a local drive to a network accessible drive (if necessary)
My question is: What are the best practices or design patterns to make this as manageable and simple as possible?
Seems like the class needs to be refactored as it would appear to violate the Single Responsibility Principle. I would recommend that each one of the bullet points above have its separate implementation class. In this way you would be implementing the facade pattern , where your main class represents the high level abstraction of what the system is doing.
This type of program can get really messy if not kept clean from the ground up. I myself always try to stick with the basic 3-Tier Application (Presentation, Business, Data). There is a lot of good information out there for building applications in this manner, and it's best to do some demo projects, and read what others have to say about the subject. Here is the MSDN reference.
I myself had to redesign an application that did something very similar. Once I got my Data Layer separated and worked out from everything else my life became a lot easier.
My best advice is take the time to Plan a lot. Use diagrams, flowcharts, etc. etc.. When a program is this complex, I like to have the groundwork for my layers laid out before I ever start writing code.
Given your description of the requirements, there's no real "simple" way to go about this. Its requisite functionality is massive and diverse. My only suggestions are to make the entire thing into a DLL library (or even a set of DLLs), to separate the various frontends so that referencing the assembly need not rely on the Windows service (for instance); and to stick to basic OOP commandments like loose coupling.
Besides recommending to use SOLID and go the extra mile to keep it DRY, I'll suggest to introduce the concept of rules in the system.
By modeling the rules you can switch to a more configurable / flexible approach. You can combine multiple rules to expose different operations that affect the outcome in jobs and the related tasks.
This allows you to have rules that are composed of others. Depending on the scenario you have, that could greatly simplify how you deal with it, since some operations that involve implicit rules that are spread across all those system can be expressed as a combination of simple rules. I'd keep it as simple as possible, but as you extend it you might find the need for different ways to combine the rules, and patterns will emerge on their own.
As for SOLID, I recommend to check the ebook here and try to keep an evolving code approach.
As I have been learning about software development the last 2 years the more I learn, it seems the more gray areas I am running into. One gray area I have issues with right now is trying to decide how many layers an application should have. For example, in a WPF MVVM application what fashion of layering is ok? Is the following too separated? When I mention layering I mean creating a new class library for each layer.
Presentation (View)
View Model
Business Layer
Data Access
Model Layer
Utility Layer
Or for a non MVVM application is this too separated?
Presenation
Business
Data Access
Model Layer
Utility Layer
Is acceptable to run layers together and just create folders for each layer? Any coloring of this gray area would be appreciated.
The answer is, it depends. First off, a separate class library doesn't always mean a separate "layer." A layer is a conceptual grouping of related functionality, that may or may not manifest itself in a single assembly.
How many layers you create is really dependent on your problem at hand. Traditionally, a WPF MVVM application will contain at least the 3 layers (Model, View, View Model) but it can really be varied. Often times I see the Views and ViewModels in the same assembly and the models in their own assembly (usually because the Model objects are POCO's that are used in other contexts)
There is really no silver bullet that answers your question, it is entirely dependent on your problem. The advantage of "layering" and separation is to increase maintainability, promote code re-use, and increase overall clarity (to name a few).
I would argue that if you are not reaching these goals with your current layering solution then you have room to improve. If increasing the layers is decreasing the clarity or maintainability then you have gone too far. If you have only a single "layer" and it is becoming bloated then you have an opportunity to add a layer.
The bottom line is don't over engineer something for the sake of following a strict "pattern." If the pattern has clear advantages to you and your problem at hand then implement it, but understand why you are doing so and what the goal of each "layer" is.
Consider the following areas:
Speed
Reusability
Readability
Development time
Modification speed (the right words to describe this point are escaping me. Edit - Maintainability was what I was looking for [stolen from someone elses answer])
Application footprint (scale and literal size)
Your development team
...then adjust your architecture based on which of these you value. I'm probably missing some other important parts, but you get the idea. There's really no right or wrong answer to this.
An application only has too many layers if the layers themselves become a hurdle to the maintainability of the project as opposed to improving maintainability.
The exact number of layers that is too many is 1 more than is needed.
Layered Architecture: This article describes a concrete example architecture for .NET/WPF Rich Client Applications. Furthermore, the architecture shows in which layer you find the participants of the Model-View-ViewModel (MVVM) pattern.
What are the fundamental techniques to make most part of my C# source code UI independent?
For example, I would like to write my source code for Winforms desktop application which I shall be able to plug into asp.net web application or a WPF application with very minor changes. I.e. I shall be able to use the same source code irrespective of UI technology to make it future-proof.
I know CSLA framework can do that.
But if I don't use CSLA (it takes some time to learn a new framework and at present I don't have that much time to spend on it), what points should be taken care of to achieve this kind of ability in my C# code?
Can you give me an example? I already use Business Objects and layering technique in my applications. But even so I have seen that it needs a lot of coding to plug my code to new UI technologies.
Please do not provide me with any superficial answer.
The best way to do UI independent coding is to seperate the logic from the presentation. Take a look at the MVC pattern.
This is more of an discipline issue with your design rather than a framework issue. A framework can't not force you to design properly. It can make things easier for you if you design the app properly, however there are always ways around the enforcement of it.
To make your code UI independent, put the logic that is not dependent upon UI into a separate layer or assembly. Separate logic from presentation. It's what all the patterns like MVC, MVP, and MVVM follow. It's such a fundamental piece of software structure that it should be ingrained upon you; if it's not, make it so.
Separate logic from presentation. Learn it. Live it. Love it.
Edit:
Can you give me an example? I already use BO and layering technique in my applications. But even so I have seen that it needs a lot of coding to plug my code to new UI technologies.
Please do not provide me with any superficial answer.
I see that you have edited. Allow me to elaborate:
There's no getting away from some logic that is UI-dependent. UIs are not a shell; they still have logic and functionality. But that functionality should only be geared toward user interaction. Display data. Gather data. Fancy graphical tricks and animations, if your preferences lie in that direction.
The rest goes to the business layer, and that stuff can be reused. If you layer properly, you can avoid having to rewrite your core functionality every time you write the program for a new UI framework.
But you still have to rewrite the UI stuff.
If you're building a multi-tier application, your business logic, data access, etc should already be separated into classes that are completely independent of your UI. Repurposing those libraries for a different target platform - desktop vs web, etc - should be a simple matter of referencing your existing libraries from your new application.
This is a fundamental rule of software development. Although patterns and frameworks like MVC, etc enforce this more stringently, it's ultimately up to you to design your application correctly. This sort of task doesn't require learning a new technology - just common sense and a tiny bit of experience.
Check out Martin Fowler's excellent article on this topic.
GUI Architectures, Including MVC, MVP, MVPC
Take a look at the explanation of MVVM(Model-View-ViewModel) at MSDN Magazine. MVVM is widely used for WPF application development.