In a RIA application you are supposed to put as much business logic as possible outside of the RIA layers (flash/silverlight etc). What is the reason behind this? Any logic that goes into the presentation tier gets the benefit of executing faster...
Is this because the RIA technology will most likely need a face lift down the road and you will have to rewrite all the business logic?
I'm not sure I agree with your premise, that you're "supposed" to put business logic outside the client. You are supposed to move the business logic outside the UI layer, but there are typically still a couple client-side layers left before you hit the back-end web service. A typical Silverlight application, for instance, is based on the MVVM model, which prescribes a View that has no business logic, a ViewModel which has a pretty good chunk of validation and business logic, and a model, which has the rest. And all of that is on the client side.
On the other hand, you really need a business logic layer on the server as well. You can't rely on a client-side application to filter out all the bad data: someone might be running an old version of the client, or a different client entirely, or might be trying to hack your system.
In other words, ideally, you should have your business logic and validations executing on both the client and on the server: on the client, because you need responsiveness, and on the server, because you need security. The question is how to get this, and there aren't any perfect answers.
One approach commonly taken in Silverlight applications (I'm less familiar with Flash) is to use WCF RIA services, which allows you to create validations in one place that are executed on both the client and server. Even if you're not using the WCF RIA Services framework, you can still get much of the same effect by linking to the source code of your validation/business logic classes on both the client and on the web service -- it's more work, but still probably less work than writing your validations twice and keeping them in sync manually.
Business Logic is a cross-cutting concern.
Will your users be entering dates? If so, the interface needs to know they are dates to give them a picker, and to prevent invalid entries. Maybe even restrict entries to a range. That is business logic. How can you keep it out and still have a meaningful interface?
Will users be entering at any time a US State or a Province? If so, the drop-down list will have to be populated, and that means the UI "knows" about foreign keys.
Will there be fields the user can see but not change? Why or why not? That is business logic. Will there be limits to what certain users can do based on certain conditions? That is business logic.
This does not mean the UI knows about all business logic, of course, many data-moving operations have nothing to do with the UI.
But in the end the question is not how to keep BL out of the UI, you cannot do that, the question is which kinds of BL will be in the UI. That tends to come down to types, ranges of values, allowed operations, and so forth.
So either the UI gets all of that information from a lower tier, or some of it is reproduced in the UI layer.
So, one reason is maintainability. If the client is already distributed everywhere, you don't need to require a re-install or re-download when a simple business rule changes. Simply deploy the change to the back-end and you are all set.
It also lets you do things like hide your database behind your firewall. If all of your business logic is in the front-end, it is likely that you need to expose the database publicly so that the business logic can be executed on the client.
But I fear that "business logic" is an overloaded term. What is "business logic"? The right architecture is the architecture that makes most sense for your application and needs.
As #Ken Smith said, you should certainly avoid business logic in your UI layer. This is for testability, maintainability, designablity, etc. But this does not mean that everything goes to the back end, especially in a RIA app with significant UI rules. In an MVVM app (Silverlight) or Presentation Model app (Flex), you put UI BEHAVIOR in the ViewModel or PresentationModel layer. Then, you put whatever level of business logic makes sense in your Model. That business logic might just be some validation. It might be more. That is dependent upon your architecture.
Related
The business domain has five high-level bounded contexts
Customers
Applications
Documents
Decisions
Preforms
Further, these bounded contexts has sub-contexts like ordering and delivery of the documents. Despite the project of consisting ten of thousands of classes and dozens of EJB's, most of the business logic resides in relational database views and triggers for a reason: A lot of joins, unions and constraints involved in all business transactions. In other words, there is complex web of dependencies and constraints between the bounded contexts, which restricts the state transfers. In layman terms: the business rules are very complicated.
Now, if I were to split this monolith to database per service microservices architecture, bounded contexts being the suggested service boundaries, I will have to implement all the business logic with explicit API calls. I would end up with hundreds of API's implementing all these stupid little business rules. As the performance is main factor (we use a lot of effort to optimize the SQL as it is now), this is out of the question. Secondly, segregated API's would probably be nightmare to maintain in this web of ever evolving business rules, where as database triggers actually support the high cohesion and DRY mentality, enforcing the business rules transparently.
I came up with a conclusion microservice architecture being unsuitable for this type of document management system. Am I correct, or approaching the idea from wrong angle?
First of all, you don't have to have a Microservices architecture. I really mean it! If you were ordered by management/architect to do it, and it doesn't solve any real problems you are having, you are probably right for pushing back.
That being said, and with the disclaimer that I don't know the exact requirements of your application, having "things" as bounded context is a smell. So having "Customers", "Applications", "Documents", etc. as services is very likely the wrong approach.
Bounded contexts should not be CRUD operations on a specific entity. They should be completely independent (or as independent as possible) "vertical" parts of the whole application. Preferably with their own Database and GUI. They should also operate independently of each other, not requiring input from other services for own decisions.
It is the complete opposite of data-centric design, where tables/fields and relations are the core concepts. Here, functionality is the core concept. You would have to split your application along functionality to arrive at a good separation.
I could imagine a document management system having these idependent bounded contexts / services: Search, Workflow, Editing, etc.
Here is how you would think about it: Search does not require any (synchronous) input from any other service. It may receive regular, even near-time updates with new documents, but that does not impact it's main feature: searching already indexed documents. The GUI is also independent, something like one google-like page with a search box maybe. It can deliver results independently, and would link back to the Workflow or Editing apps when you click on a result.
The others would be similarly independent. Again, the point is to split the services in a way that makes them work independently. If you don't have that, you will only make things worse with Microservices.
First of all the above answer is correct in suggesting that you need to breaup your microservice in a better way.
Now If scalability is your concern(lots of api calls between microservice).
I strongly suggest you to validate that how many of the constraints are really required at the first level, and how many of them you could do in async way. With that what i mean is in distributed enviornment we actually do not need to validate all the things at the same time.
Sometimes these things are not directly visible , for eg: lets say there are two services order service and customer service and order service expose a api which say place a order for customer id. and business say you cannot place a order for a unknown customer
one implementation is from the order service you call the customer service in sync ---- in this case customer service down will impact your service, now lets question do we really need this.
Because a scenario could happen where customer just placed an order and somebody deleted that customer from customer service, now we have a order which dosen't belong to customer.Consistency cannot be guaranteed.
In the new sol. we are saying allow the order service to place the order without checking the customer id and do one of the following:
Using ProcessManager check the customer validity and update the status of the order as invalid and when customer get deleted using ProcessManager update the order status as invalid or perform business logic
Do not check at all , because placing a order dosen't count a thing, when this order will be in the process of dispatch that service will anyway check the customer status
In this way your API hits are reduced and better independent services are produced
I developing an application.
I read somewhere that database should not be accessed directly but there should be kind of layer and via it database should be accessed.
I don't know the exact reason.
It will be great if you can provide me some reasoning or links to follow.
Yes it is really a good practice to abstract/encapsulate your DB access logic from other part o. Data access layer should not be accessed directly or exposed to everyone. Meaning when you are designing an application, you must consider this important factor “Layered architecture” for example business layer, service layer, presentation layer and whatsoever. The work flow like service layer (if its web application) calls business layer and business layer calls data access layer. All this layers should be very abstracted to each other or it should be accessible only to the very immediate layer (so called clients).
Answer to your question: Let’s say your current data access implementation is based on plain JDBC/ODBC .After some time when your requirements grow; you are planning to implement it with some ORM framework. In this case it’s really easy to switch/migrate between different data access logic written in different APIs without affecting rest of your application and still other layers are not aware of your changes since your design is very abstracted in nature.
Bottom Line: Always work against abstracted interface rather against implementation.
Hope this is helpful and comments are appreciated
I had a talk with teamlead about this topic and from his point of view we can just use bindings and commandings omitting ViewModel, because we can test UI behaviour without VM using Automation or our own developed mechanisms of UI testing (based on automated clicks on Views). So, if there are no real benefits, why should I spawn "redundant" entities? Besides, automated integration tests look much more indicative than VM tests. So, it seems that we can mix VMs and Models.
update:
I agree that mixing VMs and Models brings into single .cs a data model and rules of data transformation for representing it in a View. But if this is only one benefit - I don't want to create a VM for each View.
So what pros of VM do you know?
The VM is the logic behind your UI. combining the UI code with the logic ends up in a mess, at least from my experience. Your view should define what you see - buttons, menus etc. Your VM is in charge of the binding and handling events caused by the user.
Edit:
Not wanting to create a VM for each view doesn't sound like a SW-oriented reason. Doing so will leave your view clean of logic and your model free to be the connecting layer between the core layer and your app layer.
I like the following example referring to the model and its role (why it shouldn't be combined with the VM): imagine you're developing some Android app using Google maps. Google maps are your core. Then one fine day you really need the option to, say, color parts of the map in pink, bright pink. An email to Google asking for colorPink(Map)will probably get you nowhere. That's where your model steps in and provides you the map wrapper that you need to define your pinky method.
Without a separate model, you'd have to go through every VM that uses map and update it.
So, the view has a role, the model has a role, the VM is the logic between those.
Edit 2:
There are some cases where there's no need of a model layer - I tended to disagree at first but was convinced after a discussion: In relatively small applications, the model can end up being a redundant wrapper with no added functionality over the core. In such cases, you can use the core objects directly.
What is he binding to? Whatever he is binding to is effectively a view model, whether you call it that or not. If it also doubles as a data model, then you're violating the Single Responsibility Principal (SRP). Essentially, the problem here is that you're lumping together code that is servicing different parts of the application architecture, which will lead to a convoluted mess.
UI Testing is a pain not just because you need to accomodate for changes in the View which can occur many times but also because UI tends to interfere with its own testing. Depending on the tests needed you'll need to keep track of focus, resize and possibly other (mouse) events which can be extremely hard to make it a representative test.
It is much easier to scope the test to the logic in the ViewModel and leave the UI testing to humans. The human testers do not need to test the logic; their only consern should be the UI.
By breaking down a ViewModel into a hierarchy of ViewModels you might be able to reuse a ViewModel multiple times. There is no rule that states that you should have a ViewModel for each View. (After a release or two I end up there but that's besides the point :) )
It depends on the nature of your Model - sometimes they are simple and can serve as both like you are suggesting. However, depending on the framework, you'll need to dirty up your model with some PropertyChanged event code which can get messy and distracting. In more complex cases, they serve as a mediator between your the view and the model. Let's suppose you're creating a client app that monitors a remote process or database entries - creating View Model's for these entities let's you surface your data in a way that is convenient to bind to for a UI framework (but is silly in a DB framework), encapsulate operations as commands, perform validation, etc etc.
I've been designing quite a few Windows Forms applications lately (data-entry apps, office integration, etc), and although I've always designed with logical tiers in mind, the "middle tier" business logic layer has always been hosted on the desktop PC (i.e. physical client-server).
As I approach more complex applications, I find myself yearning for a physical middle tier instead, with the desktop client passing requests back to an application server to process business logic (which may change regularly) and interfaces. It feels like I'm missing out on factors such as scalability and maintainability that are more native to Web apps.
I'm curious to know how far other WinForms developers have taken their middle-tier separation:
How much processing (if any) do you perform on a middle-tier server?
What communication method are you using - WCF, remoting, web services, etc?
How much is performance a factor, and how often do you roundtrip to the server?
Is there are a benefit in moving business logic onto a separate tier, or is it more practical to host components locally on a PC (and just make sure you have a good deployment model to push out regular releases as business rules change)?
Alternatively, should I be guiding customers away from WinForms completely if these factors are involved? With alternatives such as Silverlight and even ASP.NET w/ AJAX, the reasons to choose a WinForms client seem to be shrinking.
What is important to keep in mind is that there is a trade-off between the ease of development with a seperate middle tier vs all of the scalability benefits etc. What I mean by this is that you have to refresh interface mappings etc in your code, you have to deploy a middle tier somewhere for your testers to use, which needs to be refreshed etc. Furthermore, if you are lazy like me and pass your Entity Framework objects around directly, you cannot serialise them to a middle tier, so you then need to create DTO's for all of your operations etc.
Some of this overhead can be handled by a decent build system, but that also needs effort to set up and maintain.
My preferred tactic is to keep physical seperation in terms of assemblies (i.e. I have a seperate business logic / data access assembly) and to route all of the calls to the business layer through an interface layer, which is a bunch of Facade classes. So all of these assemblies reside within my windows app. I also create interfaces for all of these facades, and access them through a factory.
That way, should I ever need the separation of a middle tier, and the trade-off in terms of productivity is worth it, I can separate my business layer out, put it behind a WCF service (as that is my preferred service platform) and perform some refactorings in terms of what my facades hand out, and what they do with what they accept.
This is one example of why I tend to always do work in a web environment. If the network is available to your client application for service calls, it's certainly available to send and retrieve data from a web server.
Certainly, client restrictions can alter your final path, but when given the chance to influence the direction, I steer towards web-based solutions. There are deployment technologies available that give you an easier upgrade path than a traditional desktop package, but there's no real substitute for updating a server-based application.
Depending on your application, there are several performance issues to keep in mind.
If your work is very similar between various clients (shared data), then doing the processing on a middle tier is better because you can make use of caching to cut down on the overall processing.
If your is different between clients (private data), then you won't have much gain by doing the processing at a middle tier.
I'm a newbie and when messing around with creating database applications I always just created my forms and put all the code and bindings in there. Instead of having arrays and lists that held information I made changes to the database directly.
Now that I have evolved a little bit let's say that I sold widgets to customers and kept the sales information in a database. If I were writing a program to access the database wouldn't I want to create a class of type 'Customer' and 'Widget' to work with those entities?
If I'm mistaken then what is the appropriate approach to programming database applications?
Yes.
You want to look into n-tier programming.
Basically, you allow you front end (presentation layer) access only to your class library (business layer). Your class library then accesses you database.
This gives you a less tightly coupled solution, and allows for more maintainable code. Also by introducing tiers you allow for changes to your DB without the need to rewrite code in your frontend, as long as the interface with the Business Layer doesn't need to be changed.
As far as binding is concerned, if you are using Visual Studio Windows Forms (2005 onwards) you should be able to us an bindingSource that you can then use to bind your controls. If you are using ASP.NET then your control should bind to a list of objects without any problems.
For ASP.Net the ObjectDataSource might be worth looking into. I haven't used it myself, but there's lots of samples on the web. Try here or here.
Yes.
You want to look closely at Object-Relational Mapping.
Your real-world business entities are modeled by objects which map to relational tables.
You do not want your presentation layer to directly depend on your database structure; the problem with that is if your database structure changes at all, your presentation layer must change, and in the long term, that tends to cause problems. Moreover, there are security issues involved with having your presentation layer directly interact with your database.
The rough analogy here is to markets; when you go to the store to buy a loaf of bread, you don't need to know how to grow wheat; all you need to know is that you have money, and they have bread, and that they will exchange a certain amount of bread for a certain amount of money. You don't need to know what time of year to plant the wheat, or how to remove the chaff, or any of that, because the backing layer takes care of that for you. Similarly, the farmer doesn't need to know how to sell bread to a whole bunch of people, or even how to make bread; all he has to do is know how to grow wheat.
Modern design philosophy recommends that you use an intermediate layer to interact between your presentation layer and your database layer; this is where you put your business logic. So, for example, let's say that you're selling widgets on your site. Instead of having your presentation code query the database for widgets and display that, you have a Business Object which handles your widgets. This way, your business object needs to know what your database structure is, but your presentation layer only needs to know how to ask your business object for a list of widgets to display. More importantly, in your business object you can place the rules that are to be invoked when certain things happen. So instead of your presentation layer directly making changes to the database for inventory and orders when an order is made, your business object knows how to make the changes and what tables to modify when your presentation layer requests that a sale occurs.
In this way, you separate the display of your information from the persistence and the logic underlying the website. What is involved is good planning; specifically, you have to figure out what your web site will be doing at any given point, and what that means in terms of what interfaces your business objects will provide. Then you implement your business objects based off of those requirements; those business objects are where you put the knowledge of the database structure and your specific business logic ("when A happens, do B and then C", etc.).
This seems like a lot of extra work at the beginning, but it really is worth it.