Which design pattern to use in order to implement "data extenders"? - java

This is what I'm trying to do:
public class DataBuilder {
public DataBlock create() {
DataBlock block = new DataBlock();
for (Extender extender : this.getExtenders()) {
extender.extend(block);
}
}
}
Some time later:
DataBlock block = new DataBuilder().create();
Every extender will add some specific information to the block. DataBuilder doesn't want to know anything about internal structure of these extenders. Currently my getExtenders() method finds all subclasses of Extender (in classpath), and returns instances of them.
Works fine, but I don't like how it looks, in terms of design. Maybe I could/should use some pattern, to make this construct more flexible?

Continuing Adrian's answer, I'll explain briefly how it would work:
Lets suppose DataBlock derives from an interface called IDataBlock. Each extender derives from DataBlockDecorator which derives from IDataBlock which does some operation to the DataBlock (accepting IDataBlock in the constructor). This allows you to do something like.
IDataBlock block = new DataBlock();
for (DataBlockDecorator extender : this.getExtenders()) {
extender.extend(block);
block = extender;
}
However, it doesn't really add anymore flexibility than before. For that matter, your original solution is already as flexible as it gets.

Have a look at the Decorator pattern.

Decorator Pattern
interface BlockDeckorator
{
extend(DataBlock block);
}
class FooBlockDecoratorImpl implements BlockDecorator
{
private BlockDeckorator blockDecorator;
public FooBlockDecoratorImpl(BlockDecorator decorator)
{
this.blockDecorator = decorator;
}
public void extend(DataBlock block)
{
blockDecorator(block);
// Add my own code to do Foo afterwards (or before)
}
}

Related

Is a Java object with hundreds of methods expensive?

I have a class like below, with hundreds of methods:
public class APIMethods {
public ToView toView;
public APIMethods(ToView toView) {
this.toView = toView;
}
public static final int SUCCESS = 1;
public static final int ERROR = 0;
public void registerAnonymous(String deviceId, String installRef, final int requestCode) {
APIInterface apiService =
RetrofitClientInstance.getRetrofitInstance().create(APIInterface.class);
JsonObject obj = new JsonObject();
obj.addProperty("androidId", deviceId);
obj.addProperty("projectId", 0);
obj.addProperty("ChannelName", installRef);
Call<Response<BasicUser>> call = apiService.registerAnonymous("application/json", Utils.getFlavorId(), obj);
call.enqueue(new Callback<Response<BasicUser>>() {
#Override
public void onResponse(Call<Response<BasicUser>> call, Response<Response<BasicUser>> response) {
Response<BasicUser> mResponse;
try {
mResponse = response.body();
if (mResponse.getErrorCode() == 0)
toView.updateView(requestCode, SUCCESS, mResponse);
else
toView.updateView(requestCode, ERROR, mResponse);
} catch (Exception e) {
mResponse = new Response<>();
mResponse.setErrorCode(-1);
toView.updateView(requestCode, ERROR, mResponse);
e.printStackTrace();
}
}
#Override
public void onFailure(Call<PetMarkResponse<BasicUser>> call, Throwable t) {
Response<BasicUser> numberValidationResponse = new Response<BasicUser>();
numberValidationResponse.setErrorCode(-1);
toView.updateView(requestCode, ERROR, numberValidationResponse);
}
});
}
///And dozens of such method
}
So in my other classes everywhere in my application, I simply instantiate the class and call the method that I want:
APIMethods api = new APIMethods(this);
api.registerAnonymous(Utils.getAndroidId(this), BuildConfig.FLAVOR, STATE_REGISTER_ANONYMOUS);
My question is how expensive this object (api) is? Note that in each class, a few methods of the object are called.
The object is not expensive at all.
An object contains a pointer to the object's class, and the methods are stored with the class. Essentially, the methods are all shared. An object of a class with no methods and an object of a class with 10000 methods are the same size (assuming everything else is equal).
The situation would be different if you had 100 fields instead of 100 methods.
You may want to think about if having hundreds of methods in a single class is a good idea. Is the code easy to understand and maintain? Is this an example of the "God object" anti pattern? https://en.m.wikipedia.org/wiki/God_object
This seems like a classic example of the XY problem. Your actual problem is how to make the code readable, but you're actually asking about whether a class with hundreds of methods is expensive.
It being expensive is the least of your concerns - you should be more worried about maintenance. There's no reason at all that any class should ever be that large, especially if you have a lot of independent methods and each class is only calling a few of them. This will make the class very hard to understand - having them all in one place will not improve the situation.
Some of the comments have already pointed this out, but you should, at a minimum, break this up topically.
Even better, refactor this to the Strategy pattern and use a Factory to pick which one to use. That will meet your goal of ease of use while avoiding the problem of having hundreds of unrelated methods in one place.
Try to define a Cohesive class, untill and unless the methods are written relevant to the class and it defines its purpose.
Below link describe the importance of methods for a class:
https://www.decodejava.com/coupling-cohesion-java.htm

Invoke Java object constant using a variable

I'm very new to Java so it makes it hard for me to explain what I'm trying to do.
I have an abstract class that invokes several object constants like this:
public abstract class Enchantment implements Keyed {
/**
* Provides protection against environmental damage
*/
public static final Enchantment PROTECTION_ENVIRONMENTAL = new EnchantmentWrapper("protection");
In a different file I can access this perfectly fine with Enchantment value = Enchantment.PROTECTION_ENVIRONMENTAL;
However, I'm trying to use a string variable for this instead. Something like this:
String str = "PROTECTION_ENVIRONMENTAL";
Enchantment value = Enchantment.str;
Obviously that won't work. So I did a bunch of research and learned I need to use reflection for this. Using this source code's docs I figured I was looking for field data. So I tried both:
Field fld = Enchantment.class.getField("PROTECTION_ENVIRONMENTAL");
Field fld = Enchantment.class.getDeclaredField("PROTECTION_ENVIRONMENTAL");
But these returned me a NoSuchFieldException. As I was on it, I've tried both getMethod() and getDeclaredMethod() just as well equally with no luck.
I'm now at the point that these are probably "object constants"? I'm not sure how to call them. But I'm definitely at a loss on how to get this to work now and after everything I've tried myself, I figured it was time to ask for some help here.
That one comment is spot on: you absolutely do not use reflection here.
There are only two valid reasons to use reflection:
you are creating a framework that has to deal with classes it doesn't know about
you have for some other reason to deal with classes you don't know about at compile time
But your code perfectly knows about that Enchantment class, its capabilities, and so on. Therefore reflection is the wrong approach. You figured it yourself: it is damn hard to get right, and damn right to get it wrong in some subtle ways. And when you get it wrong, it always blows up at runtime. Reflection code compiling means nothing. It always waits for you to run it to throw up in your face.
So to answer your question by not answering it: use a Map. Like:
Map<String, Enchantment> enchantmentsByConstantName = new HashMap<>();
enchantmentsByConstantName.put("PROTECTION_ENVIRONMENTAL", PROTECTION_ENVIRONMENTAL);
Alternatively, these constants could go into an enum, as outlined in the other answer, but in a sightly different way:
enum EnchantmentHolder {
PROTECTION_ENVIRONMENTAL(new EnchantmentWrapper("protection")),
ANOTHER_ENCHANTMENT(...)
A_THIRD_ENCHANTMENT(...)
...;
private Enchantment enchantment;
private EnchantmentHolder(Enchantment enchantment) {
this.entchantment = entchantment;
}
public Enchantment getEntchantment() { return entchantment; }
You may want to look into enumerations if you know they're going to be constant values;
public enum Enchantment {
PROTECTION_ENVIRONMENTAL {
public void cast() {
// do enum-specific stuff here
}
},
ANOTHER_ENCHANTMENT {
public void cast() {
// do enum-specific stuff here
}
},
A_THIRD_ENCHANTMENT{
public void cast() {
// do enum-specific stuff here
}
};
public abstract void cast();
}
enums can be treated like classes and have methods and properties. You can also convert to and from strings Enchantment.valueOf("PROTECTION_ENVIRONMENTAL") but that's generally if you are reading from a configuration file - in code you'd reference the value directly.
Once you have the Field, you need to call Field.get(Object) with an instance (in this case the class). Something like,
Class<?> cls = Enchantment.class;
try {
Field f = cls.getField("PROTECTION_ENVIRONMENTAL");
System.out.println(f.get(cls));
} catch (Exception e) {
e.printStackTrace();
}
Since you want the Enchantment, you could then test that the instance you get is assignable to Enchantment. Something like,
Class<? extends Enchantment> cls = Enchantment.class;
try {
Field f = cls.getField("PROTECTION_ENVIRONMENTAL");
Object obj = f.get(cls);
if (cls.isAssignableFrom(obj.getClass())) {
Enchantment e = cls.cast(obj);
System.out.println(e);
}
} catch (Exception e) {
e.printStackTrace();
}
But the enum approach is better.

What is a good java design pattern for similar objects with branching logic

I want to refactor an existing class of almost 5000 lines but I'm having difficulty with the constructor. Right now it's something like the following(methods here are in reality 10-30 blocks of code )
public MyClass( MyObject o ) {
if ( o.name.equalsIgnoreCase("a") ) {
doSomething()
} else {
doSomethingElse()
}
commonCode()
if (o.name.equalsIgnoreCase("a") ) {
doSecondThing()
} else {
doOtherSecondThing() //almost identical to doSecondThing but with some extra steps that absolutely have to be done in this sequence
}
// more of the same
}
I considered using inheritance and breaking things up into functions that would be overridden where necessary but that feels messy to me. Is there a pattern that fits this use case? Incidentally any advice on refactoring legacy code would be more than welcome.
You are exactly right. Refactoring like you described is called
Replace Conditional with Polymorphism.
Also you can look through on Chain-of-responsibility, Command or Strategy design patterns.
If every object follows the following pattern:
if(conditionA)
DoA();
else
DoElse();
Common();
if(conditionA2)
DoA2();
else if(conditionB2)
DoB2();
else
DoElse2();
Common2();
I'd advice you to have a common class that gathers handlers with conditions. This is roughly what I mean (Pseudo-code not java):
public interface IConditionalHandler
{
bool Condition();
void Action();
}
public class ActionHandler
{
private List<IConditionalHandler> m_FirstHandlers;
private List<IConditionalHandler> m_SecondHandlers; //Or possibly use a list of lists
public ActionHandler()
{
m_FirstHandlers = new ArrayList<>();
m_FirstHandlers.add(new HandlerA1());
m_FirstHandlers.add(new HandlerB1());
m_SecondHandlers = new ArrayList<>();
m_SecondHandlers.add(new HandlerA1());
m_SecondHandlers.add(new HandlerB1());
}
void DoStuff()
{
for(IConditionHandler handler : m_FirstHandlers)
{
if(handler.Condition())
{
handler.Action();
break;
}
}
CommonA();
for(IConditionHandler handler : m_SecondHandlers)
{
if(handler.Condition())
{
handler.Action();
break;
}
}
}
}
If you have lots of segment, a list of lists can include your common code as an exit-handler and contain all of the logic. You delegate the logic out to implementing classes, and shorten the actual code in your class.
However, as far as efficiency goes you are going to kill both the instruction and data cache. If this isn't what you're looking for, then more than likely this is: Chain-of-Responsibility Pattern - Wikipedia

Design patterns that can replace if statements

Our application is getting complex, it has mainly 3 flow and have to process based on one of the 3 type. Many of these functionalities overlap each other.
So currently code is fully of if-else statements, it is all messed up and not organised. How to make a pattern so that 3 flows are clearly separated from each other but making use of power of re-usability.
Please provide some thoughts, this is a MVC application, where we need to produce and consume web servicees using jaxb technology.
May be you can view the application as a single object as input on which different strategies needs to be implemented based on runtime value.
You did not specify what your if-else statements are doing. Say they filtering depending on some value.
If I understand your question correctly, you want to look at Factory Pattern.
This is a clean approach, easy to maintain and produces readable code. Adding or removing a Filter is also easy, Just remove the class and remove it from FilterFactory hashmap.
Create an Interface : Filter
public interface Filter {
void Filter();
}
Create a Factory which returns correct Filter according to your value. Instead of your if-else now you can just use the following :
Filter filter = FilterFactory.getFilter(value);
filter.filter();
One common way to write FilterFactory is using a HashMap inside it.
public class FilterFactory{
static HashMap<Integer, Filter> filterMap;
static{
filterMap = new HashMap<>();
filterMap.put(0,new Filter0());
...
}
// this function will change depending on your needs
public Filter getFilter(int value){
return filterMap.get(value);
}
}
Create your three(in your case) Filters like this: (With meaningful names though)
public class Filter0 implements Filter {
public void filter(){
//do something
}
}
NOTE: As you want to reuse some methods, create a FilterUtility class and make all your filters extend this class so that you can use all the functions without rewriting them.
Your question is very broad and almost impossible to answer without some description or overview of the structure of your application. However, I've been in a similar situation and this is the approach I took:
Replace conditions with Polymorphism where possible
it has mainly 3 flow and have to process based on this one of the 3
type. Many of these functionalities overlap each other.
You say your project has 3 main flows and that much of the code overlaps each other. This sounds to me like a strategy pattern:
You declare an interface that defines the tasks performed by a Flow.
public interface Flow{
public Data getData();
public Error validateData();
public void saveData();
public Error gotoNextStep();
}
You create an abstract class that provides implementation that is common to all 3 flows. (methods in this abstract class don't have to be final, but you definitely want to consider it carefully.)
public abstract class AbstractFlow{
private FlowManager flowManager
public AbstractFlow(FlowManager fm){
flowManager = fm;
}
public final void saveData(){
Data data = getData();
saveDataAsXMl(data);
}
public final Error gotoNextStep(){
Error error = validateData();
if(error != null){
return error;
}
saveData();
fm.gotoNextStep();
return null;
}
}
Finally, you create 3 concrete classes that extend from the abstract class and define concrete implementation for the given flow.
public class BankDetailsFlow extends AbstractFlow{
public BankDetailsData getData(){
BankDetailsData data = new BankDetailsData();
data.setSwiftCode(/*get swift code somehow*/);
return data;
}
public Error validateData(){
BankDetailsData data = getData();
return validate(data);
}
public void onFormSubmitted(){
Error error = gotoNextStep();
if(error != null){
handleError(error);
}
}
}
Lets take example, suppose you have model say "Data" [which has some attributes and getters,setters, optional methods].In context of Mobile application ,in particular Android application there can be two modes Off-line or On-line. If device is connected to network , data is sent to network else stored to local database of device.
In procedural way someone can , define two models as OnlineData,OfflineData and write code as[The code is not exact ,its just like pseudo code ]:
if(Connection.isConnected()){
OnlineData ond=new OnlineData();
ond.save();//save is called which stores data on server using HTTP.
}
else{
OfflineData ofd=new Onlinedata();
ofd.save();//save is called which stores data in local database
}
A good approach to implement this is using OOPS principles :
Program to interface not Implementation
Lets see How to DO THIS.
I am just writing code snippets that will be more effectively represent what I mean.The snippets are as follows:
public interface Model {
long save();//save method
//other methods .....
}
public class OnlineData extends Model {
//attributes
public long save(){
//on-line implementation of save method for Data model
}
//implementation of other methods.
}
public class OfflineData extends Model {
//attributes
public long save(){
//off-line implementation of save method for Data model
}
//implementation of other methods.
}
public class ObjectFactory{
public static Model getDataObject(){
if(Connection.isConnected())
return new OnlineData();
else
return new OfflineData();
}
}
and Here is code that your client class should use:
public class ClientClass{
public void someMethod(){
Model model=ObjectFactory.getDataObject();
model.save();// here polymorphism plays role...
}
}
Also this follows:
Single Responsibility Principle [SRP]
because On-line and Off-line are two different responsibilities which we can be able to integrate in Single save() using if-else statement.
After loong time I find opensource rule engine frameworks like "drools" is a great alternative to fit my requirement.

inheritance and instanceof [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Java method overloading + double dispatch
probably a dumb newbie question:. I want to avoid instanceof operator in situations like this:
class Service {
method(Some param) { }
}
class Special extends Some { }
class SpecialService extends Service {
method(Some param) {
if (param instanceof Special) {
//do special things
}
}
method(Special param) {
//do special things
}
}
Is the second special method the correct way to avoid the instanceof ?
Will there be any problems on the caller side of the service? In my case the special service is a customized version, plugged in and called from base code. Which method will be called?
Service s = new SpecialService();
s.method(specialparam);
And please point me to compact description or pattern how to solve this. Seems to be basic Java / OO knowledge...
Java does this automagically. Your code will work exactly as you want to, without the if statement. Java selects the most specific (most subclassed) method signature when choosing which version of the method to execute.
Here is a really good article on the subject.
I'm not sure durron597 is right. It all depends on how your code is written. It would workautomatically only if both variables are declared using specific types:
//good
Special specialparam = new Special();
SpecialService s = new SpecialService();
s.method(specialparam);
Code like
//bad
Some specialparam = new Special();
SpecialService s = new SpecialService();
s.method(specialparam);
or like
//bad
Special specialparam = new Special();
Service s = new SpecialService();
s.method(specialparam);
wouldn't work as you expect because known compile-time types are used to select method.
The whole design looks suspicously. This might be the right way but probably it is worths reconsidering it.
One of things that might hepl is Double dispatch mentioned by dasblinkenlight's comment. But to do one of base classes (Some or Service) should know about special cases. In short idea is that you write something like this:
class Some {
public void dispatch(Service service) {
service.method(this);
}
}
class Special extends Some {
public void dispatch(Service service) {
service.method(this);
}
}
class Service {
void dispatch(Some some) {
some.dispatch(this);
}
void method(Some some) {
// do common things here
}
void method(Special some) {
method((Some)some);
}
}
class SpecialService extends Service {
method(Special param) {
//do special things
}
}

Categories