I often wanted to be able to decorate java-classes properly, that is add behaviour to them. I know mixins from ruby, and i know that they can get terribly confusing.
I came up with the theoretical idea of having a language-construct like this:
package org.test.decorator;
public decorator ListPatch<E> extends List<E> {
public E last() {
return this.get(this.size() - 1);
}
}
this would give access to public members of List and the Decorator itself.
Then in a class i could use:
package org.test.decorator;
decoration org.test.decorator.ListPatch;
public MyClass {
public void foo() {
List<String> list = Lists.newArrayList();
list.add("test");
System.out.println(list.last());
}
}
I don't have that much knowledge about compilers, so I wondered if something like that was possible. Also if it actually would be an improvement.
Sure, it's possible.
The fact that Scala compiles to bytecode (and has a fairly straight forward mapping from Scala classes to bytecode classes) and supports mixins proves this.
Here's how your sample code looks in Scala syntax:
class ListTest {
// ...
}
trait ListPatch {
def last {
// ...
}
}
object Main {
def main(args: Array[String]) {
val list = new ListTest() with ListPatch;
list.add("test")
println(list.last)
}
}
Scala compiles this by adding an axillary class Main$$anon$1 which composes ListTest and ListPatch.
The motto for the Java developers have always been (and will probably always be) "If in doubt, leave it out." though.
Related questions:
Implement Mixin In Java?
Not really an Answer to your question but you can solve this problem with inversion of control/dependency injection (just like you did in your code)
basically:
don't use "new ArrayList()" but instead some factory like "injector.new(ArrayList.class)". This injector can now override the wanted class and return an Object which extends ArrayList decorated with your methods.
Your idea sounds much like Extension methods in C#.
Extension methods enable you to "add" methods to existing types without creating a new derived type, recompiling, or otherwise modifying the original type.
In C# you would write your example as:
public static class ListExtensions
{
public E Last(this List<E> list)
{
return list[list.Count - 1];
}
}
Using it like this:
List<String> list = new List<String>();
list.Add("test");
Console.WriteLine(list.Last());
So, from a design perspective it can certainly be designed and added. However, there are other considerations that come into play when adding something to an existing language, such as syntax conflicts, backwards compatibility, edge cases, and cost of designing and coding it versus the benefits it provides.
Eric Lippert has a great blog about Extension Properties (a natural extension of Extension Methods) in C#, and in the second part he highlights some of the aspects that affect why doesn't product X have feature Y?, which I'm sure also applies to Java and its development.
Related
I came up with this question writing specific code, but I'll try to keep the question as generic as possible.
Other similar question refer to C# which seems to have some language specific handling for this and below code is Java, but again let's try to keep it generic.
Let's say I have class A which implements interface I.
This is useful to me cause I can implement methods that use A only as a I type and abstract the implementation.
Let's now say, I have class B which implements all methods in interface I, but it's never referred to as only I.
Let's now say, I have class B which implements methods that have the same name/signature as the ones in interface I, but it doesn't implements the interface.
Should I always explicitly implement I?
Even if I don't use it (though I might in the future) for type abstraction?
A more meaningful, even if probably not realistic, example would be:
interface Printable {
String print()
class A implements Printable {
//code...
String print(){return "A";}
//code...
}
class B {
//code...
String print(){return "B";}
void otherMethod(){/*code*/}
//code...
}
class Test {
Printable a = new A();
System.out.println(a.print());
B b = new B();
b.otherMethod();
System.out.println(b.print());
}
Are there any drawbacks on explicitly implementing, or not, the interface Printable?
The only one I can think of is scalability for the second case.
In the sense that if one day I'll want to explicitly use it as Printable, I'll be able to do so without any more effort.
But is there anything else (patterns, optimization, good programming, style, ..) I should take into consideration?
In some cases the type hierarchy will affect the method call cost due to not playing well with JIT method inlining. An example of that can be found in Guava ImmutableList (and others) offer awful performance in some cases due to size-optmized specializations #1268 bug:
Many of the guava Immutable collections have a cute trick where they have specializations for zero (EmptyImmutableList) and one (SingletonImmutableList) element collections. These specializations take the form of subclasses of ImmutableList, to go along with the "Regular" implementation and a few other specializations like ReverseImmutable, SubList, etc.
Unfortunately, the result is that when these subclasses mix at some call site, the call is megamorphic, and performance is awful compared to classes without these specializations (worse by a factor of 20 or more).
I don't think there is a simple correct answer for this question.
However, if you do not implement the method, you should do this:
public void unusedBlahMethod() {
throw new UnsupportedOperationException("operation blah not supported");
}
The advantages of omitting the unused method are:
You save yourself time and money (at least in the short term).
Since you don't need the method, it might not be clear to you how best to implement it anyway.
The disadvantages of omitting the method are:
If you need the method in the future, it will take longer to add it as you may have to refamiliarize yourself with the code, check-out, re-test, etc.
Throwing an UnsupportedOperationException may cause bugs in the future (though good test coverage should prevent that).
If you're writing disposable code, you don't need to write interfaces, but one day you might notice, that you should've taken your time and write an interface.
The main advantage and purpose of interfaces is the flexibility of using different implementations. I can put something, that offers the same functionality inside a method, I can create a fake of it for test purposes and I can create a decorator that behaves like the original object, but can log the stuff.
Example:
public interface A {
void someMethod();
}
public class AImplementation {
#Override
public void someMethod() {
// implementation
}
}
public class ADecorator {
private final A a;
public ADecorator(A a) {
this.a = a;
}
#Override
public void someMethod() {
System.out.println("Before method call");
a.someMethod();
System.out.println("After method call");
}
}
Nice side effect: ADecorator works with every implementation of A.
The cost for this flexibility isn't that high and if your code will live a little bit longer, you should take it.
In Swift, you can create extension of existing class to add additional functions to the existing class whenever it is needed. This also helps to avoid creating a subclass of the existing class.
I was just wondering if there is a similar function exist in Java? or is it the only way to add additional methods to a existing Java class is to create a subclass of the existing class?
No, vanilla Java does not feature extension methods. However, Lombok adds many useful features - including extension methods syntax - thanks to its annotations and bytecode generation.
You can use its #ExtensionMethod annotations to "convert" existing static methods to extension methods. The first parameter of the static methods basically becomes this. For example, this is a valid Lombok-enhanced Java code:
import lombok.experimental.ExtensionMethod;
#ExtensionMethod({java.util.Arrays.class, Extensions.class})
public class ExtensionMethodExample {
public String test() {
int[] intArray = {5, 3, 8, 2};
intArray.sort();
String iAmNull = null;
return iAmNull.or("hELlO, WORlD!".toTitleCase());
}
}
class Extensions {
public static <T> T or(T obj, T ifNull) {
return obj != null ? obj : ifNull;
}
public static String toTitleCase(String in) {
if (in.isEmpty()) return in;
return "" + Character.toTitleCase(in.charAt(0)) +
in.substring(1).toLowerCase();
}
}
Note that Lombok extension methods can be "invoked" on null objects - as long as the static method is null-safe, NullPointerException will not be thrown, as this is basically translated to static method call. Yes - it comes down to syntax sugar, but I guess this is still more readable than the usual static methods calls.
Aside from that, you can use some other JVM language with Java interoperability, if that's OK in your project. For example, Kotlin comes with extension methods functionality, as well as some useful extensions already defined in the standard library. Here's a Kotlin and Lombok comparison.
The Decorator Pattern is perhaps the closest match. It uses interface to maintain the type compatibility and composition to enhance the existing class' function. It's not the same principle as the one you're describing but might serve the same purpose.
It can be done in other languages for JVM, like Scala, Groovy or Closure.
For example in Groovy:
List.metaClass.printSize = {
println delegate.size()
}
[1,2,3].printSize() //prints 3
In Scala you can use implicit class:
implicit class PrefixedString(val s: String) {
def prefix = "prefix_" + s
}
"foo".prefix // returns "prefix_foo"
Please have a look at this article.
An important remark is that Groovy/Scala source code is intended to be compiled to Java bytecode so that the resulting classes can be used in Java code.
I looked at an example where delegation pattern is explained for java. Didn't find much use for it (excuse the ignorance) as i feel it lacks the flexibility in objective-c. Is there way to dynamically set the delegate object as one can do in objective-c. Isn't that the whole point of delegation? My knowledge of java is very preliminary , so please explain a bit in detail.
I think there are many ways ways to implement delegation pattern in Java, but probably none which feels like a built-in.
Take a look at the Wikipedia example. Your basic option is to manually implement an interface, and then simply forward the calls to a concrete instance which you can change during run-time as much as you wish.
Now depending on what tools you have and can use, you can make this forwarding more automatic. One idea, is to use aspect-oriented programming, like AspectJ.
Having an aspect compiler (or runtime) you could utilize annotations and come up with a simple extension to the language:
class Person {
#Delegate Animal animal;
...
}
You'd then have to write an aspect that finds #Delegates and automatically adds forwarding methods in the class'es (eg. Person) interface.
If you are able to use a more groovy JVM language, then you wouldn't even have to write a single line of code, because such languages have delegates in the standard library:
You can have a look here, to see how it's done in Groovy. (essentialy exactly like the Person example syntax I came up with... but built-in!)
This is how you fake a functional idiom in Java. Yes, it's hideous. If you want elegant functional idioms, use a language that doesn't treat functions like red-headed step-children. If you want more compile time safety, you can of course use more specific interface definitions so that you don't get IndexOutOfBounds and ClassCastException all over the place from programming errors.
public interface DelegatedFunction<T> {
T call(Object... args);
}
public class DoesSomeDelegatedTask {
private List<DelegatedFunction<String>> delegatedFunctions = new ArrayList<>(1);
public void addFunction(DelegatedFunction<String> function) {
delegatedFunctions.add(function);
}
public void execute() {
for (DelegatedFunction<String> function: delegatedFunctions) {
System.out.println(function(something, someotherthing, whatever));
}
}
}
public class Main {
public static void main(String[] args) throws Exception {
DoesSomeDelegateTask doer = new DoesSomeDelegatedTask();
doer.addFunction(new DelegatedFunction<String> () {
#Override
public String call(Object... args) {
return ((SomeThings) args[0]).whatever((SomeOtherThing) args[1]//you get the idea
}
}
doer.execute();
}
}
The problem: I'd like to be able to generically access in Java any property/field on a Java ojbect similarly to how a dynamic language (think Groovy, JavaScript) would. I won't know at the time I'm writing this plumbing code what type of object it is or what the property/field name will be. But I will know the property/field name when I go to use it.
My current solution: So far I've written a simple wrapper class that uses java.beans.Introspector to grab the properties of a Bean/POJO and expose them as a Map<String, Object>. It's crude but works for simple cases.
My question is what other methodologies are there for approaching this problem besides reflection / converting to a Map?
Before I go too much further down this path, I'd like to know if anyone knows how I could cannibalize something out of Rhino or perhaps javax.script.* which has a well thought out implementation of this concept. Or perhaps an entirely different approach that I haven't considered.
Edit: yes I'm familiar with reflection (which I believe is what Introspector is using under the hood anyway). I was just curious if there was any other well thought out solutions.
Edit 2: It appears that the most popular answers involve 1) reflection either directly or via helper classes, and/or 2) mapping to interfaces which implement the desired class members. I'm really intrigued by the comment which talks about leveraging Groovy. Since Groovy has true duck-typing and it is a JVM language, is there a way to make a simple helper in Groovy and call it from Java? This would be really cool and probably more flexible and perform better.
Answer: I marked Mike's answer as the best since it is a complete concept which comes the closest. I probably won't go that route for this particular case, but it is certainly a useful approach. Anyone looking through this should be sure to read the conversations on here as there is a lot of useful info in there as well.
Thanks!
If you know the set of APIs that you want to expose, say you know you want access to a length method and an iterator method, you can define an interface:
public interface TheInterfaceIWant {
int length();
void quack();
}
and you want to be able to use this interface to access corresponding methods on instances that do not implement this interface, you can use Proxy classes : http://download.oracle.com/javase/1.4.2/docs/api/java/lang/reflect/Proxy.html
So you create a proxy
final Object aDuck = ...;
TheInterfaceIWant aDuckWrapper = (TheInterfaceIWant) Proxy.newProxyInstance(
TheInterfaceIWant.class.getClassLoader(),
new Class[] { TheInterfaceIWant.class },
new InvocationHandler() {
public Object invoke(
Object proxy, Method method, Object[] args)
throws Throwable {
return aDuck.getClass().getMethod(
method.getName(), method.getParameterTypes()).invoke(aDuck, args);
}
});
Then you can use the wrapper as you would the duck in a dynamically typed language.
if (aDuckWrapper.length() > 0) {
aDuckWrapper.quack();
}
Here's a full length runnable example that prints "Quack" four times using a wrapper:
import java.lang.reflect.*;
public class Duck {
// The interface we use to access the duck typed object.
public interface TheInterfaceIWant {
int length();
void quack();
}
// The underlying instance that does not implement TheInterfaceIWant!
static final class Foo {
public int length() { return 4; }
public void quack() { System.out.println("Quack"); }
}
public static void main(String[] args) throws Exception {
// Create an instance but cast away all useful type info.
final Object aDuck = new Foo();
TheInterfaceIWant aDuckWrapper = (TheInterfaceIWant) Proxy.newProxyInstance(
TheInterfaceIWant.class.getClassLoader(),
new Class[] { TheInterfaceIWant.class },
new InvocationHandler() {
public Object invoke(
Object proxy, Method method, Object[] args)
throws Throwable {
return aDuck.getClass().getMethod(
method.getName(), method.getParameterTypes()).invoke(aDuck, args);
}
});
for (int n = aDuckWrapper.length(); --n >= 0;) {
// Calling aDuck.quack() here would be invalid since its an Object.
aDuckWrapper.quack();
}
}
}
Another method that I just came across which leverages (abuses?) type erasure is kind of interesting:
http://rickyclarkson.blogspot.com/2006/07/duck-typing-in-java-and-no-reflection.html
I'm not sure that I buy that this is much different from simply using the interfaces directly but perhaps it is useful to someone else.
Take a look at the methods of java.lang.Class and at the reflection API: java.lang.reflect.*
We've got a set of classes which derive from a common set of interfaces such that
IFoo-> BasicFoo, ReverseFoo, ForwardFoo
IBar -> UpBar, DownBar, SidewaysBar
IYelp -> Yip, Yap, Yup
wherein the constructor for the Foo's looks like Foo(IBar, IYelp) These items are used throughout the project.
There exists another class which has a method whose signature is public double CalcSomething(IFoo, IAnotherClass) that is applied at some point to each and every Foo. We've had a request come down from above that one particular object composition, let's say a BasicFoo(UpBar,Yip), use a different algorithm other than the one found in CalcSomething.
My first instinct was to say let's change the IFoo interface so we can move the logic down to the Foo class level, change the constructor to be Foo(IBar, IYelp, IStrategy) and then have the Foo objects encapsulate this logic. Unfortunately we've also been told the design of the architecture stipulates that there be no dependencies between IFoo, it's implementations and IAnotherClass. They're adamant about this.
Ok, sure, then I thought I might use a visitor pattern but... how? The whole point of making the composition was so that no other class could see the implementation details. Reflection to look inside the objects, totally breaking encapsulation? Oh hell no.
So I've come here because I'm at a loss. Does anyone have any suggestions how we could treat a special case of one of the compositions without modifying the composition or breaking encapsulation? There has got to be a simple solution I'm over-looking.
Edit:
Removed offending beginning.
Changed "handled specially" into a more descriptive meaning.
A CalculationFactory that chooses an appropriate algorithm based on the type of IFoo you provide would solve the problem (at the cost of a conditional):
interface ICalcSomethingStrategy {
public double CalcSomething(IFoo, IAnotherClass);
}
CalcSomethingStrategyFactory {
ICalcSomethingStrategy CreateCalcSomethingStrategy(IFoo foo) {
// I'm not sure whether this is the idiomatic java way to check types D:
if (foo.Bar instanceof UpBar && foo instanceof Yip) {
return new UnusualCalcSomethingStrategy();
} else {
return new StandardCalcSomethingStrategy();
}
}
}
In the spirit of KISS I would add a method isSpecial() to IFoo, and use that to decide which algorithm to use in CalcSomething().
This assumes that this is the only special case.
There's no way for calcSomething to avoid having the knowledge needed to do the "special" behavior, but other than that, you can maintain most of your encapsulation this way.
Create a marker interface IQualifyForSpecialTreatment which extends IFoo. Extend BasicFoo to SpecialBasicFoo, and have it implement IQualifyForSpecialTreatment.
interface IQualifyForSpecialTreatment extends IFoo {
}
class SpecialBasicFoo extends BasicFoo implements IQualifyForSpecialTreatment {
...
}
You can then add another flavor of calcSomething:
calcSomething (IQualifyForSpecialTreatment foo, IAnotherClass whatever) {
... perform "special" variant of calculation
}
calcSomething (IFoo foo, IAnotherClass whatever) {
... perform "normal" variant of calculation
}