When a class performs a complicated and lengthy task, I usually refactor it step-by-step based on the situation, as shown below.
Version 0
public class ComplicatedTaskDoer{
public void doComplicatedTask(){
// lots of complicated code
}
}
Version 1:
Break it down into multiple smaller sub-tasks
public class ComplicatedTaskDoer{
public void doComplicatedTask(){
init();
doSubStepA();
doB();
doC();
wrapUp();
}
}
Version 2:
If complicated enough, outsource sub-tasks to helper classes. I don't really code to interfaces in this case.
public class ComplicatedTaskDoer{
public void doComplicatedTask(){
init();
subsetpADoerClass.doA();
classB.doB();
classC.doC();
wrapUp();
}
}
Version 3:
If I see my self in need of adding more components in the future and if there's a valid pattern in terms of input and output objects, I do the following.
public class ComplicatedTaskController{
//injected
List<SomethingHelperComponent> components;
public void doComplicatedTask(){
init();
for(SomethingHelperComponent component : components){
component.process(commonInput);
}
wrapUp();
}
}
I'm more curious about the version 3. I ended up doing that quite a few times.
Q1)
Is there any existing pattern that's similar and probably more effective? It's not 'chain of responsibilities' that I'm looking for as I prefer those components to be independent (open to discuss). It looks more like a configurable variation of template method pattern.
Q2)
I've always named the main class as 'SomethingController' and the helper classes with 'SomethingHelper' or 'SomethingComponent'. I recently realized that 'controller' was misleading and 'helper' was non-informative.
It'd be really helpful to get some ideas on correctly naming those classes. How'd you name them?
Q3)
Did you think that the refactoring was reasonable?
Q4)
Subjective: Is it OK to keep some steps in the helper methods and outsource some steps to helper classes? I usually restrain myself from unit-testing non-public methods.
Q5)
Do you consider helper classes, i.e. with no code-to-interfaces, to be a code smell? May be I can even declare them as inner classes?
Configuration of classes
This is legit solution. It is sometimes seen with spring where partial tasks
implement some interface and through spring magic you can have list of all implementations with
#Autowired
List<MyInterface> myParts;
Design Pattern Name
As for naming I think you could think about it as as special case of chain of responsibility. It might not be really accurate, but shows your intention pretty well.
Naming of classes
I'd go for suffix .*Algorithm
Name main Interface like DoSomethingComplicatedAlgorithm or DoSomethingComplicatedAlgorithmStep. Classes which implement interface would be called WhatPartOfAlgorithmIsUsedHere
Helper Classes
If they they'll let you avoid code duplication and you have no better domain model than you can use them. On the other hand leave it as a last resort option. Might be small code smell, but certainly your application won't burn.
Related
We have a small lightweight framework with around 20 classes, used by 50+ developers and semi-large code base. To keep the framework small, we've avoided creating too many interfaces, abstract classes, etc. This is a trade-off to speed up adaptation by new developers as well as keep code complexity low.
So we do not utilize internal/external interfaces or heavy use of factory classes. We rely on a few classes with public/private methods to define scope. However sometimes methods have to be public but only be accessible to the framework and not the developer.
Example:
public class Logger
public boolean isDebugEnabled() {...}
public void enableDebug() {...}
enableDebug is an "internal" framework method and is documented with "Do not use - Internal class". The method cannot be private nor at package scope due to framework structure.
Once in a while a developer will miss the javadoc and invoke an internal method which can produce unexpected results at runtime.
Example:
if (!Logger.isDebugEnabled) {
Logger.enableDebug(); // screw the javadoc - i'm enabling debug logging
}
The framework team is thinking the best approach is to name them following a certain convention. This will not introduce compile-time safety, but decrease error probability.
Example:
public void enableDebugInternal() or _enableDebug() or $enableDebug()
is more precise than
/**
* Internal method - do not use
*/
public void enableDebug()
Another option they are thinking is to wrap all internal methods into an internal class:
public class Logger
public boolean isDebugEnabled() {...}
public class Internal {
public void enableDebug() {...}
}
Can you recommend a better approach ?
Preferably something that provides compile-time safety
EDIT: Turns out what I am looking for is a design pattern for the keyword "internal" for C# in java:
https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/accessibility-levels
Well, you pretty much answered your own question. You can't change the access level, so you'll pretty much have to change the name of it. A bit hacky, but you could also deprecate the method. Hamcrest does something... err... interesting... with the Matcher interface to this effect.
If you want to enforce that it's not used outside of the package then you'll need to do some kind of static analysis as part of your build. If I had no other choice, I'd write a Maven plugin to look for usages.
Ultimately, it sounds like your design is wrong if you have a public method that needs to act as if it were package-private.
You shouldn't be writing your own logging facade anyway, especially if you're writing a framework. You should be using SLF4J.
I have a Java class called TestExecutor which responsible for starting a test. Starting the test involves a number of stages:
- Update test repository
- Locate the test script
- Create result empty directory
- Execute command
- Parse output
- Update database
For each of these stages I have created private methods in the TestExecutor class which perform each of the actions above, all surrounded in a try-catch block. I'm aware that this is not good design as my class does too much and is also a pain to unit test due to a large amount of functionality being hidden in private methods.
I'd like to hear your suggestions for refactoring this class as I'm not sure how to get away from something similar to the above structure. Code example below:
public void start() throws TestExecuteException {
try {
updateRepository();
locateScript();
createResultDirectory();
executeCommand();
parseOutput();
updateDatabase();
catch(a,b,c) {
}
}
private updateRepository() {
// Code here
}
// And repeat for other functions
I would do this way. First, enforce the contract that each test step should have.
interface TestCommand{
void run();
}
Now make your test commands as separate classes. Try to make these commands classes generic so that you reuse for similar types of commands. Now in your class where you want to run a test, configure the test steps as following.
//in your test class do this.
List<TestStep> testCommands = new ArrayList<>();
testCommands.add(new UpdateRepoCommand());
testCommands.add(new LocateScriptCommand());
// and so on....
Now, execute all your steps chronologically.
public void start(testSteps) throws TestExecuteException {
try {
for(TestCommand command : testCommands){
command.run()
}
catch(Exception e) {
//deal with e
}
}
Moreover, as CKing described above, follow SOLID principle inside those test steps. Inject dependencies and write the unit test for them separately.
Well your class looks ok to me.
I'm aware that this is not good design as my class does too much
As far as the class has a single responsibility the number of methods don't matter.
Check this template method design pattern. Your class is doing something similar to what the abstract Game class is doing.
public abstract class Game {
abstract void initialize();
abstract void startPlay();
abstract void endPlay();
//template method
public final void play(){
//initialize the game
initialize();
//start game
startPlay();
//end game
endPlay();
}
}
and is also a pain to unit test due to a large amount of functionality
being hidden in private methods
Read this & this about testing private methods. You can also use a framework like PowerMock which helps you in testing untestable code.
I'd like to hear your suggestions for refactoring this class as I'm not sure how to get away from something similar to the above structure
You should definitely take a look at the SOLID principles as a starting point to writing clean,testable object oriented code. I was introduced to it at the begning of my career and it really helps a lot to follow these principles.
That said, I would start by grouping related functionality into different classes. For example, updateRepository() and updateDatabase() can be moved to a separate class called DatabaseHelper. Similarly locateScript() and createResultDirectory() seem to be disk related operations and can be moved to a seperate class called DirectoryHelper. I believe you get the gist of it. What you just achieved was Seperation of Concerns.
Now that you have separate classes, you need to bring them together and put them to work. Your TestExecutor can continue to have the methods that you have listed. The only different will be that these methods will now delegate their work to the individual classes that we created above. For this, TestExecutor will need a reference to the DatabaseHelper and DirectoryHelper classes. You could just instantiate these classes directly inside TestExecutor. But that would mean that TestExecutor is tightly coupled to an implementation. What you can do instead is ask code outside TestExecutor to supply the DatabaseHelpe and DirectoryHelper to use. This is known as Dependency Inversion through Dependency Injection. The advantage of this approach is that you can now pass any subclass of DatabaseHelper and DirectoryHelper to TaskExecutor and it doesn't have to know the details of the implementation. This facilitates in the unit testing of TaskExecutor by mocking these dependencies instead of passing actual instances.
I will leave the rest of the SOLID principles for you to explore, implement and appreciate.
Each of the classes contains about 30 methods and almost a half of them are same or very similar. And soon I am going to add a third class which is in the same situation with these two classes. I feel it is a mess to maintain or change them. How can I refactor to avoid the duplicate code?
Here is a simplified version:
public class A extends ContentPanel{
private AMenuProvider menuProvider;
private ADefinitionTree tree;
public void sameMethod1(){
...
menuProvider.do();
tree.doSomething();
...
}
public void sameMethod2(){
...
menuProvider.do();
tree.doSomething();
...
}
public void differentMethodFromA(){
... // uses menuProvider and tree
}
...
// 10 similar methods and 20 different methods
}
public class B extends ContentPanel{
private BMenuProvider menuProvider;
private BDefinitionTree tree;
public void sameMethod1(){
...
menuProvider.do();
tree.doSomething();
...
}
public void sameMethod2(){
...
menuProvider.do();
tree.doSomething();
...
}
public void differentMethodFromB(){
... // uses menuProvider and tree
}
...
// 10 similar methods and 20 different methods
}
NOTE: BMenuProvider vs AMenuProvider and ADefinitionTree vs BDefinitionTree could be very different implementation, but they provide a lot of same methods. Each of them has some unique methods which the other does not have.
I thought about creating an abstract class and extend it, but it seems ugly wherever I put the menuProvider and tree attributes. I am not sure whether there is any design patterns or solutions. Please help me refactor the classes so that I can remove the duplicate code.
"S" in S.O.L.I.D:
The single responsibility principle states that every module or class
should have responsibility over a single part of the functionality
provided by the software, and that responsibility should be entirely
encapsulated by the class. All its services should be narrowly aligned
with that responsibility.
"I":
The interface-segregation principle (ISP) states that no client should
be forced to depend on methods it does not use.[1] ISP splits
interfaces which are very large into smaller and more specific ones so
that clients will only have to know about the methods that are of
interest to them. Such shrunken interfaces are also called role
interfaces.[2] ISP is intended to keep a system decoupled and thus
easier to refactor, change, and redeploy.
"D":
A. High-level modules should not depend on low-level modules. Both
should depend on abstractions. B. Abstractions should not depend on
details. Details should depend on abstractions.
You are violating (at least) these three sacred rules of OO. A and B should depend on abstractions (Interfaces). Same methods should be abstracted to one interface and different methods to different interfaces. S.O.L.I.D is more fundamental than design patterns. Design patterns are based on SOLID. Learn it first and you will have no more problems like this.
There are basically two ways to reuse code (when code is duplicated across two or more classes).
Inheritance: If all the participating classes (sharing duplicated code) are logically be put into a hierarchy where "is-a" relationship is followed than creating a base class, pull the common methods in the base class, and customize the subclass methods. (Consider using Template method pattern if there is a variation in method implementation across subclasses.)
Composition: If the participating classes do not follow "is-a" relationship and hence cannot be placed in a hierarchy, create a class and put all the reusable methods in that. Use the class wherever you wanted to reuse the methods via composition.
I have a common jar that uses some unmarshaling of a String object. The method should act differently depending on which application it is called from, how can I do that besides from the fact that I can identify the application by trying to load some unique class it has (don't like that). Is there some design pattern that solves this issue?
As I alluded to in my comment, the best thing to do is to break that uber-method up into different methods that encapsulate the specific behaviors, and likely also another method (used by all of the app-specific ones) that deals with the common behaviors.
The most important thing to remember is that behavior matters. If something is behaving differently in different scenarios, a calling application effectively cannot use that method because it doesn't have any control over what happens.
If you still really want to have a single method that all of your applications call that behaves differently in each one, you can do it, using a certain design pattern, in a way that makes sense and is maintainable. The pattern is called "Template Method".
The general idea of it is that the calling application passes in a chunk of logic that the called method wraps around and calls when it needs to. This is very similar to functional programming or programming using closures, where you are passing around chunks of logic as if it were data. While Java proper doesn't support closures, other JVM-based languages like Groovy, Scala, Clojure, JRuby, etc. do support closures.
This same general idea is very powerful in certain circumstances, and may apply in your case, but such a question requires very intimate knowledge of the application domain and architecture and there really isn't enough information in your posted question do dig too much deeper.
Actually, I think a good OO oriented solution is, in the common jar, to have one base class, and several derived classes. The base class would contain the common logic for the method being called, and each derived class would contain specific behavior.
So, in your jar, you might have the following:
public abstact class JarClass {
public method jarMethod() {
//common code here
}
}
public class JarClassVersion1 extends JarClass {
public method jarMethod() {
// initiailzation code specific to JarClassVerion1
super.jarMethod();
// wrapup code specific to JarClassVerion1
}
}
public class JarClassVersion2 extends JarClass {
public method jarMethod() {
// initiailzation code specific to JarClassVerion2
super.jarMethod();
// wrapup code specific to JarClassVerion2
}
}
As to how the caller works, if you are willing to design your code so that the knowledge of which derived class to use resides with the caller, then you obviously just have the caller create the appropriate derived class and call jarMethod.
However, I take it from your question, you want the knowledge of which class to use to reside in the jar. In that case, there are several solutions. But a fairly easy one is to define a factory method inside the jar which creates the appropriate derived class. So, inside the abstract JarClass, you might define the following method:
public static JarClass createJarClass(Class callerClass) {
if (callerClass.equals(CallerClassType1.class)) {
return new JarClassVersion1();
} else if (callerClass.equals(CallerClassType2.class)) {
return new JarClassVersion1();
// etc. for all derived classess
}
And then the caller would simply do the following:
JarClass.createJarClass(this.getClass()).jarMethod();
Recently, I have been writing many classes which have, apart from generic variant, some primitive variants, for example Foo<T>, IntFoo, DoubleFoo etc. First, I used to put every variant in separate files but I soon found out that the package content has become unreadable due to large number of classes with similar names. On the other hand, putting those in a separate package often results in a loss of cohesion and extra dependencies between packages.
In the meanwhile, I have come to the idea to have the following structure:
public class Foo {
public static class TypeFoo<T> { ... }
public static class IntFoo { ... }
public static class DoubleFoo { ... }
...
}
or
public class Foo {
public static class Type<T> { ... }
public static class Int { ... }
public static class Double { ... }
}
I am interested in two things:
Does any of these two approaches result in greater overhead when using only one inner class (e.g. int-variant of the class), compared to one-class-per-file approach? Does this overhead, if any, applies when there are inner interfaces instead?
Which of these two approaches is better, if any, or if none is good, what are the alternatives?
inner classes will be more of a pain in the long run, in my opinion. if you look at the way Microsoft named their animation classes, they had the same dilemma that you did. They chose to have tons of different classes, but as a consumer of these I have found that I prefer it to be this way.
to answer your first question, there should be no overhead. When java compiles inner classes it separates them into separate *.class files anyway, so in the end the result is the same. During compilation the parser will have to sift through a lot of Foo.* references but the extra time would be negligible.
Might be completely irrelevant to what you're doing, but you could consider replacing all these classes with a Builder (or otherwise known as Fluent Interface) pattern. If these classes implement a generic interface, you shouldn't need to expose them anywhere and can still keep them inside one builder class.
A good example of this would be MapMaker which probably has zillion different inner classes but the only thing you care about is the Map or ConcurrentMap instance you get out of it.