I have multiple databases of users that I have to search on. The user can have multiple instances and the app checks if the user is a duplicate across the different databases.
So each user is associated with a client, and the fields are populated differently based on what client it is. (I know it's not right, but this is inherited application) My thought would be to refactor it by adding the client as a parameter into the getUserData method. However i'm realizing this is a change preventer smell. There are many wrapper methods that will pass in default values. i also have to traverse the call hiearchy far back enough that I would have access to the client object to pass in. This may be for or five method calls, so I would have to change those as well. At this point, the way the app was developed(by other developers) is very rigid when it comes to this, and I am looking to improve it.
The getUserData method:
public User getUserData(String userId, boolean fullUserRecord, Date userStartDate){
//retrive userdata from db
//attach client specific data for user
}
Example of a wrapper method:
public User getUserData(String userId, Date userStartDate){
getUserData(userId, false, userStartDate)
}
My question would be, how do I best handle this. Currently i am going down the rabbit hole of changing the method signature, but if this needs to change again, I would have to do the same thing, which won't be fun.
The wrapper methods serve no purpose whatsoever.
Introduce a parameter object and inline the wrapper methods where possible.
"Introduce parameter object" refactoring:
http://refactoring.com/catalog/introduceParameterObject.html
https://sourcemaking.com/refactoring/introduce-parameter-object
Related
I have the following class hierarchy
Promotion - abstract
- Coupon
- Sales
- Deals
(Coupons, Sales and Deals are all subclasses of Promotion).
and would like to determine the type of the object when exchanging data between the REST APIs (JSON) and the Client (Angular). Users can submit a Coupon or a Deal or a Sale. For instance when a coupon is sent from the client, I want to be able to know that this is coupon so that i can call the correct method.
To solve this problem I have declared a variable and an abstract method in Promotion.
protected String promotionType = getPromotionType();
protected abstract String getPromotionType();
In the subclasses for instance in Coupon I have something like this
protected String getPromotionType() {
return "coupon"
// OR return this.getClass().getSimpleName().toLowerCase();
}
This will automatically initialize the promotionType variable so that in the Controllers I can check if the object is Coupon or Sales or Deal. Remember that JSON send data in String formats so I must I have a way to determine the type of object coming.
In this case I will have a single controller to handle all my CRUD operations. In my controller method I will do something like::
#PostMapping public void create(#RequestBody Promotion){
// And inside here I will check the type of **promotionType**
}
Here am using Promotion as argument instead of any of the subclasses in the create() method.
My question is, is it the best way to solve this?
Or do I have to create a separate Controller for each of the subclass? I am looking for the best way to do it in the real world.
I am using Hibernate for my mappings.
My question is, is it the best way to solve this?
Answers to this question will always be opinion-based, especially, as we don't know about your entire application, not only technically but business-wise, and how the client-code consumes and displays the code.
Or do i have to create a separate Controller for each of the subclass?
No, not necessarily. If the code is and would probably stay simple - sometime you can anticipate this - it doesn't make sense to inflate the code. Having three Controllers instead of a single PromotionController will very likely increase redundant code. Otherwise, if the subclasseses are rather heterogeneous, three Controllers could be more advisable.
Another thought, you might have a (human) client that manages only the Deals and that client has special requirements leading to a bunch of customized rest interfaces only for the Deal, you'd probably like to have a separate Controller.
I am looking for the best way to do it in the real world.
There is no best way. Five developers have probably five opinions on how to solve this. And even if one is more reasonable for the time being, it may change on the next day due to or changed new business requirements.
The best way is to discuss this in the team, create a common sense and if unsure, let the lead architect decide which way to go. Imo, your approach seems quite ok. That's my 2 cents.
I have defined a class which acts like a model/pojo. The class has many keys/variable. I have implemented custom solution for storing the POJO on disk for future uses. Now what I want to do is that whenever any value in the class/POJO is changed, I should call a method which sync the fresh changes with file on disk.
I know I can define setter for each variable. But it's quite tedious to do for 100s of direct and sub fields, and even if I define setter for each field, I have to call sync function from all the setters.
What I need is single proxy setter or interceptor for all change pushes to variables in class.
I am using this in an android application, so whenever the user enters new details in his/her account I have to store those details at that specific instance of time for preventing the data loss. I am using GSON for serialising and de-serialising.
Sorry for using vague terminologies, never been to college :|.
The easiest solution is indeed to use a setter. You only have to create one for each field you want to monitor, and most IDEs generate them for you or you can use something like Koloboke, so it being tedious isn't really an argument.
A proxy class or reflection would also be possible, but that is pretty hacky. Another way would be an asynchronous watcher/worker that checks for changes in you POJO instances, but even that seems unnecessarily complicated.
Apart from that you might need to rethink your POJOs structure if it has that many fields.
The problem with persisting(in your case writting to a disk) entity on each property update is that most of the updates are modifying more then one property. So in case you have a code like this:
entity.setA(avalue);
entity.setb(bvalue);
entity.setc(cvalue);
You would write it to the disk 3 times, which is probably not a best way, as it takes more resources, and 2 out of 3 writes are unnecessary.
There are several ways to deal with it. Imagine you have some service for saving this data to a disk, lets name it entityRepository. So one option is manually call this entityRepository each time you want to save/update your entity. It seems to be very uncomfortable, comparing to calling this automatically on setter call, however, this approach clearly shows you when and why your entity is persisted/updated, in your approach it's unclear, and can lead to some problems future problems and mistakes, for example, in future you will decide that you now need to update one of the properties without immideately persisting, then it appears that you will need 2 setter, one with update, and one without...
Another way is to add version property, and when its setter is called inside this setter call entityRepository.save(this).
The other way is to look at AOP, however anyway I don't recommend persist entity on any change, without having control over it.
You are talking about data binding. There is no built-in way for that so you have indeed to sync it yourself. Look into How to Write a Property Change Listener. There are also lots of other approaches to this, but as said no built-in way.
I'm learning AOP and am comfortable with Pointcuts, Advices etc.
What am going to ask, am pretty sure is not possible, but want to ask anyways.
I have a method which takes a userId, fetches the user's record from a database and then does something to the record. I have like twenty different methods that do different things, but all of them take the userId as input and fetch the record from database. This to me looks like a cross cutting concern that can be pulled into an aspect.
But how? I know I can access the arguments (userId in this case), access the return value of the method and catch the methods exception. But how do I give the method something to work with (record in the database in this case?)
public String printUserDetails(String userId)
{
Record record = Database.fetchRecord(userId);
System.out.println(record.getDetails());
return record.getTitle();
}
So, is there a way to pull that database accessing code into an aspect?
One way I can think of is declare something like the following for input
class RequestObject
{
String userId;
Record record;
}
and inject the record in the Aspect and then call proceed(). But this somehow feels wrong.
IMO, resolving a user, using the userid, is not a cross-cutting concern and hence aspect is not the right way. The first landing page that receives a userId should actually resolve it to UserRecord and from then on, the userRecord should be the one moving around in the application.
A simple analogy I can draw to your scenario from one of my applications is, all authenticated servlets expect the servletRequest.getRemoteUser() to return the valid user login corresponding to the user sending the request. We decorated the HttpServletRequest to resolve this to a User object in our application and all the authenticated servlets downcast the HttpServletRequest to AuthenticatedServletRequest and extract this object. No one else within the application tries to resolve a user login anymore.
You cannot access a method's local variables from AspectJ if this is what you wanted to know.
The rest of the question is rather about design and the answer dependent on what you want to achieve. You can avoid code duplication in multiple methods using a template method design pattern. You can inject real or mock objects into classes if you refactor them to have a member instead of local variables. It is another question if you create the member by directly refactoring your classes or via AspectJ's (ITD)[http://www.eclipse.org/aspectj/doc/next/progguide/starting-aspectj.html#inter-type-declarations] mechanism. A third question would be if you possibly want to use an aspect for caching in order to avoid fetching the same object from the database multiple times.
I am not sure what exactly you want to achieve, so I cannot answer more specifically.
Say I want to implement a work place. There are objects of class Employee and there is also a class WorkArrangement, which is like a box into which the employees submit their desired shifts for the next week. (The manager then empties the box and uses this information to arrange shifts for the next week).
The problem is, that the code in the class Employee doesn't know the object box (of class WorkArrangement), so I can't write a method which says "put your next week shifts in the box". I can send the box object as a parameter to the constructor of Employee, but it looks like a bad design in the sense of OOP.
So, is it a bad design?
If it is, then what is a possible solution?
Sounds more like there's a Box (could just be a list) that takes Shifts, and an Employee has multiple collections of Shifts, desiredShifts and actualShifts.
The Manager then looks at each employee's desired shifts, juggles everything around, and assigns actual shifts to each employee, and/or puts them in a shared structure for use in a company calendar.
IMHO, I would use event-driven logic (e.g. using property change listeners). Once an Employee instance is ready to submit the desired shifts, fire off an event (e.g. PropertyChangeEvent). And in this event object, pass the shift information and other relevant information. From there, the receiver (i.e. WorkArrangement) can do what it pleases with such information (e.g. firing off another change event that notifies the Manager that is has received shift information).
A straightforward approach would be for WorkArrangement to have a method where the Employee submits requests. e.g.
public void requestShift(Employee employee, Shift requestedShift);
This way Employeee doesn't know how or what WorkArrangement does with the requests (they may get thrown into the trash for all you know!) but it knows how to sumbit a request. You might need an argument for which week it is, but I'd prefer that already be in WorkArrangement, e.g. every week you construct a new WorkArrangement() for that week. Later on, Employee could find out what they got via a call:
public Shift getActualShift(Employee employee);
BTW, this guides us to a better name than "WorkArrangement", which doesn't really mean a whole lot: something like "WeeklySchedule". Not all class names can be simple and clear, but when one of the first classes you design has a fuzzy name, that's a sign that you are not on the right track.
If you really don't want WeeklySchedule to know what an Employee is, note that the argument is really just used as an identifier, on which you will use equals() (and probably hashCode()) at some point. So that argument could be an Object, an integer or String employeeID, etc...
I'm looking for something similar to the Proxy pattern or the Dynamic Proxy Classes, only that I don't want to intercept method calls before they are invoked on the real object, but rather I'd like to intercept properties that are being changed. I'd like the proxy to be able to represent multiple objects with different sets of properties. Something like the Proxy class in Action Script 3 would be fine.
Here's what I want to achieve in general:
I have a thread running with an object that manages a list of values (numbers, strings, objects) which were handed over by other threads in the program, so the class can take care of creating regular persistent snapshots on disk for the purpose of checkpointing the application. This persistor object manages a "dirty" flag that signifies whether the list of values has changed since the last checkpoint and needs to lock the list while it's busy writing it to disk.
The persistor and the other components identify a particular item via a common name, so that when recovering from a crash, the other components can first check if the persistor has their latest copy saved and continue working where they left off.
During normal operation, in order to work with the objects they handed over to the persistor, I want them to receive a reference to a proxy object that looks as if it were the original one, but whenever they change some value on it, the persistor notices and acts accordingly, for example by marking the item or the list as dirty before actually setting the real value.
Edit: Alternatively, are there generic setters (like in PHP 5) in Java, that is, a method that gets called if a property doesn't exist? Or is there a type of object that I can add properties to at runtime?
If with "properties" you mean JavaBean properties, i.e. represented bay a getter and/or a setter method, then you can use a dynamic proxy to intercept the set method.
If you mean instance variables, then no can do - not on the Java level. Perhaps something could be done by manipulations on the byte code level though.
Actually, the easiest way to do it is probably by using AspectJ and defining a set() pointcut (which will intercept the field access on the byte code level).
The design pattern you are looking for is: Differential Execution. I do believe.
How does differential execution work?
Is a question I answered that deals with this.
However, may I suggest that you use a callback instead? You will have to read about this, but the general idea is that you can implement interfaces (often called listeners) that active upon "something interesting" happening. Such as having a data structure be changed.
Obligitory links:
Wiki Differential execution
Wiki Callback
Alright, here is the answer as I see it. Differential Execution is O(N) time. This is really reasonable, but if that doesn't work for ya Callbacks will. Callbacks basically work by passing a method by parameter to your class that is changing the array. This method will take the value changed and the location of the item, pass it back by parameter to the "storage class" and change the value approipriately. So, yes, you have to back each change with a method call.
I realize now this is not what you want. What it appears that you want is a way that you can supply some kind of listener on each variable in an array that would be called when that item is changed. The listener would then change the corresponding array in your "backup" to refect this change.
Natively I can't think of a way to do this. You can, of course, create your own listeners and events, using an interface. This is basically the same idea as the callbacks, though nicer to look at.
Then there is reflection... Java has reflection, and I am positive you can write something using it to do this. However, reflection is notoriously slow. Not to mention a pain to code (in my opinion).
Hope that helps...
I don't want to intercept method calls before they are invoked on the real object, but
rather I'd like to intercept properties that are being changed
So in fact, the objects you want to monitor are no convenient beans but a resurgence of C structs. The only way that comes to my mind to do that is with the Field Access call in JVMTI.
I wanted to do the same thing myself. My solution was to use dynamic proxy wrappers using Javassist. I would generate a class that implements the same interface as the class of my target object, wrap my proxy class around original class, and delegate all method calls on proxy to the original, except setters which would also fire the PropertyChangeEvent.
Anyway I posted the full explanation and the code on my blog here:
http://clockwork-fig.blogspot.com/2010/11/javabean-property-change-listener-with.html