I have a class with some calculation login in backend:
public class MyDomainClass{
private Double amount;
private Double total;
public Double getPercentage(){
/*business logic*/
}
}
My frontend is in angular 2+ and I want to show this information in 2 ways.
In a table with a list of them provided by the server:
And in a edition form, with the percentage calculation based on user input:
To make this calculation in the form I have to duplicate the logic in a frontend domain class too? I'm afraid to duplicate business logic and lost control of the code with more complex problems with this same idea (Some logic in backend for reports and list and the same logic in frontend forms).
How can I avoid that?
P.S: I use Jax-rs in the backend.
You need to be pragmatic about these things. Front-ends need to ensure that the user experience is acceptable at the very least and at times there may be duplication of functionality to keep the UX smooth and reasonable.
Another example may be validations. Front-end validation is necessary even if your domain has to perform those same validations. The domain is the source of truth and all invariants have to be implemented there. Duplicating certain bits of functionality, within reason, on the front-end is acceptable if it improves the user experience.
Simple calculations, as the one you have used as an example, is something that I wouldn't even worry about. The same with adding up costs to display totals and the like. Your domain may be doing the same but the intent is different.
If there is any "heavy lifting" to be done then rather make a call to your web-api and have your back-end handle that.
Related
With organizations which are slow to adapt to modern technology finally junking EJBs and getting ready to transform to SpringBoot, Microservices, REST, Angular, there are some some questions application design. One being about TransferObjects and Business Objects
When the call comes to the REST Controller, is it still popular to populate a TO (POJO) and then make Service call, which in turn populates a BusinessObject and then calls a Repository service?
OR
At the REST Controller layer do we directly populate the BO and send it to the Service (This does not make any sense to me, because a BO is populated only during the execution business logic).
If nowadays its still Option 1, then how do we avoid writing to exactly similar POJO classes in most cases (in order to use BeanUtils.copyProperties()), with the BO decorated with #Id, #Column etc.
To elaborate on #Turing85's comments...
Option 1 usually (see the end of my answer) makes infinitely more sense. It's a question of responsibility (purpose) and change; the two logical components you refer to, a REST API and a repository / system service:
Responsibility: a REST service cares about working with its callers, so ideally when designing a REST API you should be involving someone from the client-side (client as in caller), because if the API doesn't work for them it's not going to be an effective API. On the other hand, repositories are somewhat self-centered, and may need to consider things that are or no interest to API callers (and vis-versa).
Change: if you pay attention to design principles, like SOLID, you'll know that part of a system should do one job - as a way of limiting the reasons why it needs to change (see: SRP). Trying to use one object across both outward-facing API's, and inward-facing repositories, is asking for trouble because it's trying to do too much - its trying to help solve problems in two very different parts of the wider solution, and thee both have very different change drivers working against them. Turning85's comment about the persistence layer stems from the same idea.
"Option 1 usually makes infinitely more sense":
One case where the REST API's objects will / can bear a very close resemblance to those that hit the actual repository (or even be reused, I guess) is when the REST API is a System API - i.e. a dedicated façade / proxy to the repository. In this case, the System API is largely driven by the repository i.e. the main change driver is just the repository.
After researching a bit I agree, keeping things simple will result in simpler code. I found a nice simple way to take care of this manual work.
https://www.baeldung.com/entity-to-and-from-dto-for-a-java-spring-application
I'm working on a Java project involving two classes. One is the Driver of the project and the other holds the actual functionality of the program. The driver is going to collect input from the user and the values will be used to create an instance of the other class. The other class has constraints on what the data can be (ie. one value needs to be below a certain number) and I was wondering when I should validate that the input meets those requirements. In general is input validation something each class being instantiated worries about or is it something the class collecting the data is supposed to do.
Thanks in advance.
As with anything, "it depends".
Let's not think about the whole application, and instead think of the individual components. For now we'll call them ApplicationHost and BusinessLogic.
The BusinessLogic component should be fully functional, in and of itself, and usable by any application. So if there are assumptions or requirements that it has about its inputs, it needs to enforce those. For example, if you're setting an int value and that value must be positive, then the setter should enforce that. Something as simple as this:
public void setSomeValue(int someValue) {
if (someValue <= 0) {
throw new NumberFormatException("Some Value must be a positive value.");
}
this.someValue = someValue;
}
The idea being that it is the responsibility of BusinessLogic to enforce this constraint. Any consuming code which attempts to use BusinessLogic while violating this constraint would get an error. BusinessLogic itself simply advertises what its constraints are and requires that they be followed. It doesn't care much about user experience, only about system state. If the state is invalid, fail fast and loudly.
So then should ApplicationHost also have this same constraint? The question you're probably asking is, should that same exact if statement be duplicated in ApplicationHost?
It depends.
Keep in mind that "code duplication" is not a measure of identical keystrokes. It is a measure of identical intents and responsibilities. ApplicationHost has no responsibility to maintain the business logic. It might, however, have a responsibility to provide a good user experience. And in doing so it has a couple of options:
Send input directly to the business logic, catch and handle any exception, show a friendly error to the user.
Validate input on its own before even invoking the business logic, interacting directly with the user to drive that input first and only when it's valid actually perform the business operation.
The first option means less code, the application layer is mostly a pass-through to the business layer. However, it also means that in cases where there may be multiple input constraint violations then only the first encountered one would generate an error. Remaining violations wouldn't be caught until each one is corrected individually.
The second option means "duplicating" code. However, it also tends to produce a much better user experience with less "back and forth" between the application layer and the business layer. (Imagine a form on a website where you had 5 errors, and had to submit and correct the form 5 times because it could only tell you one error at a time.)
Which is better? It depends on what you're doing in the application and the desired overall experience. There is no universal rule.
But how can code duplication be a good thing? Well, it isn't. Not inherently. In many cases, this isn't a problem. In fact, you may find that in many cases the validation logic in the two separate layers isn't actually the exact same logic. They are validating for different purposes, and depending on how much of a pass-through layer vs. translation layer the application is over the business logic, they may even be validating different "shapes" of the data.
If, however, they are resulting in essentially identical validation logic. Then you may be able to extract from that a third "responsibility" which can be moved to its own class. A BusinessLogicInputValidator if you will. This can live inside the business logic layer, perhaps even inside the BusinessLogic object in simple enough cases. And it would expose the same operations used by both BusinessLogic and ApplicationHost.
In this case the code which performs the validation would be centralized, and the code which consumes that validation logic would be duplicated. Which is ok, since code which consumes logic isn't itself an element of logic and isn't really subject to the same "code duplication" fears.
Starting a new GWT application and wondering if I can get some advice from someones experience.
I have a need for a lot of server-side functionality through RPC services...but I am wondering where to draw the line.
I can make a service for every little call or I can make fewer services which handle more operations.
Let's say I have Customer, Vendor and Administration services. I could make 3 services or a service for each function in each category.
I noticed that much of the service implementation does not provide compile-time help and at times troublesome to get going, but it provides good modularity. When I have a larger service, I don't have the modularity as I described, but I don't have to the service creation issues and reduce the entries in my web.xml file.
Is there a resource issue with using a lot of services? What is the best practice to determine what level of granularity to use?
in my opinion, you should make a rpc service for "logical" things.
in your example:
one for customer, another for vendors and a third one for admin
in that way, you keep several services grouped by meaning, and you will have a few lines to maintain in the web.xml file ( and this is a good news :-)
More seriously, rpc services are usually wrappers to call database stuff, so, you even could make a single 'MagicBlackBoxRpc' with a single web.xml entry and thousands of operations !
but making a separate rpc for admin operations, like you suggest, seems a good thing.
Read general advice on "how big should a class be?", which is available in any decent software engineering book.
In my opinion:
One class = One Subject (ie. group of functions or behaviours that are related)
A class should not deal with more than one subject. For example:
Class PersonDao -> Subject: interface between the DB and Java code.
It WILL NOT:
- cache Person instances
- update fields automatically (for example, update the field 'lastModified')
- find the database
Why?
Because for all these other things, there will be other classes doing it! Respectively:
- a cache around the PersonDao is concerned with the efficient storage of information to avoid hitting the DB more often than necessary
- the Service class which uses the DAO is responsible for modifying anything that needs to be modified automagically.
- To find the database is responsibility of the DataSource (usually part of a framework like Spring) and your Dao should NOT be worried about that. It's not part of its subject.
TDD is the answer
The need for this kind of separation becomes really clear when you do TDD (Test-Driven Development). Try to do TDD on bad code where a single class does all sorts of things! You can't even get started with one unit test! So this is my final hint: use TDD and that will tell you how big a class should be.
I think the thing to optimize for is that you can accomplish a result in one round trip to the server. I have an ad-hoc collection of methods on my service object, one for each situation the client finds itself in when it has to get something done. You do not want the client to RPC to the server several times in a row while the user is sitting there waiting.
REST makes things orthogonal, but orthogonality has a cost: there is a reason that the frequently used verbs in languages are irregular. In terms of maintaing clean orthogonal structure to your app, make sure your schema is well-designed. That is where each class should have semantics orthogonal to that of the other classes. When the semantics of each RPC call can be stated cleanly in the schema there will be no confusion as to what they mean, even if they aren't REST-fully ideal.
I'm tinkering with Play! java framework and trying to understand MVC.
Consider this scenario: A blogging app has moderators and users, and both can update posts. Moderators' updates are immediately saved. Users' updates are queued to be approved by a moderator. In MVC, where do we put the logic to determine whether to update or queue the updates?
One way to do it is in the Controller (pseudo-code):
public void function update() {
User user = User.find("byEmail");
if ( user.isModerator() ) {
post.update( args );
}
else {
// save post in a temporary table where it awaits approval.
}
}
Am I right in using this approach or are there better alternatives?
I know that this is quite an old question, but I had the same - so this might be of help:
In my current project, the policy is to layer the authorisation checks. This way, the checks will be done where they fit best:
if it is important for consistancy of the data, checks are done in the model (very rare cases, needs to be set in the API documentation!).
most checks are done at controller level, so most checks are in a single place.
some checks are done in the "View" (this means they controll the JSON output of an API, and this in turn changes behaviour in the front end). These are quite rare, as these are mostly based on data fed from the controller and not querying the user's permissions directly.
I came up with that solution after reading this post. It provides a good summary on why using the controller is a good idea - and what the alternatives are.
The main reason, why I chose the controller as a place for authorisation checks is that it allows the model (and the data it manages) to be independent of application logic - which includes authorisation.
Please keep in mind, that this is totally dependent on what you want to achieve. I just wanted to show what works for me.
Say, You have an application which lists down users in your application. Ideally, if you were writing code to achieve this in Java, irrespective of what your UI layer is, I would think that you would write code which retrieves result set from the database and maps it to your application object. So, in this scenario, you are looking at your ORM / Data layer doing its thing and creating a list of "User" objects.
Let's assume that your User object looks as follows:
public class User {
private String userName;
private int userid;
}
You can now use this list of "User" objects, in any UI. (Swing / Webapp).
Now, imagine a scenario, where you have to list down the userName and a count of say, departments or whatever and this is a very specific screen in a webapp. So you are looking a object structure like this:
public class UserViewBean {
private String userName;
private int countDepartments;
}
The easiest way of doing this is writing SQL for retrieving department count along with user name in one query. If I you to write such a query, where would you have this query? In your jsp? But, if you were doing this in a MVC framework, would you move this query to your data layer, get the result set, convert it to UserViewBean and send it to your jsp in request scope? If you write queries directly into jsps/if you are making use of connections directly in JSP, isn't that a bad practice?
I know, some of you might say, 'hey, you got your object composition wrong! if department is linked to user, you would want to create a list of departments in your User object' - Yes, I agree. But, think of this scenario - Say, I don't need this department count information anywhere else in my application other than this one screen. Are you saying that whereever I load my User object from the database, I would have to load a list of dependency objects, even if I won't be using them? How long will your object graph get with all the relational integrity? Yes, I do know that you have ORMs for this very reason, so that you get benefits of lazy loading and stuff, but I dont have the privilage to use one.
The bottom line question here is:
Would you write sqls in to your JSP if it serves just one screen? OR
Would you compose an anemic object
that caters to your view and make
your business layer return this
object for this screen - just to make
it look a bit OOish? OR
irrespective of what your screen
demands, would you compose your
objects such that an object graph
is loaded and you would get the
size of that list?
What is the best practice here?
I would never put SQL in a JSP. I would use Spring MVC or Struts controllers, or servlets to contain all of that type of logic. It allows for better error handling among other things (you can forward to error pages when queries fail).
If you really must do this, use the JSTL SQL tags.
Personally, I take a simple pragmatic approach. If I was writing screen that just displays a list of users with their deparment count, so that the entire code is maybe a page, and I don't expect this code to be used on any other screen, I'd probably just throw it all in the JSP. Yes, I know there are all the MVC purists who will say, "business logic should never go in a JSP". But aside from a dogmatic rule, why not? What would it hurt in a case like this?
If I found that I had two screens, maybe one where I had to simply display the list and another where I had to do some additional processing on the list, then I would certainly pull the common code out into a class that was called from both places.
I believe that the criteria should be: What produces the most maintainable code? What is shortest and easiest to understand? What produces the least linkages between modules? etc.
I adamantly refuse to accept the principle: "In some cases this approach leads to problems, therefore never use it." If sometimes it leads to problems, then don't use it in the cases where it leads to problems. Or worse, "Somebody wrote it in a book, therefore it cannot be questioned." Sure, there are some rules that are valid 99.99% of the time, so it gets to be pointless to check if this particular case is an exception. But there are lots of rules that are good 51% of the time and people leap from "mostly" to "always".
Would you write sqls in to your JSP if it serves just one screen?
In a prototype, just as a quick hack - maybe. In any other situation, not to mention a production environment - NEVER.
Use a proper MVC framework to separate business logic from presentation.
I am not even sure that JSP should be used, but for trivial applications. If you really have to use them, use MVC pattern or encapsulate your logic in a JavaBean.
Have a look at JPA which allow you to do object manipulations which then is persisted in the database
I wouldn't put SQL in a jsp for fear of forgetting it in future maintenance. Think of the poor guy maintaining your code-- poor guy = you in 10 months or whenever the database is restructured-- and at least put all SQL in the same general region.