Design pattern for handling many parameters and business rules - c#

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.

Related

approaches to organise event handling with increasing software complexity

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.

How to implement a maintainable and loosly coupled application using DDD and SRP?

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.

Software-design only with interfaces?

Is it good approach when in software-designing the class interactions are describe only with interfaces? If yes, should I always use this approach?
I must design class library that should have a high testability (I use C#).
This library have one facade and some amount of classes with different interactions in the background.
In the case of optimizing this library for good testability I've replace most part of my classes with interfaces.
And when I did this, I saw in a connection diagram (Visual Studio class diagram) only interfaces.
Is it normal decision of my problem? or there should be some another approach?
P/S: Maybe it's well known way in software-design but I can't find some confirmation in books that I have.
Yes this is good practice. It allows you to focus about the responsibilities of each class without getting concerned with implementation details. It allows you to see the method call stack and as you say gives a high level of testability and maintainability. You're on the right track as far as I see :)
Yes, that is generally a good practice.
I would recommend you to read a good design patterns book, for example this one.
it is targeted for Java developers but I had no trouble understanding all the examples as a C# developer.
By using interfaces you can decompose your applications into subsystems to make it maintenable and easily expandable. Some uses cases can be:
application may need to communicate more than one web service endpoints to to fullfill same functions such as direct billing or payment interfaces from different providers
data access layer class that execute SQLs to different Databases with different drivers.
processing different objects that implements the same interface using the same thread pool from the same queue

What factors drive you to use embedded scripting in your applications?

What factors do you weigh in your decision process when you select an embedded scripting, and can issues of configuration and variation be overcome purely with IOC and the Plugin pattern?
Many times the Strategy Pattern and Decorator Pattern are good way to tame variation in domain logic. The problem set I am faced with is that calculations and starting points of workflows will vary from through out the year based on different marketing campaigns, and not all data requirements and business rules are know until just before the campaign begins. Being a small shop we would like to have a solution where we can make configuration changes, test rigorously and yet not be forced to compile/link and re-deploy on a constant basis.
Many times I have made internal data structures mutable through Python or Lua. Somtimes externalizing business logic into loadable modules. This makes your solution a reusable framework too that you can deploy to other clients cheaply. It also make 'in the field' fixes quicker (just update a text file) and gives clients freedom to modify their own dynamic data.
If you can safely expose the API without breaking things ... why not?
My two concerns are:
Can I externalize logic that is specific to a client? or that might be tailored later?
Can I do this whilst meeting performance and intellectual property constraints?
A clean framework == Reusable code and a platform you can quickly modify to solve problems of the same ilk without recoding.
I've used this technique in 2 scenarios:
I want to provide some facility for customers/clients to be able to provide some (limited) customisation themselves. e.g. to colour a chart red if a value exceeds 50, so allowing them to type a short script like "if val > limit then 'red'" etc. You have to be careful to limit what the user can program, however (for obvious reasons)
When I need some customisation of the software in the field (i.e. recompilation isn't an option) and I know I'll need a little more than being able to turn components on/off. So I'll implement some mechanism where the application configures itself via scriptable components
(I'm mainly Java-based, so I'm using the Java 6 embedded scripting plus a variety of languages to achieve the above, depending on the focus)

Linq to SQL ORM 3-layer question

I am designing this HR System (desktop-based) for a mid-size organization. The thing is I have all the tables designed and was planning on using the O/RM in VS2008 to generate the entity classes (this is the first time I work with OR/M; in fact, this is my first "big" project.) I wanted to make the app with 3 layers (one of the programmers of the company suggested not 3 but 4 or 5 layers) but after reading quite a lot of blog entries and a lot of questions here I've realized that is not quite easy to do that with LINQ to SQL because of how the datacontext works and how difficult it is to pass objects between layers using LINQ to SQL.
Probably I'll just use the entity classes generated by the VS2008 ORM and add any validation and bussines logic in partial classes. But that would be 2 layers, or not? The app will be used by like 10 users, so I don't think the 2 layer approach is a big issue for now.
In the future, a web-based front-end will be developed so candidates can apply to jobs online. I want to develop it as scalable as possible. But the truth is I don't have a lot of time to waste to make a decision, times running up hehe.
Having said all that, should I just use the entities generated by the VS2008 ORM?
So any suggestion or idea would be greatly appreciated. Thanks.
You're chewing over quite a lot with your line of questioning here. (Is there a concrete question hidden in there somewhere?)
With layers, I assume you mean physical boundaries, i.e. application, app/SOA/WCF server, data layer that lives on the SOA server, and a database somewhere.
Designing for the future might seem like a good idea, but DO make sure that there WILL be a need for all those layers somewhere down the line. Essentially, you do not need a WCF/SOA based approach if you're not exposing your application over the internet at some point. A web frontend can solve the same problem in many cases.
I'm not saying you will not need those layers at all, but you might not. If you really do, seams are your friend. You need to make "cut points" where you can define your boundaries. I commonly use the repository pattern to diversify data access methodologies, and use plain objects (POCO) and interfaces that are persisted via technologies such as NHibernate. Using POCOs also makes it MUCH easier to transfer those objects over the wire at a later point, either standalone or part of messages.
Creating service interfaces that are called can solidify your boundaries. When you are ready to move cross-machine/physical boundaries, you simply create your boundaries in the service implementations.
It sure sounds like a dangerous way to go - creating the tables first, then domain and finally GUI.
I must admit I am no expert on ORM expert but the generated classes I´ve seen looks more like dataobjects than classes. I would say you need another layer to stop all logic to end up in the GUI ).

Categories

Resources