Below is an attempt to create a reusable solution for the control break pattern. It is built on Command Pattern (Action and Test interfaces). However, I realized my old COBOL thinking got in the way, because this solution is predicated on each of the Action and Test objects having access to "global variables." And my immediate thought after that was "the need for variable access like this (wider scope) must be an already invented wheel.
How to give all the Actions and Tests below access to a group of variables -- an indeterminate group because this is supposed to be a reusable solution??
public class ControlBreak {
public static void controlBreak(Action initialize,
Test endOfInput,
Test onChange,
Action breakAction,
Action detailAction,
Action getNext) {
boolean hasProcessed = false;
getNext.execute();
for (initialize.execute();endOfInput.test();detailAction.execute(),getNext.execute()) {
hasProcessed = true;
if (onChange.test()) {
breakAction.execute();
}
detailAction.execute();
}
if (hasProcessed) {
breakAction.execute();
} else {
// throw empty input exception
}
}
}
On a few re-reads, it seems like you're trying to abstract a certain control flow, where the parameters can be coupled. In this case, I'd look into generics. I.e. something like this:
public static void <TParams> controlBreak(Action<TParams> initialize, ..., TParams params) {
// ...
initialize.execute(params)
// ...
}
That way this method will remain reusable, but the various actions / tests can still accept a strongly-typed set of parameters/variables. (The concrete type of TParam.)
Thanks to millimoose, I got where I was going. Here's the fleshed out code, for reference:
public class ControlBreak<TParams> {
public TParams controlBreak(Action<TParams> initialize,
Test<TParams> endOfInput,
Test<TParams> onChange,
Action<TParams> breakAction,
Action<TParams> detailAction,
Action<TParams> getNext,
TParams params) {
boolean hasProcessed = false;
getNext.execute(params);
for (params = initialize.execute(params);endOfInput.test(params);params = detailAction.execute(params),params = getNext.execute(params)) {
hasProcessed = true;
if (onChange.test(params)) {
breakAction.execute(params);
}
detailAction.execute(params);
}
if (hasProcessed) {
breakAction.execute(params);
} else {
// throw empty input exception
}
return params;
}
}
Related
So, this element of code has the potential to get pretty ugly. There is the potential of adding multiple elements to the list in each if statement as well as many more if/else statements. What would be the best pattern or way of going about designing this piece of code. I was thinking about the chain of responsibility but that means be passing the list round everywhere which isn't the best or even the builder pattern? Any thoughts??
List<String> aList = new ArrayList<>();
if (something.contains(Effect.HARD)) {
aList.add("");
}
if (something.contains(Effect.REFLECT)) {
aList.add("");
aList.add("");
} else {
aList.add("no reflect");
}
if (something.contains(Effect.OUTLINE)) {
aList.add("something");
}
if (something.contains(Effect.GRADIENT)) {
aList.add("gradient");
} else {
aList.add("no gradient");
}
Use a visitor (link to wikipedia page).
Here is some lighthearted example code:
public interface Visilator
{
// Process the stuff and, maybe, add an element to the kerplungy list.
void doStuff(Stuff stuff, List<Kerplungy> kerplungyList);
}
public class Kerplungilator
{
// Actually create this however you choose.
#Autowired
private List<Visilator> visilatorList;
public List<Kerplungy> processStuffs(final Stuff stuff)
{
final List<Kerplungy> returnValue = LinkedList<>(); // ArrayList is for chumps.
for (final Visilator current : visilatorList)
{
current.doStuff(Stuff, returnValue);
}
return returnValue;
}
}
public clss HootVisilator
implements Visilator
{
public void doStuff(
#NotNull final Stuff stuff,
#NotNull final List<Kerplungy> kerplungyList)
{
if (stuff.hoot())
{
final Kerplungy hootKerplungy = new Kerplungy("hoot");
kerplungyList.add(hootkerplungy);
}
else
{
System.out.println("not hoot");
}
}
}
Normally you'd look at replacing those ugly conditionals with polymorphic code, but that won't work well here as the conditions (something.contains(...)) are not based on the type of the object. You could turn them into objects, but this would not be an elegant solution either. Builder and Visitor could be used, but I doubt very much you code would more readable at all.
In my java app I got a method that runs a long sequence of steps (synchronously) where one step result is the input for the next.
for example:
// Step 1
Map<String, SomeObject> objectsMap = someService.createObjectsMap();
if (!objectsMap.isEmpty()) {
// Step 2
AnotherObject anotherObject = anotherService.createAnotherObject(objectsMap);
if (null != anotherObject) {
// Step 3 that gets anotherObject as input and returns something else
} else { // Step 2 failed
// log and handle
}
} else { // Step 1 failed
// log and handle
}
And so I got this series of steps written in a series of if-else blocks.
There is no common interface for the steps since each one has different signature. I've been loking on some different and tried to customize patterns such as chain-of-responsibility and command but could not get to a satisfied result.
I wonder if this ugly long if-else section is the way to go or is there a pattern out there that can help make this series of steps more clean and scalable.
One question you must answer yourself is Why do I want to refactor my code?
Do you want it to be
more clean code?
more modularized?
Must the steps be configurable (replaceable) at runtime?
Refactor in order to make the code clean
If the steps do not need to be configured at runtime and you want to make your code more clean than you should take a look at the comments you made. Each comment is a hint.
Break the code block into methods and name them after the steps
/**
* Explain what step1 does.
*/
private void step1() {
// Step 1
Map<String, SomeObject> objectsMap = someService.createObjectsMap();
if (!objectsMap.isEmpty()) {
step2(objectsMap);
} else { // Step 1 failed
// log and handle
}
}
/**
* Explain what step2 does.
*/
private void step2(Map<String, SomeObject> objectsMap) {
// Step 2
final AnotherObject anotherObject = anotherService
.createAnotherObject(objectsMap);
if (null != anotherObject) {
step3(anotherObject);
} else { // Step 2 failed
// log and handle
}
}
/**
* Explain what step3 does.
*/
private void step3(AnotherObject anotherObject) {
// Step 3 that gets anotherObject as input and returns something
// else
}
This approach just breaks the method down to smaller methods. The advantage is that each smaller method is only responsible for one thing. And because it is a method you can add javadoc to it. So there is no need for inline comments anymore. Eventually you can give the method better names and omit the javadoc at all.
Refactor in order to make the steps replaceable at runtime
If you want to configure the steps that are executed at runtime (e.g. because of some user input) than you must encapsulate them in objects, because your application has references to objects that can be replaced.
Since you want all steps to have a common api you must make it more general.
Start thinking from the clients perspective. How should the steps be executed. E.g.
for (Step step : steps) {
boolean executeNext = step.execute();
if (!executeNext) {
break;
}
}
Design a Step interface
public interface Step {
boolean execute();
}
How to pass the output of one step as the input to another?
Make an interface
public static interface StepInput<T> {
public T getInput();
}
Implement your Steps. An abstract class will help you.
public abstract class InputOutputStep<T> implements Step,
StepInput<T> {
private T returnValue;
protected void setReturnValue(T returnValue) {
this.returnValue = returnValue;
}
public T getInput() {
return returnValue;
}
}
public class Step1 extends InputOutputStep<Map<String, SomeObject>> {
private StepInput<Map<String, SomeObject>> stepInput;
public Step1(StepInput<Map<String, SomeObject>> stepInput) {
this.stepInput = stepInput;
}
public boolean execute() {
boolean executeNext = false;
Map<String, SomeObject> objectsMap = stepInput.getInput();
if (!objectsMap.isEmpty()) {
// Step 2
setReturnValue(objectsMap);
executeNext = true;
} else { // Step 1 failed
// log and handle
}
return executeNext;
}
}
public class Step2 extends InputOutputStep<AnotherObject> {
private StepInput<Map<String, SomeObject>> stepInput;
private AnotherService anotherService;
public Step2(AnotherService anotherService,
StepInput<Map<String, SomeObject>> stepInput) {
this.anotherService = anotherService;
this.stepInput = stepInput;
}
public boolean execute() {
boolean executeNext = false;
Map<String, SomeObject> objectsMap = stepInput.getInput();
AnotherObject anotherObject = anotherService
.createAnotherObject(objectsMap);
if (null != anotherObject) {
setReturnValue(anotherObject);
executeNext = true;
} else { // Step 2 failed
// log and handle
}
return executeNext;
}
}
public class Step3 extends InputOutputStep<Void> {
private StepInput<AnotherObject> stepInput;
public Step3(StepInput<AnotherObject> stepInput) {
this.stepInput = stepInput;
}
public boolean execute() {
AnotherObject anotherObject = stepInput.getInput();
setReturnValue(null);
return false;
}
}
Configure the steps at runtime and execute
Step1 step1 = new Step1(stepInput);
Step2 step2 = new Step2(anotherService, step1);
Step step3 = new Step3(step2);
Step[] steps = new Step[]{step1, step2, step3};
for (Step step : steps) {
boolean executeNext = step.execute();
if (!executeNext) {
break;
}
}
This scenario -where you do lots of things and want to abort and log if any of them fails - is what exception handling is designed for. For example:
try {
// Step 1
Map<String, SomeObject> objectsMap = someService.createObjectsMap();
if (objectsMap.isEmpty())
throw new SomethingWentWrongException("Failed to get object map from service");
// Step 2
AnotherObject anotherObject = anotherService.createAnotherObject(objectsMap);
if(anotherObject == null)
throw new SomethingWentWrongException("Failed to create another object");
// Step 3 that gets anotherObject as input and returns something else
} catch(SomethingWentWrongException e) {
// log and handle
e.printStackTrace();
}
Ideally, someService.createObjectsMap and anotherService.createAnotherObject would throw their own exceptions instead of making you check the return value. Then you would only need to write:
try {
Map<String, SomeObject> objectsMap = someService.createObjectsMap();
AnotherObject anotherObject = anotherService.createAnotherObject(objectsMap);
// Step 3 that gets anotherObject as input and returns something else
} catch(Exception e) {
// log and handle
e.printStackTrace();
}
(although note that you should only catch Exception if you really want to catch all failures)
Options:
Memento Pattern:
With memento, you can store the state of the object. Like when you want to redo and undo things.
This way, when you have similar methods in step 1 and step 3, you can simply use 1 general method.
Then, with undo and redo, you know that you have to save your state.
Think of possibility to save your step number.
Strategy pattern:
With strategy pattern, you are saving the IF-ELSE statement.
You just have to go to one function, strategy object will determine the rest.
Think of a router as the strategy class.
The router will determine the best way, best route, or best process (from several process options).
Observer pattern:
This is something like MVC.
I always think that observer is a CCTV.
When something changes, something weird happened, the CCTV admin will know.
So you have a controller class, which monitors everything, and configures where you have to go next.
Thank you,
When a class' public method needs to call a private method that results in a field being changed, which method should change the field? Is there any common convention for this? Is one approach preferable over the other?
Consider these two code snippets:
public class boolHolder {
private boolean theBool = false;
public void doYourThing() {
// Do a lot of other stuff
setBool();
}
private void setBool() {
// Do a lot of other stuff, justifying a private method for this
this.theBool = true;
}
}
VS
public class boolHolder {
private boolean theBool = false;
public void doYourThing() {
// Do a lot of other stuff
theBool = setBool();
}
private boolean setBool() {
// Do a lot of other stuff, justifying a private method for this
return true;
}
}
These two snipped of course being a very simple case, but I'm sure I'm not the only one ending up with public methods calling a huge tree of private methods. Should the field be set at the end of the branch, or should a value be passed back?
I think it makes more sense that only a single place would set the value of the field, and it should be the last method being called. It makes the code easier to understand. Your first snippet looks much more readable to me.
Here's another snippet which, in my opinion, supports this convention :
Lets say we have an int member with two setters - one accepts an int and the other accepts a String representation of that int (which is used, for example, if we de-serialize an instance from an XML String).
int value;
public void setIntField (String value)
throws SomeException
{
if (value == null)
throw new SomeException();
try {
int val = Integer.parseInt (value);
setIntField (val);
}
catch (NumberFormatException ex) {
throw new SomeException();
}
}
public void setIntField (int value)
throws SomeException ()
{
if (value < MIN_ALLOWED || value > MAX_ALLOWED)
throw new SomeException ();
this.value = value;
}
Apart from renaming theBool and setBool to something more understandable (which I'm going to assume you did eitherway in the real application), I'd go with the first one. Methods with the word set are expected to be setters and not many people will expect a return value.
It doesn't change much, but you can try to use a better naming for your methods: i don't like that you name your second method setBool().
If you write "Do a lot of other stuff, justifying a private method for this" you can try to associate a verb to that stuff you do.
Say you update an account status and upon completion want to signal with the boolean the status, well use something like what you did but call it in a meaningful way, e.g. updateAccount() and either return a true if the update went fine or set it inside:
public class boolHolder {
private boolean accountUpdated = false;
public void doYourThing() {
// Do a lot of preliminary stuff
updateAccount();
}
private void updateAccount() {
// try to update account
// if update went fine
this.accountUpdated = true;
}
}
or
public class boolHolder {
private boolean accountUpdated = false;
public void doYourThing() {
// Do a lot of preliminary stuff
this.accountUpdated = updateAccount();
}
private boolean updateAccount() {
// try to update account
// if error happens, rollback change and set
return false;
// else (update went fine)
return true;
}
}
are both perfectly fine, but make your method tell what they do, since updating the bool is not the main action since you "Do a lot of other stuff, justifying a private method for this".
The value setting inside is more compact if you use a default to false as you did, but the other is more explicit in what it does. So I tend to prefer that: returning a result for you operation.
I'd like to ask for help and some suggestion how to refactor source code which I receive.
Here is pseudocode of my method:
public void generalMethod(String type) {
InputParameters params = new InputParameters();
if (type.equals("someKey1"){
decodeSomeKey1(params);
} else if (type.equals("someKey2"){
decodeSomeKey2(params);
} else if (type.equals("someKey3"){
decodeSomeKey3(params);
} else if (type.equals("someKey4"){
etc...
}
}
}
All methods have the same input parameters. In first step I created new interface and created for each method separate class which implements created interface.
interface ISomeInterfaceDecoder {
void decode(InputParameters params);
}
class DecodeSomeKey1 implements ISomeInterfaceDecoder {
#Override
public void decode(InputParameters params) {
// some implementation
}
}
class DecodeSomeKey2 implements ISomeInterfaceDecoder {
#Override
public void decode(InputParameters params) {
// some implementation
}
}
Then I created factory class as follows:
class Factory {
ISomeInterfaceDecoder getDecoder(String type) {
if (type.equals("someKey1"){
return new DecodeSomeKey1();
} else if (type.equals("someKey2"){
return new DecodeSomeKey2();
} else if (type.equals("someKey3"){
return new DecodeSomeKey3());
} else if (type.equals("someKey3"){
etc...
}
}
}
}
After these changes the code looks like this:
class SomeClass {
Factory factory = new Factory();
public void generalMethod(String type) {
InputParameters params = new InputParameters();
ISomeInterfaceDecoder decoder = factory.getDecoder(type);
decoder.decode(params);
}
}
Code of this method looks better but...
This method is called very very often. Each time a new instance of the given class is created. This can cause performance problems. So, I think it's not good approach to this problem.
Can you give me some suggestion how I should to refactor this code?
Thanks in advance for help.
Instead of having a key as a String, make it an enum. Then in the enum you can implement the decode() method like this:
public enum MyKeyEnum {
VALUE1 {
public void decode(InputParameters ip) {
// do specific decoding for VALUE1
}
},
VALUE2 {
public void decode(InputParameters ip) {
// do specific decoding for VALUE2
}
}
...
;
public abstract void decode(InputParameters ip);
}
Now in the calling code you can do something like this:
public void generalMethod(MyKeyEnum type) {
InputParameters params = new InputParameters();
type.decode(params);
}
The advantage is that all the decode methods are in 1 enum, you dont need a specific class for each of the decoders. Also when a new value is added to the enum, you cannot forget to implement the decode method (or it will not compile).
Can you give me some suggestion how I should to refactor this code?
I see no mention of automated regression testing, and that would be my first step, to put in a test suite (via, say, JUnit or TestNG) before going further.
After that, I'd perhaps introduce a Map of String keys to Decoder objects.
But put the test framework in first. Otherwise you'll never really know if you've introduced bugs or different modes of operation.
Introduce caching/singletons in your factory, that you only return an algorithm once. Also, make your factory a singleton.
Create a static Map<String, ISomeInterfaceDecoder> where you map the identifier to algorithms executing the call which means no factory class and no algorithm instantiation. Works only, if you have stateless algorithms.
Okay guess this question looks a lot like:
What is the best way to replace or substitute if..else if..else trees in programs?
consider this question CLOSED!
I would like to refactor code which looks something like this:
String input; // input from client socket.
if (input.equals(x)) {
doX();
} else if (input.equals(y)) {
doY();
} else {
unknown_command();
}
It is code which checks input from socket to perform some action, but I don't like the if else construction because every time a new command is added to the server (code) a new if else has to be added which is ugly. Also when deleting a command the if else has to be modified.
Collect those commands in a Map<String, Command> where Command is an interface with an execute() method.
Map<String, Command> commands = new HashMap<String, Command>();
// Fill it with concrete Command implementations with `x`, `y` and so on as keys.
// Then do:
Command command = commands.get(input);
if (command != null) {
command.execute();
} else {
// unknown command.
}
To get a step further, you could consider to fill the map dynamically by scanning for classes implementing a specific interface (Command in this case) or a specific annotation in the classpath. Google Reflections may help lot in this.
Update (from the comments) You can also consider combining the answer of Instantsoup with my answer. During the buildExecutor() method, first get the command from a Map and if the command doesn't exist in Map, then try to load the associated class and put it in the Map. Sort of lazy loading. This is more efficient than scanning the entire classpath as in my answer and creating it everytime as in Instantsoup's answer.
One way could be to have an interface ICommand that is the general contract for a command, e.g.:
public interface ICommand {
/** #param context The command's execution context */
public void execute(final Object context);
public String getKeyword();
}
And then you could use Java's SPI mechanism to auto-discover your various implementations and register them in a Map<String,ICommand> and then do knownCommandsMap.get(input).execute(ctx) or something alike.
This practically enables you to decouple your service from command implementations, effectively making those pluggable.
Registering an implementation class with the SPI is done by adding a file named as the fully qualified name of your ICommand class (so if it's in package dummy the file is going to be META-INF/dummy.ICommand within your classpath), and then you'll load and register them as:
final ServiceLoader<ICommand> spi = ServiceLoader.load(ICommand.class);
for(final ICommand commandImpl : spi)
knownCommandsMap.put(commandImpl.getKeyword(), commandImpl);
How about interfaces, a factory, and a little reflection? You will still need to handle exceptions on bad input, but you would always need to do this. With this method, you just add a new implementation of Executor for a new input.
public class ExecutorFactory
{
public static Executor buildExecutor(String input) throws Exception
{
Class<Executor> forName = (Class<Executor>) Class.forName(input);
return (Executor) executorClass.newInstance();
}
}
public interface Executor
{
public void execute();
}
public class InputA implements Executor
{
public void execute()
{
// do A stuff
}
}
public class InputB implements Executor
{
public void execute()
{
// do B stuff
}
}
Your code example then becomes
String input;
ExecutorFactory.buildExecutor(input).execute();
Building the Command patten upon an enum class can reduce some of the boilerplate code. Let's assume that x in input.equals(x) is "XX" and y in input.equals(y) is "YY"
enum Commands {
XX {
public void execute() { doX(); }
},
YY {
public void execute() { doY(); }
};
public abstract void execute();
}
String input = ...; // Get it from somewhere
try {
Commands.valueOf(input).execute();
}
catch(IllegalArgumentException e) {
unknown_command();
}
You say that you're processing input from a socket. How much input? How complex is it? How structured is it?
Depending on the answers to those questions, you might be better off writing a grammar, and letting a parser generator (eg, ANTLR) generate the input-processing code.