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
}
}
Related
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
I am writing endpoint unit tests and for most of those there is an external web service that should be mocked, or a couple of them.
At first, i was creating mocks within tests which was okay when an endpoint test used only one external service, the mock creation was basically one liner.
As use cases became more complex, i needed to mock couple of services and exceptions for a single endpoint test.
I have put these mocks creation behind factories that all extend single factory and used builder pattern.
Within that base factory there is an inner class which i used as a builder for MockWebServiceServer.
protected class MultiStepMockBuilder {
private List<Object> mockActions = new ArrayList<Object>();
private WebServiceGatewaySupport gatewaySupport;
protected MultiStepMockBuilder(WebServiceGatewaySupport gatewaySupport) {
this.gatewaySupport = gatewaySupport;
}
protected MultiStepMockBuilder exception(RuntimeException exception) {
mockActions.add(exception);
return this;
}
protected MultiStepMockBuilder resource(Resource resource) {
mockActions.add(resource);
return this;
}
protected MockWebServiceServer build() {
MockWebServiceServer server = MockWebServiceServer.createServer(gatewaySupport);
for(Object mock: mockActions) {
if (mock instanceof RuntimeException) {
server.expect(anything()).andRespond(withException((RuntimeException)mock));
}
else if (mock instanceof Resource)
{
try
{
server.expect(anything()).andRespond(withSoapEnvelope((Resource) mock));
} catch (IOException e) {e.printStackTrace();}
}
else
throw new RuntimeException("unusuported mock action");
}
return server;
}
}
}
So i can now do something like this to create mock:
return new MultiStepMockBuilder(gatewaySupport).resource(success).exception(new WebServiceIOException("reserve timeout"))
.resource(invalidMsisdn)
.build();
The issue i have with this implementation is dependence on instanceof operator which i never use outside of equals.
Is there an alternative way to instanceof operator in this scenario ? From the questions on topic of instanceof everybody argues it should only be used within equals and therefore i have feeling that this is 'dirty' solution.
Is there an alternative to instanceof operator, within Spring or as a different design, while keeping fluent interface for mocks creation ?
I don't know Spring well enough to comment specifically on this particular area, but to me, this just seems like a design thing. Generally, when you are faced with using instanceof, it means that you need to know the type, but you don't have the type. It is generally the case that we might need to refactor in order to achieve a more cohesive design that avoids this kind of problem.
The root of where the type information is being lost, is in the List of mock actions, which are currently just being stored as a List of Objects. One way to help with this then, is to look at the type of the List and consider if there is a better type that could be stored in the List that might help us later. So we might end up with a refactoring something like this.
private List<MockAction> mockActions = new ArrayList<MockAction>();
Of course, then we have to decide what a MockAction actually is, as we've just made it up. Maybe something like this:
interface MockAction {
void performAction(MockWebServiceServer server);
}
So, we've just created this MockAction interface, and we've decided that instead of the caller performing the action - we're going to pass the server into it and ask the MockAction to perform itself. If we do this, then there will be no need for instanceof - because particular types of MockActions will know what they contain.
So, what types of MockActions do we need?
class ExceptionAction implements MockAction {
private final Exception exception;
private ExceptionAction(final Exception exception) {
this.exception = exception;
}
public void performAction(final MockWebServiceServer server) {
server.expect(anything()).andRespond(withException(exception);
}
}
class ResourceAction implements MockAction {
private final Resource resource;
private ResourceAction(final Resource resource) {
this.resource = resource;
}
public void performAction(final MockWebServiceServer server) {
/* I've left out the exception handling */
server.expect(anything()).andRespond(withSoapEnvelope(resource));
}
}
Ok, so now we've gotten to this point, there are a couple of loose ends.
We're still adding exceptions to the list of MockActions - but we need to change the add methods to make sure we put the right thing in the list. The new versions of these methods might look something like this:
protected MultiStepMockBuilder exception(RuntimeException exception) {
mockActions.add(new ExceptionAction(exception));
return this;
}
protected MultiStepMockBuilder resource(Resource resource) {
mockActions.add(new ResourceAction(resource));
return this;
}
So, now we've left our interface the same, but we're wrapping the resource or exception as they're added to the list so that we have the type specificity we need later on.
And then finally, we need to refactor our method that actually makes the calls, which now looks something like this - which is much simpler and cleaner.
protected MockWebServiceServer build() {
MockWebServiceServer server = MockWebServiceServer.createServer(gatewaySupport);
for(MockAction action: mockActions) {
action.performAction(server);
}
return server;
}
The Application
I am writing an application that executes certain functions depending on user input.
E.g. if the user input were to be
"1 2 add" the output would be "3".
I aim to implement many such methods (div, modulo, etc.). As my Scanner recognizes a function name like "add" the function "add()" should be called.
My Way
My way to do this is to let a FunctionHandler class evaluate the input.
Main:
String inputCommand = sc.nextCommand();
functionHandler.handle(inputCommand);
Function Handler:
public class FunctionHandler {
public void handle (String functionName) {
if (functionName.equals("add")) {
add();
} else if (functionName.equals("div") {
div();
}
}
private void add() {
.......
}
....
}
The Problem with that
As I am adding more and more functions the if statement gets very large, and of course the FunctionHandler class too. Also, whenever I add a new function, I have to change code in two places: I have to define the function, and then add the else if clause in handle() to call the function. Which means two pieces of information that should be encapsulated are "stored" completely independent from each other.
I was wondering what the best practice was to solve this kind of situation?
My Ideas
I was thinking about using enums, but they don't seem to fit well in this case.
Another idea I had was creating an interface Function, and then a class for each function that implements Function. The interface would have two methods:
getName()
execute()
Then I could create an array (manually) of Functions in the FunctionHandler, through which I could loop to see if the command the user enters matches getName().
However, having a different class for each function is not very clean either, and it also does not get rid of the problem that for each function I am adding I have to do it in two places: the class and the array.
This question is only about finding out how to solve this problem cleanly. A pointer in the right direction would be appreciated!
Thanks a lot!
Another option would be to keep a Map of handlers. If you're using Java 8, they can even be method references.
// InputType and ResultType are types you define
Map<String, Function<InputType, ResultType>> operations = new HashMap<>();
operations.put("add", MathClass::add);
// ...
ResultType result = operations.get(userInput).apply(inputObject);
One downside to doing it this way is that your input and output types must be the same for all operations.
You could create a custom annotation for the various functions. Then you could employ your array idea, but have it use reflection to discover which functions have your new annotation and what their names are.
As background, take a look at http://www.oracle.com/technetwork/articles/hunter-meta-2-098036.html and http://www.oracle.com/technetwork/articles/hunter-meta-3-092019.html. They're a bit old, but seem to address the necessary ideas.
You can always use reflection if you want a short solution.
In your handle method you could do something like this:
Method m = this.getClass().getMethod(functionName, new Class[]{});
m.invoke(this, new Object[]{});
Assuming you do not have a lot of functions that you want to do this way, and do not want to expose yourself to the security risks caused by reflection, you could use a string switch, like this:
void handleFunction(String function) {
switch (function) {
case "foo":
foo();
break;
case "bar":
bar();
break;
default:
throw new IllegalArgumentException("Unknown function " + function);
break;
}
}
Starting Java 7, you can use Strings in a switch statement and the compiler will make something reasonable out of it
I would do something like this:
public class FunctionTest {
private static final Map<String, Runnable> FUNCTIONS = new HashMap<String, Runnable>() {{
put("add", () -> System.out.println("I'm adding something!"));
put("div", () -> System.out.println("I'm dividing something!"));
}};
public void handle(String functionName) {
if (!FUNCTIONS.containsKey(functionName)) {
throw new IllegalArgumentException("No function with this name: " + functionName);
}
FUNCTIONS.get(functionName).run();
}
}
You basically can use any functional interface in place of Runnable, I used it, because it matches your add() method. You can map the names of the functions to their actual executable instance, get them by name from the Map and execute them.
You could also create an enum with the desired executable blocks:
public class FunctionsAsEnumsTest {
private static enum MyFunction {
ADD {
#Override public void execute() {
System.out.println("I'm adding something");
}
},
DIV {
#Override public void execute() {
System.out.println("I'm dividing something");
}
};
public abstract void execute();
}
public void handle(String functionName) {
// #toUpperCase() might not be the best idea,
// you could name your enums as you would the methods.
MyFunction fn = MyFunction.valueOf(functionName.toUpperCase());
fn.execute();
}
}
I have the following java code
public class QuestionBuilder {
private QuestionBuilder(){}
static HashMap<Long,Class<? extends Question>> questionIdMap;
static{
questionIdMap = new HashMap();
questionIdMap.put(1L, LicenseNumberQuestion.class);
questionIdMap.put(2L, USPQuestion.class);
}
static Question getQuestion(long questionId)
{
if(!questionIdMap.containsKey(questionId))
{
throw new BusinessProfileInputException("Add an id to question class map entry");
}
return questionIdMap.get(questionId).newInstance();
}
}
and I would like my getQuestion method to return me a new instance of the class that was specified as a value in the map as is intended via my code. Howerver the last line of code does not compile :
return questionIdMap.get(questionId).newInstance();
Am I thinking of this wrongly? i.e. is there a better way to approach this?
You just need to catch an exception:
try {
return questionIdMap.get(questionId).newInstance();
} catch(InstantiationException e) {
System.out.println("Constructor failed: );
e.printStackTrace();
return null;
}
This should compile fine.
I would do it like this:
public final class QuestionBuilder {
private QuestionBuilder(){}
public enum Type {
LICENSE_NUMBER {
#Override
Question getQuestion() { return new LicenseNumberQuestion(); }
},
USP {
#Override
Question getQuestion() { return new USPQuestion(); }
};
abstract Question getQuestion();
}
public static Question getQuestion(Type type) {
return type.getQuestion();
}
}
With your solution the user of the class has to write
Question question = QuestionBuilder.getQuestion(1);
This isn't great because it's not clear what "1" here means, and she is going to have to learn the meaning of a load of numbers. Also, if you pass in a number that doesn't mean anything, there's a problem (hence the need for a BusinessProfileInputException).
With the enum approach, the user of the class would write
Question question = QuestionBuilder.getQuestion(QuestionBuilder.Type.LICENSE_NUMBER);
Now this is obviously longer, but there are 3 major advantages. (1) The user of the class doesn't need to remember any abstract code numbers. In fact if the user is using a decent IDE, she should actually be presented with a meaningful list of choices as she types. (2) There is no longer the need for the BusinessProfileInputException because it is now impossible to pass something that doesn't mean anything (except null, but in this case a NullPointerException would be thrown anyway). (3) You no longer need reflection to create the new Question, so there is no need for the irritating try block.
But it's even better than this. You'll notice that since we've got rid of the Map, the class QuestionBuilder doesn't actually do anything at all. You could improve things further by getting rid of the class completely, and making the enum a top-level class with a simple name like TypeOfQuestion. Then all the user would have to type is
Question question = TypeOfQuestion.LICENSE_NUMBER.getQuestion();
enums in Java are absolutely brilliant. They are far superior to the counterparts in other languages. I strongly recommend learning about them.
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)
}
}