I'm not sure if I'm using "standard" terms, but this is a basic OO question I'm trying to resolve.
I'm coding a windows form. I don't want logic in the form event handler, so I just make a call to a custom object from there.
At the custom object, there are two sets of logic.
The "controller" logic, which decides what needs to get done and when.
The actual business logic that does what needs to be done (for example a control that performs a math operation and returns results, etc.).
My question is, does OO architecture allow for having both of these in a single object? Or is it recommended to split them out into a "controller" object and a "business logic" object? Is there a design pattern I should refer to for this?
For the time being, I've started down the route of combining them into one object. This object has a "start" method which contains the controller logic. This method then calls other methods of the object as needed, and ultimately returns results to the caller of the object.
What you're doing is a form of "fat controller" architecture. These days software development is trending toward thin controllers.
OO design is all about decoupling. If you internalize only one thing about OO programming, let it be that.
Check out "Domain-Driven Design Quickly." This free e-book is a condensed introduction to the concepts covered in Eric Evans' important book "Domain-Driven Design."
Getting educated in these concepts should help you to understand how to separate business logic from the controller, or service layer.
In general, you should probably have these in two different objects, but there's a qualifier on that. It may make sense, if your project is small enough and your object model is not complex enough, to have the functionality composed into one object; however, if your functionality is complex enough, it's almost certainly going to be better for you to segregate the controller and the business objects. At the very least, design the system with an eye towards separating the controller and the business objects at a later point, if you don't completely separate them now.
No, I don't put business logic in controllers. I add an intermediate service layer that's injected into controllers. Let the service do the work. Controllers are for routing requests and marshaling responses.
Putting the logic in a clean service layer is "service oriented", even if you aren't using web services or WSDL. It has the added benefit of still working if you decide to change controller/view technologies.
The answer to you design question can is as the following scenario: how would you design your application if you also had to provide a web-client for it.
Both your Windows Forms UI and you Web UI would be calling the same classes and methods. The only difference, then, would be how each populates the UI and communicates with the other layers.
Related
From what I understand in onion architecture, the domain must contain all the business logic. And enforcing database validations are typically done by using Services.
My code is inspired from this repo https://github.com/asadsahi/AspNetCoreSpa , where they are using features, where each folder has all the validation rules and logic for specific feature inside the application layer.
What is the best way to share a specific validation for multiple features? Should I create a service and use it for each feature?
And what is the reason that they moved all the business logic to the application layer while the domain entities does not have any logic?
I found a good article talking about what I need here Dealing with Duplication in MediatR Handlers
Excluding sub-handlers or delegating handlers, where should my logic
go? Several options are now available to me:
Its own class (named appropriately) Domain service (as was its
original purpose in the DDD book) Base handler class Extension method
Method on my DbContext Method on my aggregate root/entity As to which
one is most appropriate, it naturally depends on what the duplicated
code is actually doing. Common query? Method on the DbContext or an
extension method to IQueryable or DbSet. Domain behavior? Method on
your domain model or perhaps a domain service. There’s a lot of
options here, it really just depends on what’s duplicated and where
those duplications lie. If the duplication is within a feature
folder, a base handler class for that feature folder would be a good
idea.
In the end, I don’t really prefer any approach to the another. There
are tradeoffs with any approach, and I try as much as possible to let
the nature of the duplication to guide me to the correct solution.
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 4 years ago.
Improve this question
Let's imagine I'm using MVC. controller got the request from user. do the logic in controller and return the response.
People say that controllers don't do any logic, they simply give the incoming request to service and all the logic stays in service classes methods. But I don't understand why this is good.
Argument 1) people say this is good because you have skinny controllers instead of fat controllers, but who cares skinny controllers if it doesn't give you benefit?
Argument 2) your business logic is somewhere else and not coupled to controller. Why is this argument even worth mentioning? Okay, I have all the logic in service classes' methods and in my controllers they're two lines of code. What did that give me? Service classes are still huge. Is this some kind of benefit?
Argument 3) one engineer even told me that service layer is good because from service methods you return objects to controller and in controller we sometimes return json or some other format. He told me this is good if we have desktop/web/mobile application all together and we are writing api for them. but still doesn't make sense.
What people do and I hate is that they use repository and service (in service methods, they have business logic and repository classes method calls).
Here is how I think. If using service classes (I call it helpers), in a service method, there shouldn't be a thing related to framework. if there's fraemwork dependent code, then it's bad because all my business logic is tightly coupled to framework. What my friend advised is that I put get,insert,update eloquent calls in controller and pass the results to helper (service) which does the data modification. This way to test a helper (service) no need to inject repository or model at all. And why do we have to even need to test repository or model (it's already tested by the framework).
I just have to understand why service layer is going to help me. The thing is I've read so much, and none of the articles really say the real benefits. Is it possible we discuss pros and cons with examples?
Abstraction.
The theory that most people subscribe to is that all functions should do one thing only and one thing well. Keeping this in mind, one huge controller method doesn’t make sense.
but what about just using lots of private methods in your controller file?
It’s arguably harder to debug private methods than public ones because you typically can’t access them to unit test them. Why not just make them public and still keep them in the same file? Because that’s not how we do things. Separation of concern is very important in the MVC model.
Here’s how a controller should work in MVC:
Take an input
Do stuff (doesn’t matter what that stuff is)
Output
The controller shouldn’t care about the business logic - complicated logic should just be a black box that just works as far as the controller is concerned.
Moreover, if you have external API calls, the controller should never be doing them directly. They should be hidden away in a connectors package and accessed via a service layer.
I think the main point of using a service layer is that if your business logic ever changes, your controller shouldn’t care. Your controller should be as “stupid” as possible.
In order to make each layer of your app as reliable and predictable as possible, you need to make sure each layer has a defined purpose - the controller shouldn’t be taking in inputs, doing complex logic, and giving outputs. Obviously if the logic is tiny then abstracting it is a bit of overkill but it’s a good habit to get into.
Finally, it makes debugging your code easier for other people. If you move on from this project and someone else has to pick up where you left off, if your code is all in one place then they will hate you. Finding bugs and making improvements is very hard when everything is all together. If you follow convention and separate your business logic away from your controller, you will make other people’s lives easier as they’ll know what to expect.
Basically, just do it. It’s a good practice to get into and will make your life easier in the future.
I will try to give simple answer
Try to write unitest for fat controller ...
It is better to test class or even interface method instead of controller method which returns view. Better to test method which have less preconditions and responsibility. Controller's methods is final method which intergate all logic. Http processing, Validation, business, and so on. For unit testing,debuging and reusing it is better to keep this logical parts separately.
I'm currently designing the foundation for a large application. We are going with the traditional 3 tier system using EF in the data layer, plain jane c# classes in the business layer and MVC / WCF for the ui layer. We have prototyped enough of the application to realize that this will work for us, however due to the complexity of the business requirements it will be common for some of the business components interact with one another.
Consider the following two business components:
RetailManager - Deal with everything related to retail in the system
CartManager - Deals with everything related to the shopping cart experience
The two interact, for instance, during the checkout process when an item is purchased. The inventory for the purchased item needs to be reduced.
Here is my thought process so far:
Let business components reference each other and ensure cyclical references never happen (CartManager references RetailManager, but never the other way). "Checkout" would be a method on the CartManager class, and it would call a method on the RetailManager to adjust inventory. While this will work, I'm not sure how well it will scale, and what the maintenance cost will be over time. It doesn't feel 100% "right" to me.
Create a Facade between the business components and the UI tier. In this example, the Facade would have the checkout method and a reference to both managers. I like this approach more than the first, however I know that not all of my business objects will need a Facade, and I don't want to create a ton of Facade classes just to have empty pass through methods.
I'm leaning towards 2, with the caveat that I will only create facade classes where needed. The UI tier will have access to both the Facade and the business layer components and will have to know when to use which (the only part I don't like about this solution).
I've done a lot of research but haven't been able to come to come up with a solution that feels completely right.
Any thoughts on using the facade pattern in this way, or other ideas to solve the problem are welcome.
Thanks in advance.
That's a typical problem for using manager/service classes. they always tend to get bloated. When you come to that point it's probably better to start using commands instead.
The great thing since you are using an IoC is that you doesn't have to refactor all the code directly, but can do it when there is time. Simply start writing commands for all new features while keeping the old architecture for everything else.
Here is a intro to commands: http://blog.gauffin.org/2012/10/writing-decoupled-and-scalable-applications-2/
And an intro to my own framework: http://blog.gauffin.org/2012/10/introducing-griffin-decoupled/
I would tend to go with facade implementation.
I would first ask myself, whose responsibility is it to make sure that inventory is reduced when a checkout happens? I don't think it is responsibility of CartManager to reduce the inventory. I would have a third class (in your case facade) that makes sure that whenever an item is checked out by CartManager, corresponding item is reduced from inventory.
Another option I would consider is event based implementation. CartManager would raise a ItemCheckedOut event whenever an item is checked out. RetailManager would subscribe to this event and would reduce the inventory whenever an event is raised. If you are new to event driven design, follow this question on quora - http://www.quora.com/What-are-some-good-resources-on-event-driven-software-design
I personally like the pattern of CQRS, it fits naturally with other architerural patterns
such as Event Sourcing and suited to complex domains.
I've recently been handed a code base which does a few things I'm a little different to how I usually do them.
The main difference is that it seems to pass elements (say for example a drop down list control) down to the business logic layer (in this case a separate project but still in the same solution) where the binding to business data takes place.
My natural approach is always to surface the information that is required up to the UI and bind there.
I'm struggling to match the first technique to any of the standard patterns but that may be down to the actual implementation less than the idea of what it is doing.
Has anyone ever encountered this type of architecture before? If so can you explain the advantages?
The solution is an ASP.Net website. Thanks.
Thanks,
I would make the case that this is a bad architecture, since the original developer tightly coupled the business logic to the presentation layer. If you wanted to switch from webforms to, say, MVC, you'd have to refactor chunks of your business layer, which shouldn't be the case!
If it's at all possible, you should consider moving away from developing the site in this fashion. In the interim, you can at least start the decoupling process by splitting the logic up a little bit further. If, say, you have a BindDropDown(DropDownList ddl) method, split the method apart, so you have a GetDropDownData() method that returns your actual business object, and BindDropDown only sets the values of the DropDownList. That way, at least, you'll be more easily able to move away from the tight coupling of the presentation layer and business layer in the future.
Of course, if the site is already designed like that (with a clear demarcation between the presentation layer, the intermediate "presentation binding" layer, and the business layer), I could see a case being made that it's acceptable. It doesn't sound like that's the case, however.
No, you should not pass UI elements to the Domain Model to bind / Populate.
Your domain model should ideally be able to be used with Windows Forms / WPF / Silverlight / ASP.NET / MVC you name it.
Now, I kinda understand the idea that your business objects should know how to store and render themselves etc it's the OO holy grail, but in practice this doesn't work well, as there often are dependencies (database middleware, UI components etc) with those functions, that you do not want in your BO assembly, it severely limits your reusablility.
Something that you can do though that gives your users the illusion of your BO knowing how to render itself is using extension classes (in a separate assembly, to contain the dependencies) something like...
public static class AddressUIExtensions
{
public static void DisplayAddress(this Address add, AddressControl control)
{
...
}
}
Then the API user can simply do
var ctrl = new AddressControl();
address.DisplayAddress(ctrl);
but you still have physical separation.
Has anyone ever encountered this type of architecture before?
If so can you explain the advantages?
The only advantage is speed of development - in the short-term; so it's well suited to simple apps, proof-of-concepts (PoC), etc.
Implementing proper abstraction usually takes time and brings complexity. Most of the time that is what you really want, but sometimes an app might be built as a simple throw-away PoC.
In such cases it isn't so much that a room full of people sit down and debate architectures for a couple of hours and arrive at the decision that binding in the BL makes sense - it's usually a "whatever-gets-it-done-fastest" call by the developers based on speed.
Granted, that simple laziness or ignorance will probably be the reason why it's used in other cases.
Your business layer should return a model - view model that the UI layer will in turn use to populate what it needs - period. There should be nothing sent to the business layer in terms of ui components - period. Its that simple and that hard and fast of a rule.
I am a asp.net developer and don't know much about patterns and architecture. I will very thankful if you can please guide me here.
In my web applications I use 4 layers.
Web site project (having web forms + code behind cs files, user controls + code behind cs files, master pages + code behind cs files)
CustomTypesLayer a class library (having custom types, enumerations, DTOs, constructors, get, set and validations)
BusinessLogicLayer a class library (having all business logic, rules and all calls to DAL functions)
DataAccessLayer a class library( having just classes communicating to database.)
-My user interface just calls BusinessLogicLayer. BusinessLogicLayer do proecessign in it self and for data it calls DataAccessLayer functions.
-Web forms do not calls directly DAL.
-CustomTypesLayer is shared by all layers.
Please guide me is this approach a pattern ? I though it may be MVC or MVP but pages have there code behind files as well which are confusing me.
If it is no pattern is it near to some pattern ?
That's not four layers, that's three layers, so it's a regular three tier architecture.
The CustomTypesLayer is not a layer at all. If it was, the user interface would only use the custom types layer and never talk to the business layer directly, and the data access layer would never use the custom types layer.
The three tier architecture is a Multitier architecture
As far as patterns go, I recommend getting to grips with these:
My biggets favourite by a mile is the Dependency Inversion Principle (DIP), also commonly known as (or at least very similar to) Inversion of control (IoC) ans Dependencey Injection; they are quite popular so you should have no problem finding out more info - getting examples. It's really good for abstracting out data access implementations behind interfaces.
Lazy Load is also useful. Interestingly, sometimes you actually might want to do the opposite - get all the data you need in one big bang.
Factory pattern is a very well known one - for good reason.
Facade pattern has also helped me keep out of trouble.
Wikipedia has a pretty good list of Software design patterns, assuming you haven't seen it yet.
A final thing to keep in mind is that there are three basic types of patterns (plus a fourth category for multi-threaded / concurrency); it can help just to know about these categories and to bear them in mind when you're doing something of that nature, they are:
Creational
Structural
Behavioral
Take a look at the Entity Framework or LinqToSQL. They can both generate your data access layer automatically from your database. This will save you a lot of (boring) work and allow you to concentrate on the interesting layers.
Code-behind does not really have anything to do with architecture - it is more of a coding style. It is a way of separating logic from presentation. Any architecture you mention can be used with or without code-behind.
You seem to be describing a standard three-tier architecture. MVC is a pattern than describes how your layers and the user interact. The user requests a page (represented by a View), which requests its data from the Controller. The Controller communicates with your business layer (Model) to extract the correct data and passes it to your View for display. If the View is interactive, for instance it allows the user to update something, then this user action action is passed back to your Controller, which would call the relevant method against the business layer to save the update to the database.
Hope this helps.