Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 1 year ago.
Improve this question
I need to do some "bytecode hacking" to inject something into a POJO without adding a "visible" property.
Consider this code:
public class Entity {
private Multimap<String, Entity> linkMap;
public void setLink(String linkName, Entity entity) {
if(linkMap == null) {
linkMap = HashMultimap.create();
}
boolean isSet = false;
entity = byteCodeHack(entity, false);
linkMap.put(linkName, entity);
}
public void addLink(String linkName, Entity entity) {
if(linkMap == null) {
linkMap = HashMultimap.create();
}
boolean isSet = true;
entity = byteCodeHack(entity, isSet);
linkMap.put(linkName, entity);
}
}
Where there are two types of link, one is "set" and one is "not set (or multi)" and there's no way to determinate if the "link" is a "set" or "not set" even if the Multimap contains only one entry for a given link name, it does not mean that it is a "set" it could be an "addLink" which is just one. The point here is the underlying database can link objects one-to-one (set) or one-to-many (add). And the stage that will process this Entity needs to know from the Multimap which database operation to do, "set" or "add" -- but as mentioned that can't be inferred by just iterating over the Multimap.
So my strategy is to inject a value into the entity before inserting it to the Multimap, the byteCodeHack method.
What would be the best way to implement this?
An alternative solution without class enhancing is to add an additional method to set the Multimap in such as way when it is "set" it will first remove all the other elements existing, then another method "add" to just add causing to have multiple similar keys:
public void addLink(String linkName, Entity entity) {
linkMap.put(linkName, entity);
}
public void setLink(String linkName, Entity entity) {
Collection<Entity> oldValues = linkMap.get(linkName);
if(Objects.nonNull(oldValues)) {
linkMap.remove(linkName, oldValues);
}
linkMap.put(linkName, entity);
}
If class enhancing is really required, it can be done through https://bytebuddy.net/#/ library.
Related
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 2 years ago.
Improve this question
public class Student {
public Student(String name){
do_smth(name);
}
public Student(){
this("Mike");
}
}
How force developers to use parameterized constructor only if value differs from default:
not calling new Student("Mike") but use for this new Student()?
The reason: we have constructor with 5 parameters. In most cases parameters are the same. But there are about 5%-10% cases when they differ.
So in order to avoid duplications, I would like to use such approach.
I know it maybe better to use smth like Builder pattern here. But I don't like it verbosity.
This may be implemented by using additional private constructor with a flag:
public class Student {
public Student(String name) {
this(name, false);
}
public Student() {
this("Mike", true);
}
private Student(String name, boolean defaultUsed) {
if (!defaultUsed && "Mike".equals(name)) {
throw new IllegalArgumentException(
"Tut-tut lil kid, it's pwohibited to set Mike's name outside defauwt constwuctor");
}
do_smth(name); // only if do_smth cannot be overridden in child classes
}
}
Note: method do_smth should be private or final so that it could not be overloaded in subclasses which is far more important than setting a limit on setting a name from specific constructor.
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 2 years ago.
Improve this question
I have a Feeder class that contains a method that feed data into a list, given data, the list and a custom class :
default void feedData(CustomData myData, List list, Class c){
ObjectMapper objectMapper = new ObjectMapper();
if(myData!= null) {
for (Map<String, Object> map : myData.getData()) {
list.add(objectMapper.convertValue(map, c));
}
}
}
I want to implement a design pattern because I have several classes that can should feed data regarding specific classes.
I thought about Factory pattern, is that a good idea?
Class 1 would be like:
public void feed(CustomData myData){
feedData(myData, myField, CustomClass1.class);
}
Class 2 :
public void feed(CustomData myData){
feedData(myData, myField2, CustomClass2.class);
}
etc.
And then, an interface for example IFeeder where I declare
void feed(CustomData myData);
But where can I put the feedData method? Inside this interface?
If yes, I should declare it as default, but default keyword is for a default method that return always the same result, isn't it?
Thanks for any advice.
public static <T> void feedData(CustomData myData, List<T> list, Class<T> clazz){
ObjectMapper objectMapper = new ObjectMapper();
if(myData!= null) {
for (Map<String, Object> map : myData.getData()) {
list.add(objectMapper.convertValue(map, clazz));
}
}
}
I believe this should work. This can be a static method in some util class.
I am assuming that all the other classes that you are referring can implement a common interface.
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 5 years ago.
Improve this question
The following is less a question than a request for evaluation.
So you will most likely be familiar with the following pattern of a lazy getter.
private Object obj;
public Object getObject() {
if(obj==null) {
obj = new Object();
}
return obj;
}
That code
is long
requires a class variable
requires some logic inside the getter
So recently a colleague and I came up with the following interface (simplified):
public interface LazyGetterSupport {
default Object get(Supplier<Object> impl) {
String key = impl.getClass().getName();
Object retVal;
if ((retVal = getInstanceCache().get(key)) == null) {
retVal = impl.get();
getInstanceCache().put(key, retVal);
}
return retVal;
}
Map<String, Object> getInstanceCache();
}
Sidenote: Not using HashMap#computeIfAbsent bc of Bug-8071667
That Interface is then implemented by the class that you want to use lazy getters in. You need to provide an implementation of getInstanceCache() as follows:
private Map<String, Object> instanceCache;
#Override
public Map<String, Object> getInstanceCache() {
if (instanceCache == null) {
instanceCache = new HashMap<>();
}
return instanceCache;
}
But given that you can start rewriting all other lazy getters in that class (and subclasses) like this:
public Object getObject() {
return get(Objetct::new);
}
This works because the key we get by using impl.getClass().getName(); inside our Interface will actually always be unique for every lambda we use inside implementations of its get-method. Yet it will stay the same for each call-site for at least the life duration of our VM.
Benefits are obvious. We no longer have to create a class-variable for every lazy-getter and the getter themselves become shorter. It may not be a world of a difference, but in our use-case we often have classes with 20+ Lazy Getters for UI Elements. That is where this new technique comes to shine.
I would love to know your thoughts on this approach and whether you have any concerns towards using this in production.
Or you could simply use #Getter(lazy=true) from Project Lombok.
Your cache is per class which doesn't feel future proof to me. If you had some generic Supplier that was used multiple times then using the Class as the cache key wouldn't work. I'd just store a reference on a LazyValue which you can use and cache however you like. Here's a thread safe implementation:
public class LazyValue<T> {
private AtomicReference<T> reference = new AtomicReference<>();
private final Supplier<T> supplier;
public LazyValue(Supplier supplier) { this.supplier = supplier; }
public T get() {
T t = reference.get();
if (t == null) {
synchronized (reference) {
t = reference.get();
if (t == null) {
t = supplier.get();
reference.set(t);
}
}
}
return t;
}
}
public class MyBean {
private LazyValue<Object> lazyObject = new LazyValue(Object::new);
public Object getObject() {
return lazyObject.get();
}
}
Looks interesting, but you replaced a bunch of member variables with a Hashmap. While this works, it increases the memory usage of your class, and adds O(1) overhead to member access. Synchronizing the lazy getter method is not enough, you need to synchronize on the HashMap, adding keys concurrently will break something. In the traditional lazy getter, synchronizing on the one attribute is enough. Here, if you concurrently access different attributes they have to wait on each other.
And in your use case, I really wonder why one would need lazy getters for UI elements.
Object o;
public Object getInstance() {
return o == null ? (o = new Object()) : o;
}
No need for a fancy HashMap, just convert "long" 4 lines of code into 1.
You could also allow the client to actually set a property.
interface LazyGetterSupport<T> {
T get();
static <T> LazyGetterSupport<T> of(T value, Supplier<T> create, Consumer<T> store) {
T result = value;
if (result == null) {
result = create.get();
store.accept(result);
}
return result;
}
}
which you could call using
class Client {
Object field;
void getField() {
LazyGetterSupport.of(field, Object::new, o -> field = o).get();
}
}
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 6 years ago.
Improve this question
So the similar type of questions are answered elsewhere but here I am expecting the best way to omit if else chain for the given situation.
CURRENT CODE
private ViewModel getViewModel(Receipt receipt) {
String receiptType = receipt.type;
if(receiptType.equals("HOTEL")) {
return new HotelReceiptViewModel(receipt));
} else if(receiptType.equals("CAR")) {
return new CarReceiptViewModel(receipt));
}
.
.
.
} else if(receiptType.equals("LUNCH")) {
return new FoodReceiptViewModel(receipt));
}
}
where all the view models extend a class called ReceiptViewModel. e.g.
public class HotelReceiptViewModel extends ReceiptViewModel implements ViewModel {
public HotelReceiptViewModel(Receipt receipt) {
super(receipt);
this.receiptNumber = receipt.getDocumentNumber();
this.receiptHeading = "HOTEL";
}
}
There are currently 5 types of receipts and there will be 3-4 more types of receipts in future.
POSSIBLE SOLUTIONS
Use of HashMap
Use of Enum
Use Strategy Pattern or Command Pattern
Use of Reflection
Let's see pros and cons of each approach
1. Use of HashMap
private ReceiptViewModel getViewModel(Receipt receipt) {
Map<String, ReceiptViewModel> map = getViewModelsMap();
String receiptType = receipt.type;
ReceiptViewModel viewModel = map.get(receiptType);
if(viewModel != null) {
viewModel.setReceipt(receipt);
}
return viewModel;
}
private Map<String, ReceiptViewModel> getViewModelsMap() {
Map<String, ReceiptViewModel> map = new HashMap<String, ReceiptViewModel>();
map.add("HOTEL"), new HotelReceiptViewModel());
map.add("CAR"), new CarReceiptViewModel());
map.add("LUNCH"), new FoodReceiptViewModel());
}
and ReceiptViewModel classes will look like
public class HotelReceiptViewModel extends ReceiptViewModel implements ViewModel {
public HotelReceiptViewModel(Receipt receipt) {
super(receipt);
this.receiptNumber = receipt.getDocumentNumber();
this.receiptHeading = "HOTEL";
}
}
PROS
Faster, Easier, Extensible.
CONS
ReceiptViewModel object does not require an object of Receipt type in the constructor. Receipt is rather set using a setter, where all the logic of initializing the ReceiptViewModel class will move now.
2. Use of Enum
private ReceiptViewModel getViewModel(Receipt receipt) {
String receiptType = receipt.type;
ReceiptViewModel viewModel =
ReceiptViewModels.valueOf(receiptType).getReceiptViewModel(receipt);
return viewModel;
}
And Enum will look like
public enum ReceiptViewModels {
HOTEL(
ReceiptViewModel getReceiptViewModel(Receipt receipt) {
return new HotelReceiptViewModel(receipt);
}
),
CAR(
ReceiptViewModel getReceiptViewModel(Receipt receipt) {
return new CarReceiptViewModel(receipt);
}
),
.
.
.
LUNCH(
ReceiptViewModel getReceiptViewModel(Receipt receipt) {
return new FoodReceiptViewModel(receipt);
}
),
public abstract ReceiptViewModel getReceiptViewModel(Receipt receipt);
}
PROS
Fast, Probably Easy.
CONS
Size of Enum will keep on increasing as the receipt types increase, resulting in non-maintainable code.
ReceiptViewModels.valueOf(receiptType) expects a known receipt type. If a new receipt type comes as a response from server, it will result in an IllegalArgumentException
3. Use of Reflection
Class<? extends ReceiptViewModel> viewModel = Class.
forName(receiptType + name + "ReceiptViewModel").asSubclass(ReceiptViewModel.class);
ReceiptViewModel receiptViewModel = viewModel .newInstance();
CONS
1. Slower
Cannot be used when the class names are different. e.g. For LUNCH type the view model class name is FoodReceiptViewModel
Logic of getting values from receipt is moved to a setter instead of constructor as in case of HashMap
4. Use of Strategy Pattern or Template Pattern
PROS Easy to understand and faster than Reflection
CONS Probably an overkill. A new class will be added for each type of receipt.
Considering all the above points, which would be the best approach for my use case to remove the multiple if-else blocks?
I would use a switch, unless there is a reason to use something more complex.
private ViewModel getViewModel(Receipt receipt) {
switch(receipt.type) {
case "HOTEL": return new HotelReceiptViewModel(receipt);
case "CAR": return new CarReceiptViewModel(receipt);
case "LUNCH": return new FoodReceiptViewModel(receipt);
default:
throw new IllegalArgumentException("Unknown receipt type " + receipt.type);
}
I would claim this is the best solution as it is the simplest which meets you needs.
No behavior needed, no structure needed, no polymorphism needed, so I don't see interest to use design patterns such as strategy or to use a map which brings nothing but complexity in the need you describe.
You want a very simple state machine. So, "if else if" or "switch" is perfect .
Maybe out of the subject but with a private method, the code is not unitary testable.
I would make a new abstract method into your Receipt class. Something like
public <T extends ReceiptViewModel> T createModel()
And then would create subclasses of the Receipt class where each type would correspond to one subclass. Then each subclass will implement his own version of createModel returning the correct subclass of ReceiptViewModel. Your initial code will be as simple as
private ViewModel getViewModel(Receipt receipt) {
return receipt.createModel()
}
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 4 years ago.
Improve this question
I have a class called GoogleWeather, I want to convert it to another class CustomWeather.
Is there any design pattern which helps you to convert classes?
In that case I'd use a Mapper class with a bunch of static methods:
public final class Mapper {
public static GoogleWeather from(CustomWeather customWeather) {
GoogleWeather weather = new GoogleWeather();
// set the properties based on customWeather
return weather;
}
public static CustomWeather from(GoogleWeather googleWeather) {
CustomWeather weather = new CustomWeather();
// set the properties based on googleWeather
return weather;
}
}
So you don't have dependencies between the classes.
Sample usage:
CustomWeather weather = Mapper.from(getGoogleWeather());
There is one critical decision to make:
Do you need the object that is generated by the conversion to reflect future changes to the source object?
If you do not need such functionality, then the simplest approach is to use a utility class with static methods that create a new object based on the fields of the source object, as mentioned in other answers.
On the other hand, if you need the converted object to reflect changes to the source object, you would probably need something along the lines of the Adapter design pattern:
public class GoogleWeather {
...
public int getTemperatureCelcius() {
...
}
...
}
public interface CustomWeather {
...
public int getTemperatureKelvin();
...
}
public class GoogleWeatherAdapter implements CustomWeather {
private GoogleWeather weather;
...
public int getTemperatureKelvin() {
return this.weather.getTemperatureCelcius() + 273;
}
...
}
Besides, You can also use new Java8 feature 'Function' from java.util.function'.
More detailed explanation is provided in http://www.leveluplunch.com/java/tutorials/016-transform-object-class-into-another-type-java8/ . Kindly have a look!