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.
Related
I'm working on a project that is split into several smaller Java Projects. I have this Account object that stores user credentials, etc. I want to create a function to return all characters that account has, e.g. findCharacters(); Where should I put that, inside an API or in the Account class itself?
It is better place that function inside Account class as it is related functionality to Account object.
public class Account {
//properties go here
int findCharacters() {
//method logic goes here
}
}
Since this is Java, I recommend using its Object Oriented nature and capabilities. Oracle has a decent tutorial on Java and OOP. Here are some references to get you started:
https://docs.oracle.com/javase/tutorial/java/concepts/
http://people.ucls.uchicago.edu/~bfranke/apcs_0809/downloads/BPJ_TextBook_3_0_5.pdf
Just go for the function: findCharacters() inside the Account class.
As the comments say: it depends.
From a pure OO point of view, the first place to look for would be the Account class itself.
But the important thing is: the Account should follow the SOLID principles - namely: single responsibility! Therefore one has to be careful to only have those methods inside a class that contribute to that single responsibility. In other words: you want to avoid adding all kinds of methods on a specific class - just because that method is mainly using objects of that class.
Domain Driven Design gives a hint what to do when the method "doesn't fit" into the "domain object": you turn to special service classes to wrap around that "service like" functionality.
Which model to pick/follow depends on the context of your application.
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
I have a some functionality implemented to store documents inside a data base.
Now, I want to access the functionality in my module but not directly.
As I have the FileInputStream with me and the functionality implemented accepts JSON string.
So, which design pattern could be used to bridge the gap in input parameters?
I know Adapter is one of the answers but can anyone suggest anything else?
Below is the sample of the functionality.
public interface DocumentService {
public String create(String jsonRequest);
public String search(String jsonRequest);
public String update(String jsonRequest);
public String fetch(String jsonRequest);
}
To elucidate my comments:
Trying to wedge every bit of functionality into an explicit "pattern" isn't a productive use of your time.
Even if it is, trying to find the perfect "name" for what you actually come up with isn't.
You need a helper class that converts an FIS into JSON, and that's about it.
You could compose a service that uses that helper and your existing class, or...
Compose your existing class into the FIS => JSON converter, or...
Modify your data flow so that you pass the data through a filter that JSONifies it, or...
In other words, (a) the "best" answer depends on your very specific situation, and (b) it doesn't matter what it's called. Do something, put it somewhere half-way reasonable, and if it ends up not being exactly right, iterate until it is. Don't waste time trying to name the "pattern".
It's like throws and joint locks: don't look for them, find them. The patterns are hidden in your application, surface them and implement.
Just make a private converting method
String toJSON(FileInputStream fs) {
...
}
If you happen to need that method in multiple locations move it into a utility class.
If that single method is not flexible enough for every situation you need it in right now then you should consider writing an adapter class.
The desire to design a perfect, flawless architecture for every functionality is natural in many programmers. It poses the risk of paralyzing the actual objective, which is to deliver a working product.
The important thing about good design is not that it fulfills every possible use case that may arise in the future, but that it is easy to understand and easy to change should that use case actually arrive.
Looks like Adapter is a good choice. I will move forward.
Why don't you use the DAO pattern?
Pass the input stream to the DAO object and make it convert it from the file input stream to JSON and call the create methods.
http://www.tutorialspoint.com/design_pattern/data_access_object_pattern.htm
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.
My original question was quite incorrect, I have classes (not POJO), which have shortcut methods for business logic classes, to give the consumer of my API the ability to use it like:
Connector connector = new ConnectorImpl();
Entity entity = new Entity(connector);
entity.createProperty("propertyName", propertyValue);
entity.close;
Instead of:
Connector connector = new ConnectorImpl();
Entity entity = new Entity();
connector.createEntityProperty(entity, "propertyName", propertyValue);
connector.closeEntity(entity);
Is it good practice to create such shortcut methods?
Old question
At the moment I am developing a small framework and have a pretty nice separation of the business logic in different classes (connectors, authentication tokens, etc.), but one thing is still bothers me. I have methods which manipulates with POJOs, like this:
public class BuisnessLogicImpl implements BusinessLogic{
public void closeEntity(Entity entity) {
// Business Logic
}
}
And POJO entities which also have a close method:
public class Entity {
public void close(){
businessLogic.closeEntity(this);
}
}
Is it good practice to provide two ways to do the same thing? Or better, just remove all "proxy" methods from POJOs for clarity sake?
You should remove the methods from the "POJOs"... They aren't really POJO's if you encapsulate functionality like this. The reason for this comes from SOA design principles which basically says you want loose coupling between the different layers of your application.
If you are familiar with Inversion of control containers, like Google_Guice or Spring Framework-- this separation is a requirement. For instance, let's say you have a CreditCard POJO and a CreditCardProcessor service, and a DebugCreditCardProcess service that doesn't actually charge the CC money (for testing).
#Inject
private CardProcessor processor;
...
CreditCard card = new CreditCard(...params...);
processor.process(card);
In my example, I am relying on an IoC container to provide me with a CardProcessor. Whether this is the debug one, or the real one... I don't really care and neither does the CreditCard object. The one that is provided is decided by your application configuration.
If you had coupling between the processor and credit card where I could say card.process(), you would always have to pass in the processor in the card constructor. CreditCards can be used for other things besides processing however. Perhaps you just want to load a CreditCard from the database and get the expiration date... It shouldn't need a processor to do this simple operation.
You may argue: "The credit card could get the processor from a static factory". While true, singletons are widely regarded as an anti-pattern requiring keeping a global state in your application.
Keeping your business logic separate from your data model is always a good thing to do to reduce the coupling required. Loose coupling makes testing easier, and it makes your code easier to read.
I do not see your case as "two methods", because the logic of the implementation is kept in bussinessLogic. It would be akin of asking if it is a good idea java.lang.System has both a method getProperties() and a getProperty(String), more than a different method is just a shortcut to the same method.
But, in general, no, it is not good practice. Mainly because:
a) if the way to do that thing changes in the future, you need to remember that you have to touch two implementations.
b) when reading your code, other programmers will wonder if there are two methods because they are different.
Also, it does not fit very well with assigning responsabilities to a specific class for a given task, which is one of the tenets of OOP.
Of course, all absolute rules may have a special case where some considerations (mainly performance) may suggest breaking the rule. Think if you win something by doing so and document it heavily.