combined vs. separate backend calls - java

I try to figure out the best solution for a use case I'm working on. However, I'd appreciate getting some architectural advice from you guys.
I have a use case where the frontend should display a list of users assigned to a task and a list of users who are not assigned but able to be assigned to the same task.
I don't know what the better solution is:
have one backend call which collects both lists of users and sends them
back to the frontend within a new data class containing both lists.
have two backend calls which collect one of the two lists and send them
back separately.
The first solution's pro is the single backend call whereas the second solution's pro is the reusability of the separate methods in the backend.
Any advice on which solution to prefer and why?
Is there any pattern or standard I should get familiar with?

When I stumble across the requirement to get data from a server I start with doing just a single call for, more or less (depends on the problem domain), a single feature (which I would call your task-user-list).
This approach saves implementation complexity on the client's side and saves protocol overhead for transactions (TCP header, etc.).
If performance analysis shows that the call is too slow because it requests too much data (user experience suffers) then I would go with your 2nd solution.
Summed up I would start with 1st approach. Optimize (go with more complex solution) when it's necessary.

I'd prefer the two calls because of the reusability. Maybe one day you need add a third list of users for one case and then you'd need to change the method if you would only use one method. But then there may be other use cases which only required the two lists but not the three, so you would need to change code there as well. Also you would need to change all your testing methods. If your project gets bigger this makes your project hard to update or fix. Also all the modifications increase the chances of introducing new bugs as well.
Seeing the methods callable by the frontend of the backend like an interface helps.
In general an interface should be open for extension but closed on what the methods return and require. As otherwise a slight modification leads to various more modifications.

Related

Hardcoding Area, City, Country Strings

There can be potentially up to 1000 strings in total. Should these be hardcoded or stored in database? These are frequently accessed because everytime user wants to register or checkout an item, they are going to need to see list of area/suburb/province/countries.
If i have bunch of Enums, i think the performance should be fast because there is a max number of strings ~1-2k max.
On the other hand, if i store them in database, there's going to be latency accessing the database as well as cpu/memory consumption.
Which option do you choose?
1000 isn't a huge amount, and I would put this information into a text file and read them into the program on start-up.
Regardless, this is data, not code, and so should not be an enum (code). Why not enum? It's a lot easier and more flexible to update/change data than it is to change code, should this need to be changed in the future.
If you will definitely be updating and changing this information with time, especially if through multiple sources, then a database is surely the way to go.
It all depends on you. There is no proper convention. Below are 3 ways along with their pros and cons.
Create a class with static final string variables.
Pros:
a. Very easy to use.
b. Developers can do look ups from within IDEs.
Cons:
a. Every time you need to add/delete something, code will have to be recompiled. However, this will not be much problem if you have ci-cd in place.
Add everything in properties file and load at runtime.
Pros:
a. Modifying things will be a breeze. No code recompilation required.
Cons:
a. This would still need re-deployment and server restart.
b. Developers will be unhappy as they will have to refer the txt file every now and then. Also this could lead to mistake if developers use wrong codes which are not present in properties file.
Use database
Pros:
a. Highly configurable.
b. No need of re-deployment.
Cons:
a. Service restart will be required.
As you can see, service restart will be required for all of them as you will definitely going to use caching in case 2 and 3. My suggestion would be to use first option if they are literally never going to change as it is quite developer friendly.

Using Stream API for organising application pipeline

As far as I know Stream API is intended to be applied on collections. But I like the idea of them so much that I try to apply them when I can and when I shouldn't.
Originally my app had two threads communicating through BlockingQueue. First would populate new elements. Second make transformations on them and save on disk. Looked like a perfect stream oportunity for me at a time.
Code I ended up with:
Stream.generate().flatten().filter().forEach()
I'd like to put few maps in there but turns out I have to drag one additional field till forEach. So I either have to create meaningless class with two fields and obscure name or use AbstractMap.SimpleEntry to carry both fields through, which doesn't look like a great deal to me.
Anyway I'd rewritten my app and it even seems to work. However there are some caveats. As I have infinite stream 'the thing' can't be stopped. For now I'm starting it on daemon thread but this is not a solution. Business logic (like on connection loss/finding, this is probably not BL) looks alienated. Maybe I just need proxy for this.
On the other hand there is free laziness with queue population. One thread instead of two (not sure how good is this). Hopefully familiar pattern for other developers.
So my question is how viable is using of Stream API for application flow organising? Is there more underwather roks? If it's not recomended what are alternatives?

Designing a point system in Spring

I have a lot of existing data in my database already, and want to develop a points mechanism that computes a score for each user based on what actions they do.
I am implementing this functionality in a pluggable way, so that it is independent of the main logic, and relies on Spring events being sent around, once an entity gets modified.
The problem is what to do with the existing data. I do not want to start collecting points from now, but rather include all the data until now.
What is the most practical way to do this? Should I design my plugins in such a way as to provide for an index() method, which will force my system to fetch every single entity from the database, send an EntityDirtyEvent, to fire the points plugins, for each one, and then update it, to let points get saved next to each entity. That could result in a lot of overhead, right?
The simplest thing would be to create a complex stored procedure, and then make the index() call that stored procedure. That however, seems to me like a bad thing either. Since I will have to write the logic for computing the points in java anyway, why have it once again in SQL? Also, in general I am not a fan of splitting business logic into the different layers.
Has anyone done this before? Please help.
First let's distinguish between the implementation strategy and business rules.
Since you already have the data, consider obtaining results directly from the data. This forms the data domain model. Design the data model to store all your data. Then, create a set of queries, views and stored procedures to access and update the data.
Once you have those views, use a data access library such as Spring JDBC Template to fetch this data and represent them into java objects (lists, maps, persons, point-tables etc).
What you have completed thus far does not change much, irrespective of what happens in the upper layers of the system. This is called Model.
Then, develop a rule base or logic implementation which determines, under what inputs, user actions, data conditions or for all other conditions, what data is needed. In mathetical sense, this is like a matrix. In programming sense, this would be a set of logic statements. If this and this and this is true, then get this data, else get that data, etc. This encompasses the logic in your system. Hence it is called "Controller".
Do not move this logic into the queries/stored procedure/views.
Then finally develop a front-end or "console" for this. In the simplest case, develop a console input system, which takes a .. and displays a set of results. This is your "view" of the system.
You can eventually develop the view into a web application. The above command-line view can still be viable in the form of a Restful API server.
I think there is one problem here to be considered: as I understand there's huge data in the Database so the idea to create only one mechanism to calculate the point system could not be the best approach.
In fact if you don't want to start collecting points but include all the data, you must process and calculate the information you have now. Yes, the first time you will run this can result an overhead, but as you said, you need this data calculated.
By other hand you may include another mechanism that attends changes in an entity and launches a different process capable of calculate the new pointing diffence that applies to this particular modification.
So, you can use one Service responsible of calculate the pointing system, one for a single entity and another, may be longer to finish, capable of calculate the global points. Even, if you don't need to be calculated in real-time you can create a scheduled job responsible of launch it.
Finally, I know it's not a good approach to split the business logic in two layers (Db + Java) but sometimes is a requirement do it, for example, if you need to reply quickly to a request that finally works with a lot of registries. I've found some cases that there's no other option than add business logic to the database (as a stored procedures, etc) to manage a lot of data and return the final result to the browser client (ex: calculation process in one specific time).
You seem to be heading in the right direction. You know you want your "points" thing decoupled from the main application. Since it is implied you are already using hibernate (by the tag!), you can tap into the hibernate event system (see here section 14.2). Depending upon the size/complexity of your system, you can plugin your points calculations here (if it is not a large/complex system), or you can publish your own event to be picked up by whatever software is listening.
The point in either design approach is that neither knows or cares about your point calculations. If you are, as I am guessing, trying to create a fairly general purpose plugin mechanism, then you publish your own events to that system from this tie-in point. Then if you have no plug-ins on a given install/setup, then no one gets/processes the events. If you have multiple plug-ins on another install/setup, then they each can decide what processing they need to do based upon the event received. In the case of the "points plugin" it would calculate it's point value and store it. No stored proc required....
You're trying to accomplish "bootstrapping." The approach you choose should depend on how complicated the point calculations are. If stored procedures or plain update statements are the simplest solution, do that.
If the calculations are complicated, write a batch job that loads your existing data, probably orders it oldest first, and fires the events corresponding to that data as if they've just happened. The code which deals with an event should be exactly the same code that will deal with a future event, so you won't have to write any additional code other than the batch jobs themselves.
Since you're only going to run this thing once, go with the simplest solution, even if it is quick and dirty.
There are two different ways.
One is you already know that - poll the database for for changed data. In that case you are hitting the database when there may not be change and it may slow down your process.
Second approach - Whenever change happens in database, the database will fire the event. That you can to using CDC (Change Data Capture). It will minimize the overhead.
You can look for more options in Spring Integration

Multiple threads modifying a collection in Java?

The project I am working on requires a whole bunch of queries towards a database. In principle there are two types of queries I am using:
read from excel file, check for a couple of parameters and do a query for hits in the database. These hits are then registered as a series of custom classes. Any hit may (and most likely will) occur more than once so this part of the code checks and updates the occurrence in a custom list implementation that extends ArrayList.
for each hit found, do a detail query and parse the output, so that the classes created in (I) get detailed info.
I figured I would use multiple threads to optimize time-wise. However I can't really come up with a good way to solve the problem that occurs with the collection these items are stored in. To elaborate a little bit; throughout the execution objects are supposed to be modified by both (I) and (II).
I deliberately didn't c/p any code, as it would be big chunks of code to make any sense.. I hope it make some sense with the description above.
Thanks,
In Java 5 and above, you may either use CopyOnWriteArrayList or a synchronized wrapper around your list. In earlier Java versions, only the latter choice is available. The same is true if you absolutely want to stick to the custom ArrayList implementation you mention.
CopyOnWriteArrayList is feasible if the container is read much more often than written (changed), which seems to be true based on your explanation. Its atomic addIfAbsent() method may even help simplify your code.
[Update] On second thought, a map sounds more fitting to the use case you describe. So if changing from a list to e.g. a map is an option, you should consider ConcurrentHashMap. [/Update]
Changing the objects within the container does not affect the container itself, however you need to ensure that the objects themselves are thread-safe.
Just use the new java.util.concurrent packages.
Classes like ConcurrentLinkedQueue and ConcurrentHashMap are already there for you to use and are all thread-safe.

How to deal with monstrous Struts Actions?

I inherited this gigantic legacy Java web app using Struts 1.2.4. I have a specific question regarding Actions. Most of the pages have exactly one Action, and the processExecute() methods are hideous monsters (very long and tons of nested if statements based on request parameters).
Given that Actions are an implementation of the command pattern, I'm thinking to split these Actions into one Action per user gesture. This will be a large refactoring though, and I'm wondering:
Is this the right direction?
Is there an intermediate step I could take, a pattern that deals with the mess inside the monolithic actions? Maybe another command pattern inside the Action?
My way of dealing with this would be:
dont do 'everything at once'
whenever you change anything, leave it better than you found it
replacing conditionals with separate Action implementations is one step.
Better yet: Make your implementations separate from the Action classes so that you can use it when you change frameworks
Keep your new Command implementation absolutely without references to Struts, use your new Actions as Wrapper around these implementations.
You might need to provide interfaces to your Struts ActionForms in order to pass them around without copying all the data. On the other hand - you might want to pass around other objects than ActionForms that are usually a bunch of Strings (see your other question about Struts 1.2 ActionForms)
start migrating parts to newer & better technology. Struts 1.2 was great when it came out, but is definitely not what you want to support in eternity. There are some generations of better frameworks now.
There's definitely more - Sorry, I'm running out of time here...
Struts Actions, in my mind, shouldn't have very much code in them at all. They should just interact directly with the request and response - take some data from a form or a request parameter, hand that info off to the Service Layer, and then put some stuff in a Response object or maybe save some data in the user's session.
I'd recommend staying away from doing inheritance with action classes. It sounds like a good idea at first but I think sooner or later you realize that you're shoe-horning things more than you're actually making the code base robust. Struts has enough base actions as is, if you're creating new ones you've probably got code in the web layer that shouldn't be there.
That is just my personal experience.
I've dealt with this type of thing before. A good first step is to insert another base class into the inheritance chain between Action and one of the original monstrous action classes (lets call it ClassA). Especially if you don't have time to do everything at once. Then you can start pulling out pieces of functionality into smaller parallel Action classes (ClassB, ClassC). Anything that's common between the original ClassA and the new refactored classes can be pulled up into the new base class. So the hierarchy now looks like this:
Original Hierarchy: New Hierarchy:
Action Action
| |
| BaseA
(old)ClassA |
+--------+----------+
| | |
ClassB (new)ClassA ClassC
Go one method at a time
Record some test cases you can play back later. Example here (make sure to hit as many paths through the code as you can, i.e. all user gestures on the page that call this action)
refactor the method to reduce its complexity by creating smaller methods that do smaller things.
Re-run tests as you do this
At this point, you have refactored version of the big huge annoying method. Now you can actually start creating specific actions.
You can use your newly refactored class as a base class, and implement each specific action as a subclass using those refactored small methods.
Once you've done this, you should have a good picture of the logic shared between the classes and can pull-up or push-down those methods as needed.
It's not fun, but if you will be working on the codebase for a while, it will save you time and headaches.
Tough problem but typical of early web app development.
First things first you need to start thinking about which logic constitutes business behavior, which logic constitutes "flow" (i.e. what the user sees), and which logic gets the content for what he sees.
You don't have to go down the route of factories and interfaces and all that; retroactive implementation is far less useful... but consolidating business logic and data retrieval logic into delegates of some kind... and leaving the struts actions to determine page flow based on success/failure of that logic.
From there you just have to take a few weeks and grind it out
One long method is never good, unless it happens to be a single switch statement where the cases are very short (token parsing or something like that).
You could at least refactor the long method into smaller methods with descriptive names.
If at all possible you could start your method with recognizing what it is it should do by examining the form, and then if/else your way to the various options. No nested ifs though, those tend to make code unreadable. Just
enum Operation {
ADD, DELETE;
}
...
Operation operation = determineOperation(form);
if (operation == Operation.DELETE) {
doDelete(form);
} else if (operation == Operation.ADD) {
doAdd(form);
}
If you can go that far you have your logic nice and clean and you can do whatever refactoring you want.
The hard part is to get your logic clear, and you can do that in steps. Don't choose a pattern untill you understand exactly what your problem is.
If you're planning to refactor the code you should make sure to write tests for the existing code first so you can be sure you haven't altered the functionality of it once you start refactoring.

Categories