Implementing new feature using SOLID principles in old code - java

I just try to get more into SOLID principles but get stuck by implementing new structures in my old (not SOLID) code.
I have this Room.Class
public class Room {
private String roomCode;
private String roomDescription;
// getter/setter
}
Now I need to have a translation for the roomDescription. I started to create an interface
public interface ITranslation {
String findTranslation();
}
and an implementation
public class RoomDescriptionTranslation implements ITranslation {
#Override
public String findTranslation() {
return "translated Room";
}
In the already existing code there is a service class which creates some Rooms with codes and descriptions. These Rooms are also used in the view (as jsp bean).
The new requirement is to have the translated description on the view.
So for me the question is where I should implement the logic of translation of the existing Rooms.
Should I implement it in the existing serivce class where the Rooms are created?
Or should RoomDescriptionTranslation be a field inside Room?
Or should I created a new service class where just the description gets translated?
Just need a pointer to go to the right direction.

It could be first or third option, but not the second option in my opinion. I think one important question, in general for designing any class is this:
For a property p and class C, is p a property of C?
So, in your case the question becomes: is translation a property of Room? Semantically, it sounds that it is not.
Then, you can ask the same question on Room Service class. The answer to that depends on how you defined your service class. Again, another rule that helps to decide whether a property belongs to a class, is this:
What is one singe word or phrase that describes this class?
This goes to the very idea of what a class is in OOP and also to S in SOLID. Once, you ask this question and can describe one single purpose for your class, then you can go back and ask the first question, whether certain property belongs to this class or not.
Now, if your service class is such that, "Handle all room related actions" (not saying this is right, but if this is the case) then you can add one more action to it, namely translation. But, if it is not then you may create a new service, translation.
Considering all this, I lean more towards having a new translation service as it looks
Something independent
Will be easily extendible (compared to other option) like adding more languages
Does not require changing existing code
Again, there might be other factors affecting the whole thing.

I would create a model TranslatedRoom extends Room to use only in view this L from SOLID and inside this new model would take care about translations.
Of course if it is possible to refactor service which creates model for views etc.
One more thing (maybe it is S from SOLID) this idea is good if we need to show translated room only in this/these views.

If you want to translate text you should use internationalization solutions which already exist in java.
In your solution you'll create painful maintenance problems and every string which you'll return will be surrounded by if.

Related

What Java design pattern fits the scenario of adding a user to multiple systems based on csv values?

I am working on a project where I need to add users to multiple systems (active directory, a database, & Sisense) based on data received from a spreadsheet. I've coded can get the data input correctly into each system, but I am struggling to figure out how to organize my code, in terms of what design pattern to use.
I have a model class for each component that contains the field each system needs:
ActiveDirectoryUser
SisenseUser
DatabaseUser
Then, I have what I call the worker class for each of these that actually does creates the user in the system.
ActiveDirectoryWorker
SisenseWorker
DatabaseWorker
The basic flow of my code is
Read in each line from the spreadsheet
Validate the input is valid.
Create a instance of each model class that contains the appropriate fields.
Call the individual worker classes that control how the user get added to the respective system. The model instance will be passed into this class.
I've read up on some of the various design patterns, but none of the explanations are in "plain" English. Still learning the ropes here a bit, so I'd appreciate someone suggesting a model that fits my scenario.
It sounds as though you've defined three distinct data models, one for each storage. That makes your job more difficult than it has to be. Instead, consider modelling data based on data in the spreadsheet. You could, for instance, define a class called SpreadsheetUser, which contains the valid data from a spreadsheet row.
Now define an interface, e.g. UserCreator:
interface UserCreator
{
void Create(SpreadsheetUser user);
}
Now loop through each row in your spreadsheet, validate the data and then call Create on a Composite, which could be defined like this:
class CompositeUserCreator : UserCreator
{
UserCreator[] creators;
CompositeUserCreator(params UserCreator[] creators)
{
this.creators = creators;
}
public void Create(SpreadsheetUser user)
{
foreach (creator in creators)
creator.Create(user);
}
}
You also define three concrete implementations of UserCreator, one for each storage system, and create the composite like this:
CompositeUserCreator creator =
new CompositeUserCreator(
new ActiveDirectoryUserCreator(/* perhaps some config values here... */),
new SisenseUserCreator(/* ... and here... */),
new DatabaseUserCreator(/* ... and here... */));
You'll still have the problem of dealing with failures. What should happen if you've already created a user in active directory, but then Sisense creation fails? That is, however, not a problem introduced by the Composite pattern, but a problem which is inherent in distributed computing.

Determining Subclasses Types with Attribute

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.

Where is the correct place to put find functions?

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.

Which design pattern should be used?

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

Java best practice library creation for flexible class creation (Factory Pattern, abstraction, and interfaces)

Imagine I am a Java software developer for a car manufacturer. I have been tasked with creating a library that will be used by numerous in-house applications. For each type of car model manufactured, I create a java object representing that model. I must be able to track not only current models, but prototype models. The prototype models will have one name that is very likely to change once it goes into production. I need to be able to use the library to account for the prototypes and flex with the name change when they are switched into production.
My question is, what is the best approach for this?
Here are my thoughts...
I have been reading several books for ideas as to best handle this situation. Immediately my mind jumps to using a factory pattern. I would have a CarModelFactory class which would return a concrete object for each model. For example:
public class CarModelFactory() {
public CarModel createCivicModel() {}
public CarModel createAccordModel() {}
public CarModel createPrototype1() {
return new ModelX();
}
public CarModel createPrototype1() {
return new ModelY();
}
Would this be the best approach? I feel like there should be another layer of abstraction. Problems I see are:
1) What if ModelX goes into production, I create a method for it and put something else in createPrototype1 method, now programs that call that method get the wrong object
2) How do I handle ModelX changing its name?
I thank you for your time!
The factory model sounds good, but I would suggest a createCarModel(String model) method, which looks up in a map the appropriate object. Then renaming a car model is a simple add/remove in that map. With appropriate synchronization, of course, to prevent a rename and a get from colliding.
The map would likely be Map<String, Class<? extends CarModel>>, and the createCar method would instantiate the class using a no-argument constructor, which you would require of all Cars.
This way, there is no recompile necessary any time you add or rename a model, as the factory class does not change its set of method signatures.
Additionally, if you override the ClassLoader, you can unload an old model and load up a new model, allowing the actual directory containing your .class files to be kept clean (no old prototype classes that have since been made into real models).

Categories

Resources