How to simplify a class without writing methods that are already simple? - java

I have a complex class and I want to simplify it by implementing a facade class (assume I have no control on complex class). My problem is that complex class has many methods and I will just simplify some of them and rest of the will stay as they are. What I mean by "simplify" is explained below.
I want to find a way that if a method is implemented with facade then call it, if not then call the method in complex class. The reason I want this is to write less code :) [less is more]
Example:
Facade facade = // initialize
facade.simplified(); // defined in Facade class so call it
// not defined in Facade but exists in the complex class
// so call the one in the complex class
facade.alreadySimple();
The options that comes to mind mind are:
Option 1: Write a class holding a variable of complex class and implement complex ones then implement simple ones with direct delegation:
class Facade {
private PowerfulButComplexClass realWorker = // initialize
public void simplified() {
// do stuff
}
public void alreadySimple() {
realWorker.alreadySimple();
}
// more stuff
}
But with this approach I will need to implement all the simple methods with just a single delegation statement. So I need to write more code (it is simple though)
Option 2: Extend the complex class and implement simplified methods but then both simple and complex versions of these methods will be visible.
In python I can achieve similar behaviour like this:
class PowerfulButComplexClass(object):
def alreadySimple(self):
# really simple
# some very complex methods
class Facade(object):
def __init__(self):
self.realworker = PowerfulButComplexClass()
def simplified(self):
# simplified version of complex methods in PowerfulButComplexClass
def __getattribute__(self, key):
"""For rest of the PowerfulButComplexClass' methods use them as they are
because they are simple enough.
"""
try:
# return simplified version if we did
attr = object.__getattribute__(self, key)
except AttributeError:
# return PowerfulButComplexClass' version because it is already simple
attr = object.__getattribute__(self.data, key)
return attr
obj = Facace()
obj.simplified() # call the one we have defined
obj.alreadySimple( # call the one defined in PowerfulButComplexClass
So what is the Java way to achieve this?
Edit: What I mean by "simplify": A complex method can be either a method with too many arguments
void complex method(arg1, arg2, ..., argn) // n is sufficiently large
or a set of related methods that will almost always called together to achieve a single task
outArg1 = someMethod(arg1, arg2);
outArg2 = someOtherMethod(outArg1, arg3);
actualResult = someAnotherMethod(outArg2);
so we want to have something like this:
String simplified(arg1, arg2, arg3) {
outArg1 = someMethod(arg1, arg2);
outArg2 = someOtherMethod(outArg1, arg3);
return someAnotherMethod(outArg2);
}

It's called Inheritence. Consider the following code:
class Complex {
public function complex() { /* Complex Function */ }
public function simple() { /* Already simple function */ }
}
class SimplifiedComplex extends Complex {
public function complex() { /* Simplify Here */ }
}
The simple() method will work on a SimplifiedComplex object.

I think you've already called it. I would go with Option 1. It provides the most flexibility given the rigidity of java.
I prefer it because it favors composition over inheritance. Although this creates more code, I find designs like this generally are easier to modify in the long run.
Inheritance should only be used to model strict "is a" relationships where the subclass necessarily has all the properties and behaviors of the base class. If you're using inheritance for anything else your asking for trouble.
Finally, I don't buy into the idea of "Less Is More"(Insert incredibly concise, indecipherable perl example here). I buy into the principle of "Code should be as simple as it needs to be and no simpler".

Depending on your use case, you might want to create a facade in front of some of the functionality in complex class by delegating (Option 1), and instead of providing support for the rest of the functionality in complex class, you provide means to access complex class directly (getComplexClass).
This might make the design clearer. Consider, for example, a complex class handling most of the features of a bank system. Creating a class named "Account" that has access to the complex class but only uses the methods relevant for a bank account helps the design. For convenience, the Account class could have a method getBankSystemForAccount or something similar.

This is ugly in Java, but you can write a function that takes the name of the method you want to call, and a parameter list, and use reflection to find the appropriate method to call. This will be conceptually similar to how you'd do it in Python, except much uglier.

Related

Java - correct way to delegate methods

My program gets information from an external source (can be a file, a database, or anything else I might decide upon in the future).
I want to define an interface with all my data needs, and classes that implement it (e.g. a class to get the data from a file, another for DB, etc...).
I want the rest of my project to not care where the data comes from, and not need to create any object to get the data, for example to call "DataSource.getSomething();"
For that I need DataSource to contain a variable of the type of the interface and initialize it with one of the concrete implementations, and expose all of its methods (that come from the interface) as static methods.
So, lets say the interface name is K, and the concrete implementations are A,B,C.
The way I do it today is:
public class DataSource {
private static K myVar = new B();
// For **every** method in K I do something like this:
public static String getSomething() {
return myVar.doSomething();
}
...
}
This is very bad since I need to copy all the methods of the interface and make them static just so I can delegate it to myVar, and many other obvious reasons.
What is the correct way to do it? (maybe there is a design pattern for it?)
**Note - since this will be the backbone of many many other projects and I will use these calls from thousands (if not tens of thousands) code lines, I insist on keeping it simple like "DataSource.getSomething();", I do not want anything like "DataSource.getInstance().getSomething();" **
Edit :
I was offered here to use DI framework like Guice, does this mean I will need to add the DI code in every entry point (i.e. "main" method) in all my projects, or there is a way to do it once for all projects?
The classes using your data source should access it via an interface, and the correct instance provided to the class at construction time.
So first of all make DataSource an interface:
public interface DataSource {
String getSomething();
}
Now a concrete implementation:
public class B implements DataSource {
public String getSomething() {
//read a file, call a database whatever..
}
}
And then your calling class looks like this:
public class MyThingThatNeedsData {
private DataSource ds;
public MyThingThatNeedsData(DataSource ds) {
this.ds = ds;
}
public doSomethingRequiringData() {
String something = ds.getSomething();
//do whatever with the data
}
}
Somewhere else in your code you can instantiate this class:
public class Program {
public static void main(String[] args) {
DataSource ds = new B(); //Here we've picked the concrete implementation
MyThingThatNeedsData thing = new MyThingThatNeedsData(ds); //And we pass it in
String result = thing.doSomethingThatRequiresData();
}
}
You can do the last step using a Dependency Injection framework like Spring or Guice if you want to get fancy.
Bonus points: In your unit tests you can provide a mock/stub implementation of DataSource instead and your client class will be none the wiser!
I want to focus in my answer one important aspect in your question; you wrote:
Note - I insist on keeping it simple like "DataSource.getSomething();", I do not want anything like "DataSource.getInstance().getSomething();"
Thing is: simplicity is not measured on number of characters. Simplicity comes out of good design; and good design comes out of following best practices.
In other words: if you think that DataSource.getSomething() is "easier" than something that uses (for example) dependency injection to "magically" provide you with an object that implements a certain interfaces; then: you are mistaken!
It is the other way round: those are separated concerns: one the one hand; you should declare such an interface that describes the functionality that need. On the other hand, you have client code that needs an object of that interface. That is all you should be focusing on. The step of "creating" that object; and making it available to your code might look more complicated than just calling a static method; but I guarantee you: following the answer from Paolo will make your product better.
It is sometimes easy to do the wrong thing!
EDIT: one pattern that I am using:
interface SomeFunc {
void foo();
}
class SomeFuncImpl implements SomeFunc {
...
}
enum SomeFuncProvider implements SomeFunc {
INSTANCE;
private final SomeFunc delegatee = new SomeFuncImpl();
#Override
void foo() { delegatee.foo(); }
This pattern allows you to write client code like
class Client {
private final SomeFunc func;
Client() { this(SomeFuncProvider.INSTANCE); }
Client(SomeFunc func) { this.func = func; }
Meaning:
There is a nice (singleton-correctway) of accessing an object giving you your functionality
The impl class is completely unit-testable
Client code uses dependency injection, and is therefore also fully unit-testable
My program gets information from an external source (can be a file, a database, or anything else I might decide upon in the future).
This is the thought behind patterns such as Data Access Object (short DAO) or the Repository pattern. The difference is blurry. Both are about abstracting away a data source behind a uniform interface. A common approach is having one DAO/Repository class per business- or database entity. It's up to you if you want them all to behave similarly (e.g. CRUD methods) or be specific with special queries and stuff. In Java EE the patterns are most often implemented using the Java Persistence API (short JPA).
For that I need DataSource to contain a variable of the type of the
interface and initialize it with one of the concrete implementations,
For this initialization you don't want to know or define the type in the using classes. This is where Inversion Of Control (short IOC) comes into play. A simple way to archieve this is putting all dependencies into constructor parameters, but this way you only move the problem one stage up. In Java context you'll often hear the term Context and Dependency Injection (short CDI) which is basically an implementation of the IOC idea. Specifically in Java EE there's the CDI package, which enables you to inject instances of classes based on their implemented interfaces. You basically do not call any constructors anymore when using CDI effectively. You only define your class' dependencies using annotations.
and expose all of its methods (that come from the interface)
This is a misconception. You do want it to expose the interface-defined method ONLY. All other public methods on the class are irrelevant and only meant for testing or in rare cases where you want to use specific behavior.
as static methods.
Having stateful classes with static method only is an antipattern. Since your data source classes must contain a reference to the underlying data source, they have a state. That said, the class needs a private field. This makes usage through static methods impossible. Additionally, static classes are very hard to test and do not behave nicely in multi-threaded environments.

How can I initialize interdependent final references?

I have a class and a factory function that creates new anonymous class objects extending that class. However, the anonymous class objects all have a method in which there are references to other objects. In my full program, I need this to create and combine parsers, but I've stripped down the code here.
class Base{
public Base run(){
return null;
}
static Base factory(final Base n){
return new Base(){
public Base run(){
return n;
}
};
}
}
public class CircularReferences{
public static void main(String args[]){
final Base a, b;
a = Base.factory(b);
b = Base.factory(a);
}
}
I get CircularReferences.java:17; error: variable b might not have been initialized. That's true, it wasn't, but can't I set aside space for these variables and then initialize them using references to these spaces, which will be filled with the proper values before they are ever actually used? Can I perhaps use new separately from the constructor? How can I create these variables so they reference each other?
The quick answer is that you can't do this. If you absolutely must do something like this, then use a private setter on the class and bind things together after they are constructed (i.e. use enforced immutability instead of final fields). Hopefully it's obvious that I don't think this is a good idea - I just wanted to provide a answer to your actual question before I answer the way that I really want to.
OK - now that is out of the way, here's the real response that is called for here:
Generally speaking, this sort of situation is a strong indicator that refactoring is needed to separate concerns. In other words, the Base class is probably trying to be responsible for too many things.
I realize that the example is contrived, but think about what functionality requires the circular dependency, then factor that functionality out into a separate class/object that then gets passed to both of the Base constructors.
In complex architectures, circular dependency chains can get pretty big, but strictly forcing final fields is great way to look for those types of refactoring opportunities.
If you have a concrete example, I'd be happy to help with some refactoring suggestions to break a dependency like this.
concrete example provided - here's my suggestion:
It seems like there is a concern of obtaining an appropriate ParseStrategy based on a token. A ParseStrategyProvider. So there would be a TopLevelParseStrategy that reads the next token, looks up the appropriate parse strategy, and executes it.
TopLevelParseStrategy would hold a final reference to the ParseStrategyProvider.
The ParseStrategyProvider would then need to have a registration method (i.e. registerStrategy(token, parseStrategy) ).
This isn't functionally much different from doing this with enforced immutability via a private setter (the registerStrategy method is for all intents and purposes the same as the private setter), but the design is much more extensible.
So you'd have:
public ParseStrategy createParser(){
ParseStrategyProvider provider = ParseStrategyProvider.create();
TopLevelParseStrategy topLevel = new TopLevelParseStrategy(provider);
provider.registerStrategy("(", topLevel);
// create and register all of your other parse strategies
return topLevel;
}

Inheritance with unknown descendents

Let's say I have a labyrinth with AI characters, where the users define the characters. Each user provide the classes for their individual characters. All the characters/classes extend some class/type C which has method control().
I want to do call each user's control() method, but I don't know how many users there will be or what classes they will provide. How do I resolve this problem?
EDIT: I wanted to convey that I do not know how many subclasses there are, or what their names are. Therefore, I am not able to place those subclasses in the code statically.
EDIT 2: Is there a way of doing this WITHOUT using reflection? I am aware that reflection solves the problem, but I hoped there was a cleaner implementation.
EDIT 3: It completely necessary to have the users create the different classes, as the point of the program is to test competing AIs.
btw, I am writing this in Java.
First of all, you need to decide if the different characters' behavior is really going to be as differentiated as to need Java code to implement the particular behaviors. Perhaps the behavior can be expressed with a single class and only modified by setting different values for parameters such as speed, health, attack strength etc. In this case you would get rid of the inheritance problem altogether and use a single class while users would only provide different configurations.
Now, if you really need very custom behavior and load custom Java classes, I see two main solutions.
First is the standard one. It uses just a tiny bit of reflection. You define an interface, for example:
public interface C {
void control(); //Params skipped for brevity
}
Now, your users create classes which implement this interface. The only problem is how to create an instance of the player's class. Once you have it, you call its control() or other methods via the interface. First, users need to make this class loadable. Thiscan be done through the network or in other complex ways but the simplest is that they put their .class or .jar file in their classpath when they run your application. Now all you need is to create an instance of the class. Assuming you specify the requirement that the class have a zero-argument constructor (you can define a method in your interface to load some configuration and perform initialization later on), you would be doing something like:
C gameCharacter = (C)Class.forName("your.fully.qualified.ClassName").newInstance();
Apart from error handling, that's all the reflection you need. You can now call all methods of interface C on your gameCharacter object - without knowing who or how wrote it and what exactly the methods do.
The other solution would be to use Groovy or another similar language to compile and run code on the fly. In this case you don't need the custom JAR in the classpath and you can even get around the need to know the name of the class to be loaded. Your user can provide the Java code of control() method in the form of text, and you can have a stub class whose control() method only compiles and executes the Groovy code the user provided. This may be more convenient, but requires the custom character code to be provided to you as source code, not compiled JAR, which may be a problem for some users. Also, this solution is more convenient if the implementations are going to be short and self-contained while the separate JAR and loading via reflection is better if the loaded code is more complex, uses helper classes apart from the main class etc.
The whole thing about inheritance is that you don't need to know the exact type.
If you have a reference to an object that is of type C or a subclass of C, you can call your "control()" method on them and it will call the right method, i.e. the one implemented by the child class.
Not knowing how many users means you'll have to use a list or something and loop over it.
public class AIGame {
public static void main(String[] args) {
List<AICharacter> characters = new ArrayList<AICharacter>();
characters.add( new ReallySmartAICharacter() );
characters.add( new ReallyDumbAICharacter() );
for ( AICharacter c : characters ) {
c.control();
}
}
}
interface AICharacter {
public void control();
}
class ReallySmartAICharacter implements AICharacter {
#Override
public void control() {
// TODO do something clever here
}
}
class ReallyDumbAICharacter implements AICharacter {
#Override
public void control() {
// TODO do something stupid here
}
}
If all the characters extend some common class, for convenience let's call it Character, then you can use polymorphism to dynamically call each of the control() methods.
In other words, if each subclass of Character overrides control(), then all you need to do is call it normally and Java will figure out which control() method to call.
e.g.
Character[] characters = new Character[2];
characters[0] = new Man(); // Man is a subclass of Character
characters[1] = new Woman(); // same with Woman
character[0].control(); // <- this will call the control() method as defined in Man
The mechanism for this is called late (or dynamic) binding, which you can read more about here: http://en.wikipedia.org/wiki/Late_binding
If the subclasses are not known at compile-time (i.e. they are specified at run-time), then you will need to use reflection to load them.
To keep track of each user, use a dynamically sized List type like a LinkedList or ArrayList. This way you don't need to know how many users there are beforehand.

How to change a method's behavior according to the application which is calling it?

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();

Architecture/Design of a pipeline-based system. How to improve this code?

I have a pipeline-based application that analyzes text in different languages (say, English and Chinese). My goal is to have a system that can work in both languages, in a transparent way. NOTE: This question is long because it has many simple code snippets.
The pipeline is composed of three components (let's call them A, B, and C), and I've created them in the following way so that the components are not tightly coupled:
public class Pipeline {
private A componentA;
private B componentB;
private C componentC;
// I really just need the language attribute of Locale,
// but I use it because it's useful to load language specific ResourceBundles.
public Pipeline(Locale locale) {
componentA = new A();
componentB = new B();
componentC = new C();
}
public Output runPipeline(Input) {
Language lang = LanguageIdentifier.identify(Input);
//
ResultOfA resultA = componentA.doSomething(Input);
ResultOfB resultB = componentB.doSomethingElse(resultA); // uses result of A
return componentC.doFinal(resultA, resultB); // uses result of A and B
}
}
Now, every component of the pipeline has something inside which is language specific. For example, in order to analyze Chinese text, I need one lib, and for analyzing English text, I need another different lib.
Moreover, some tasks can be done in one language and cannot be done in the other. One solution to this problem is to make every pipeline component abstract (to implement some common methods), and then have a concrete language-specific implementation. Exemplifying with component A, I'd have the following:
public abstract class A {
private CommonClass x; // common to all languages
private AnotherCommonClass y; // common to all languages
abstract SomeTemporaryResult getTemp(input); // language specific
abstract AnotherTemporaryResult getAnotherTemp(input); // language specific
public ResultOfA doSomething(input) {
// template method
SomeTemporaryResult t = getTemp(input); // language specific
AnotherTemporaryResult tt = getAnotherTemp(input); // language specific
return ResultOfA(t, tt, x.get(), y.get());
}
}
public class EnglishA extends A {
private EnglishSpecificClass something;
// implementation of the abstract methods ...
}
In addition, since each pipeline component is very heavy and I need to reuse them, I thought of creating a factory that caches up the component for further use, using a map that uses the language as the key, like so (the other components would work in the same manner):
public Enum AFactory {
SINGLETON;
private Map<String, A> cache; // this map will only have one or two keys, is there anything more efficient that I can use, instead of HashMap?
public A getA(Locale locale) {
// lookup by locale.language, and insert if it doesn't exist, et cetera
return cache.get(locale.getLanguage());
}
}
So, my question is: What do you think of this design? How can it be improved? I need the "transparency" because the language can be changed dynamically, based on the text that it's being analyzed. As you can see from the runPipeline method, I first identify the language of the Input, and then, based on this, I need to change the pipeline components to the identified language. So, instead of invoking the components directly, maybe I should get them from the factory, like so:
public Output runPipeline(Input) {
Language lang = LanguageIdentifier.identify(Input);
ResultOfA resultA = AFactory.getA(lang).doSomething(Input);
ResultOfB resultB = BFactory.getB(lang).doSomethingElse(resultA);
return CFactory.getC(lang).doFinal(resultA, resultB);
}
Thank you for reading this far. I very much appreciate every suggestion that you can make on this question.
The factory idea is good, as is the idea, if feasible, to encapsulate the A, B, & C components into single classes for each language. One thing that I would urge you to consider is to use Interface inheritance instead of Class inheritance. You could then incorporate an engine that would do the runPipeline process for you. This is similar to the Builder/Director pattern. The steps in this process would be as follows:
get input
use factory method to get correct interface (english/chinese)
pass interface into your engine
runPipeline and get result
On the extends vs implements topic, Allen Holub goes a bit over the top to explain the preference for Interfaces.
Follow up to you comments:
My interpretation of the application of the Builder pattern here would be that you have a Factory that would return a PipelineBuilder. The PipelineBuilder in my design is one that encompases A, B, & C, but you could have separate builders for each if you like. This builder then is given to your PipelineEngine which uses the Builder to generate your results.
As this makes use of a Factory to provide the Builders, your idea above for a Factory remains in tact, replete with its caching mechanism.
With regard to your choice of abstract extension, you do have the choice of giving your PipelineEngine ownership of the heavy objects. However, if you do go the abstract way, note that the shared fields that you have declared are private and therefore would not be available to your subclasses.
I like the basic design. If the classes are simple enough, I might consider consolidating the A/B/C factories into a single class, as it seems there could be some sharing in behavior at that level. I'm assuming that these are really more complex than they appear, though, and that's why that is undesirable.
The basic approach of using Factories to reduce coupling between components is sound, imo.
If I'm not mistaken, What you are calling a factory is actually a very nice form of dependency injection. You are selecting an object instance that is best able to meet the needs of your parameters and return it.
If I'm right about that, you might want to look into DI platforms. They do what you did (which is pretty simple, right?) then they add a few more abilities that you may not need now but you may find would help you later.
I'm just suggesting you look at what problems are solved now. DI is so easy to do yourself that you hardly need any other tools, but they might have found situations you haven't considered yet. Google finds many great looking links right off the bat.
From what I've seen of DI, it's likely that you'll want to move the entire creation of your "Pipe" into the factory, having it do the linking for you and just handing you what you need to solve a specific problem, but now I'm really reaching--my knowledge of DI is just a little better than my knowledge of your code (in other words, I'm pulling most of this out of my butt).

Categories

Resources