I would like to ask for your help regarding the following problem.
There is an interface which has more implementations:
public interface MyInterface {
void method();
}
public class MyInterfaceA implements MyInterface
public class MyInterfaceB implements MyInterface
and there is a class which uses these implementations of the interface in its different methods:
public class MyClass {
public void firstMethod() {
new MyInterfaceA().method();
}
public void secondMethod() {
new MyInterfaceB().method();
}
}
My problem is that I wouldn't like to create new specific instances in the methods of the class, so somehow I would like to hide which implementation is used.
Do you know a nice solution for this? Is there any design pattern what I can use? How can I hide the concrete implementations or I cannot?
Thanks for your answers in advance!
For example, you can receive the implementations in the constructor of MyClass and further use it. It helps you to hide the specific implementations.
public class MyClass {
private MyInterface one;
private MyInterface two;
private MyClass(MyInterface one, MyInterface two) {
this.one = one;
this.two = two;
}
public void firstMethod() {
one.method();
}
public void secondMethod() {
two.method();
}
}
You can apply the Factory pattern:
class Factory {
public MyInterface a() { return new MyInterfaceA(); }
public MyInterface b() { return new MyInterfaceB(); }
}
public class MyClass {
private Factory factory;
public MyClass(Factory factory) { this.factory = factory; }
public void firstMethod() {
factory.a().method();
}
public void secondMethod() {
factory.b().method();
}
}
Inside the Factory class you can cache the objects created if necessary.
Related
My program takes data from different file types and inserts them into different DBs depending on the department which uploaded the file.
To accomplish this, I have a base abstract class AbstractHandler which has some methods which are unimplemented and some which are common to all children. Two types of abstract classes extend from this class, InputTypeAHandler, InputTypeBHandler, etc. and OutputTypeAHandler, OutputTypeBHandler, etc. These abstract classes also implement some more methods but not all.
I have concrete classes which I want to extend from these two types of classes and which will implement some more methods specific to every class. For example,
abstract class AbstractHandler {
public void method1() {
// ....
}
public abstract void method2();
public abstract void method3();
public abstract void method4();
}
abstract class InputTypeAHandler extends AbstractHandler {
#Override
public void method2() {
// ....
}
}
abstract class OutputTypeBHandler extends AbstractHandler {
#Override
public void method3() {
// ....
}
}
public class ConcreteHandler1 extends InputTypeAHandler, OutputTypeBHandler {
#Override
public void method4() {
// ....
}
}
public class ConcreteHandler2 extends InputTypeCHandler, OutputTypeAHandler {
#Override
public void method4() {
// ....
}
}
Since Java does not allow multiple inheritance, how do I do this?
You seem to implement some kind of conversion between any pair of A,B,C... types (perhaps formats?). If it is the case, the AbstractHandler probably has multiple responsibilities. Split its logic to part involving source format and part involving target format. You can inspire in converter pattern or GoF Bridge pattern.
I use lombok and the power of interfaces for this:
public class Test implements InputTypeAHandler,OutputTypeAHandler {
#Delegate
OutputTypeAHandlerImp outputTypeAHandlerImp = new OutputTypeAHandlerImp() {
#Override
String id() {
return "mellow";
}
};
#Delegate
InputTypeAHandlerImp inputTypeAHandler = new InputTypeAHandlerImp(){
#Override
String id() {
return "hello124";
}
};
}
public static abstract class OutputTypeAHandlerImp implements OutputTypeAHandler {
abstract String id();
#Override
public void write(String s) {
System.out.println(s);
}
}
public static abstract class InputTypeAHandlerImp implements InputTypeAHandler {
abstract String id();
#Override
public String read() {
return new Scanner(System.in).nextLine();
}
}
public interface InputTypeAHandler {
String read();
}
public interface OutputTypeAHandler{
void write(String s);
}
I have a generic interface
public interface Consumer<E> {
public void consume(E e);
}
I have a class that consumes two types of objects, so I would like to do something like:
public class TwoTypesConsumer implements Consumer<Tomato>, Consumer<Apple>
{
public void consume(Tomato t) { ..... }
public void consume(Apple a) { ...... }
}
Apparently I can't do that.
I can of course implement the dispatch myself, e.g.
public class TwoTypesConsumer implements Consumer<Object> {
public void consume(Object o) {
if (o instanceof Tomato) { ..... }
else if (o instanceof Apple) { ..... }
else { throw new IllegalArgumentException(...) }
}
}
But I am looking for the compile-time type-checking and dispatching solution that generics provide.
The best solution I can think of is to define separate interfaces, e.g.
public interface AppleConsumer {
public void consume(Apple a);
}
Functionally, this solution is OK, I think. It's just verbose and ugly.
Any ideas?
Consider encapsulation:
public class TwoTypesConsumer {
private TomatoConsumer tomatoConsumer = new TomatoConsumer();
private AppleConsumer appleConsumer = new AppleConsumer();
public void consume(Tomato t) {
tomatoConsumer.consume(t);
}
public void consume(Apple a) {
appleConsumer.consume(a);
}
public static class TomatoConsumer implements Consumer<Tomato> {
public void consume(Tomato t) { ..... }
}
public static class AppleConsumer implements Consumer<Apple> {
public void consume(Apple a) { ..... }
}
}
If creating these static inner classes bothers you, you can use anonymous classes:
public class TwoTypesConsumer {
private Consumer<Tomato> tomatoConsumer = new Consumer<Tomato>() {
public void consume(Tomato t) {
}
};
private Consumer<Apple> appleConsumer = new Consumer<Apple>() {
public void consume(Apple a) {
}
};
public void consume(Tomato t) {
tomatoConsumer.consume(t);
}
public void consume(Apple a) {
appleConsumer.consume(a);
}
}
Because of type erasure you can't implement the same interface twice (with different type parameters).
Here's a possible solution based on Steve McLeod's one:
public class TwoTypesConsumer {
public void consumeTomato(Tomato t) {...}
public void consumeApple(Apple a) {...}
public Consumer<Tomato> getTomatoConsumer() {
return new Consumer<Tomato>() {
public void consume(Tomato t) {
consumeTomato(t);
}
}
}
public Consumer<Apple> getAppleConsumer() {
return new Consumer<Apple>() {
public void consume(Apple a) {
consumeApple(t);
}
}
}
}
The implicit requirement of the question was Consumer<Tomato> and Consumer<Apple> objects that share state. The need for Consumer<Tomato>, Consumer<Apple> objects comes from other methods that expect these as parameters. I need one class the implement them both in order to share state.
Steve's idea was to use two inner classes, each implementing a different generic type.
This version adds getters for the objects that implement the Consumer interface, which can then be passed to other methods expecting them.
At least, you can make a small improvement to your implementation of dispatch by doing something like the following:
public class TwoTypesConsumer implements Consumer<Fruit> {
Fruit being an ancestor of Tomato and Apple.
just Stumbled upon this. It just happened, that I had the same Problem, but I solved it in a different way:
I just created a new Interface like this
public interface TwoTypesConsumer<A,B> extends Consumer<A>{
public void consume(B b);
}
unfortunately, this is considered as Consumer<A> and NOT as Consumer<B> against all Logic. So you have to create a small Adapter for the second consumer like this inside your class
public class ConsumeHandler implements TwoTypeConsumer<A,B>{
private final Consumer<B> consumerAdapter = new Consumer<B>(){
public void consume(B b){
ConsumeHandler.this.consume(B b);
}
};
public void consume(A a){ //...
}
public void conusme(B b){ //...
}
}
if a Consumer<A> is needed, you can simply pass this, and if Consumer<B> is needed just pass consumerAdapter
In Functional style it is quite easy do this without implementing the interface and also it does the compile time type checking.
Our functional interface to consume entity
#FunctionalInterface
public interface Consumer<E> {
void consume(E e);
}
our manager to process and consume entity appropriately
public class Manager {
public <E> void process(Consumer<E> consumer, E entity) {
consumer.consume(entity);
}
public void consume(Tomato t) {
// Consume Tomato
}
public void consume(Apple a) {
// Consume Apple
}
public void test() {
process(this::consume, new Tomato());
process(this::consume, new Apple());
}
}
You cannot do this directly in one class as the class definition below cannot be compiled due to erasure of generic types and duplicate interface declaration.
class TwoTypesConsumer implements Consumer<Apple>, Consumer<Tomato> {
// cannot compile
...
}
Any other solution for packing the same consume operations in one class requires to define your class as:
class TwoTypesConsumer { ... }
which is pointless as you need to repeat/duplicate the definition of both operations and they won't be referenced from interface. IMHO doing this is a bad small and code duplication which I'm trying to avoid.
This might be an indicator also that there is too much responsibility in one class to consume 2 different objects (if they aren't coupled).
However what I'm doing and what you can do is to add explicit factory object to create connected consumers in the following way:
interface ConsumerFactory {
Consumer<Apple> createAppleConsumer();
Consumer<Tomato> createTomatoConsumer();
}
If in reality those types are really coupled (related) then I would recommend to create an implementation in such way:
class TwoTypesConsumerFactory {
// shared objects goes here
private class TomatoConsumer implements Consumer<Tomato> {
public void consume(Tomato tomato) {
// you can access shared objects here
}
}
private class AppleConsumer implements Consumer<Apple> {
public void consume(Apple apple) {
// you can access shared objects here
}
}
// It is really important to return generic Consumer<Apple> here
// instead of AppleConsumer. The classes should be rather private.
public Consumer<Apple> createAppleConsumer() {
return new AppleConsumer();
}
// ...and the same here
public Consumer<Tomato> createTomatoConsumer() {
return new TomatoConsumer();
}
}
The advantage is that the factory class knows both implementations, there is a shared state (if needed) and you can return more coupled consumers if needed. There is no repeating consume method declaration which aren't derived from interface.
Please note that each consumer might be independent (still private) class if they aren't completely related.
The downside of that solution is a higher class complexity (even if this can be a one java file) and to access consume method you need one more call so instead of:
twoTypesConsumer.consume(apple)
twoTypesConsumer.consume(tomato)
you have:
twoTypesConsumerFactory.createAppleConsumer().consume(apple);
twoTypesConsumerFactory.createTomatoConsumer().consume(tomato);
To summarize you can define 2 generic consumers in one top-level class using 2 inner classes but in case of calling you need to get first a reference to appropriate implementing consumer as this cannot be simply one consumer object.
Another alternative to avoid the use of more classes. (example using java8+)
// Mappable.java
public interface Mappable<M> {
M mapTo(M mappableEntity);
}
// TwoMappables.java
public interface TwoMappables {
default Mappable<A> mapableA() {
return new MappableA();
}
default Mappable<B> mapableB() {
return new MappableB();
}
class MappableA implements Mappable<A> {}
class MappableB implements Mappable<B> {}
}
// Something.java
public class Something implements TwoMappables {
// ... business logic ...
mapableA().mapTo(A);
mapableB().mapTo(B);
}
Sorry for answer old questions, but I really love it! Try this option:
public class MegaConsumer implements Consumer<Object> {
Map<Class, Consumer> consumersMap = new HashMap<>();
Consumer<Object> baseConsumer = getConsumerFor(Object.class);
public static void main(String[] args) {
MegaConsumer megaConsumer = new MegaConsumer();
//You can load your customed consumers
megaConsumer.loadConsumerInMapFor(Tomato.class);
megaConsumer.consumersMap.put(Apple.class, new Consumer<Apple>() {
#Override
public void consume(Apple e) {
System.out.println("I eat an " + e.getClass().getSimpleName());
}
});
//You can consume whatever
megaConsumer.consume(new Tomato());
megaConsumer.consume(new Apple());
megaConsumer.consume("Other class");
}
#Override
public void consume(Object e) {
Consumer consumer = consumersMap.get(e.getClass());
if(consumer == null) // No custom consumer found
consumer = baseConsumer;// Consuming with the default Consumer<Object>
consumer.consume(e);
}
private static <T> Consumer<T> getConsumerFor(Class<T> someClass){
return t -> System.out.println(t.getClass().getSimpleName() + " consumed!");
}
private <T> Consumer<T> loadConsumerInMapFor(Class<T> someClass){
return consumersMap.put(someClass, getConsumerFor(someClass));
}
}
I think that is what you are looking for.
You get this output:
Tomato consumed!
I eat an Apple
String consumed!
When to implement interface in class and when to instantiate an anonymous implementation of an interface. Below are two interfaces.
public interface InterfaceOne {
void one();
}
public interface InterfaceTwo {
void two();
}
Approach 1: Implement interface in class
public class A implements InterfaceOne, InterfaceTwo {
private void doSomething() {
Hello hello = new Hello();
hello.hi(this);
hello.bye(this);
}
#Override
public void one() {
//One
}
#Override
public void two() {
//Two
}
}
Approach 2: Instantiate an anonymous implementation of an interface
public class B {
private void doSomething() {
Hello hello = new Hello();
hello.hi(interfaceOne);
hello.bye(interfaceTwo);
}
private InterfaceOne interfaceOne = new InterfaceOne() {
#Override
public void one() {
//One
}
};
private InterfaceTwo interfaceTwo = new InterfaceTwo() {
#Override
public void two() {
//Two
}
};
}
What are the scenarios in which we need to use Approach 1 and Approach 2?
With Java8 things slightly changed because with functional interfaces you are allowed to define lambdas with are internally managed as anonymous classes so the awkward syntax is somewhat saved.
In any case an anonymous class makes sense only when you are dealing with something which doesn't need to be named (think about an ActionListener for a button). A named class instead always makes sense, there is no explicit reason to avoid naming a class.
I have two abstract generic classes. They cooperate and hence depend on each other. Occasionally one needs to pass this to the other. I am trying to find a type safe way to do this:
public abstract class AbstractA<T extends AbstractB<? extends AbstractA<T>>> {
protected void foo() {
T aB = createB();
aB.setA(this);
}
/** factory method */
abstract public T createB();
}
public abstract class AbstractB<T extends AbstractA<? extends AbstractB<T>>> {
private T theA;
#SuppressWarnings("unchecked")
public void setA(AbstractA<? extends AbstractB<?>> theA) { // dreamed of parameter list (T theA)
// Unchecked cast from AbstractA<capture#1-of ? extends AbstractB<?>> to T
this.theA = (T) theA;
}
protected T getA() {
return theA;
}
}
My question is whether I can find a cleaner way so I avoid the unchecked cast in AbstractB.setA(). I had hoped to declare it setA(T theA), but then the call to it won’t compile: The method setA(capture#1-of ? extends AbstractA<T>) in the type AbstractB<capture#1-of ? extends AbstractA<T>> is not applicable for the arguments (AbstractA<T>). I am still struggling to understand whether the compiler should know enough to allow it or not.
I was thinking my problem may be related to the one discussed in Java generics compilation error - The method method(Class<capture#1-of ? extends Interface>) in the type <type> is not applicable for the arguments. My unchecked cast was inspired from there. I liked the reply by Tom Hawtin - tackling, but I have not found a way to apply it to my situation.
My user will declare concrete subclasses and instantiate one ConcreteA and any number of ConcreteBs:
public class ConcreteA extends AbstractA<ConcreteB> {
#Override
public ConcreteB createB() {
return new ConcreteB();
}
public void concreteAMethod() {
// ...
}
}
public class ConcreteB extends AbstractB<ConcreteA> {
public void bar() {
ConcreteA a = getA();
a.concreteAMethod();
}
}
(class AbstractA<T extends AbstractB<? extends AbstractA<T>>> looks a bit complicated; I thought I needed it for concrete subclasses to know each other’s exact types, but apparently it doesn’t give me that.)
If I've understood you correctly, this should create the binding you want.
class Demo {
public static void main(String[] args) {
ConcreteA a = new ConcreteA();
ConcreteB b = new ConcreteB();
a.foo(b);
b = (ConcreteB) a.getB();
}
}
abstract class AbstractA<T extends AbstractB<?>>{
private AbstractB<?> b;
public AbstractB<?> getB(){
return b;
}
void foo(AbstractB<?> aB) {
b = aB;
aB.bar(this);
}
}
abstract class AbstractB<T extends AbstractA<?>> {
private AbstractA<?> a;
public AbstractA<?> getA(){
return a;
}
public void bar(AbstractA<?> theA) {
a = theA;
theA.foo(this);
}
}
class ConcreteA extends AbstractA<ConcreteB>{
}
class ConcreteB extends AbstractB<ConcreteA>{
}
I think this is what you ended up at yourself. I am not able to remove the cast to ConcreteB, getB() simply cannot be sure of the type it is holding. I now see why you had multiple generic statements in your declaration. :)
If you're up for it, continue searching, and post your own answer if you find one, I'd love to see it.
I hope solving half your problem counts for anything. ;)
I think I got it now why I cannot declare public void setA(T theA) in AbstractB and then call it as aB.setA(this) in foo(). Suppose we had:
class IntermediateConcreteA extends AbstractA<ConcreteB> {
#Override
public ConcreteB createB() {
return new ConcreteB();
}
}
class SubConcreteA1 extends IntermediateConcreteA {}
class SubConcreteA2 extends IntermediateConcreteA {}
class ConcreteB extends AbstractB<SubConcreteA2> {}
Now if I have a SubConcreteA1 and call its foo(), then createB() will return an object that can pass as an AbstractB<SubConcreteA2> but cannot pass as an AbstractB<SubConcreteA1>. Therefore its setA() shouldn’t accept this as an argument. The compiler error message is logical after all.
Each abstract class would be parameterized with two type parameters, one for the actual concrete class of A, and one for the actual concrete class of B:
public abstract class AbstractA<A extends AbstractA<A,B>, B extends AbstractB<A,B>> {
protected void foo() {
B aB = createB();
aB.setA(getThis());
}
abstract public A getThis();
abstract public B createB();
}
public abstract class AbstractB<A extends AbstractA<A,B>, B extends AbstractB<A,B>> {
private A theA;
public void setA(A theA) {
this.theA = theA;
}
protected A getA() {
return theA;
}
}
public class ConcreteA extends AbstractA<ConcreteA, ConcreteB> {
#Override
public ConcreteA getThis() {
return this;
}
#Override
public ConcreteB createB() {
return new ConcreteB();
}
public void concreteAMethod() {
// ...
}
}
public class ConcreteB extends AbstractB<ConcreteA, ConcreteB> {
public void bar() {
ConcreteA a = getA();
a.concreteAMethod();
}
}
A factory can solve it:
public abstract class AbstractA {
public void abstractAMethod() {
// ...
}
}
public abstract class AbstractB<A> {
private A theA;
public void setA(A theA) {
this.theA = theA;
}
protected A getA() {
return theA;
}
}
public abstract class AbstractFactory<A extends AbstractA, B extends AbstractB<A>> {
private A theA = createA();
public A getA() {
return theA ;
}
public B getNextB() {
B newB = createB();
newB.setA(theA);
return newB;
}
protected abstract A createA();
protected abstract B createB();
}
Now the user can go:
public class ConcreteA extends AbstractA {
public void concreteAMethod() {
// ...
}
}
public class ConcreteB extends AbstractB<ConcreteA> {
public void bar() {
ConcreteA a = getA();
a.abstractAMethod();
a.concreteAMethod();
}
}
public class ConcreteFactory extends AbstractFactory<ConcreteA, ConcreteB> {
#Override
protected ConcreteA createA() {
return new ConcreteA();
}
#Override
protected ConcreteB createB() {
return new ConcreteB();
}
}
I don’t think it’s a typical application of the abstract factory pattern, though …
#Chris Wohlert, I did give up in my production code since I considered the factory overkill, but I could not let go of the theoretical question.
I have come to realize that my problem really came out of stuffing two concepts into the AbstractA/ConcreteA hierarchy that didn’t belong together. Though maybe not interesting to very many, I am posting this insight for two reasons: (1) I feel I owe Chris Wohlert the answer I have found myself (2) more importantly, I’d love to inspire anyone else facing a similar tricky generics issue to review your design from a higher level than just solving the generics and/or class cast issue. It certainly helped me. The cast/generics problem was a sign that something more fundamental was not quite right.
public abstract class AbstractA {
public void foo() {
AbstractB aB = createB();
aB.setA(this);
}
/** factory method */
abstract public AbstractB createB();
}
public abstract class AbstractB {
private AbstractA theA;
public void setA(AbstractA theA) {
this.theA = theA;
}
// methods that use theA
}
No generics and no class cast. Taking out the stuff that didn’t belong in the A class hierarchy into ConcreteC (with no AbstractC):
public class Client {
public void putTheActTogether() {
ConcreteC theC = new ConcreteC();
// the concrete A
AbstractA theA = new AbstractA() {
#Override
public AbstractB createB() {
return new ConcreteB(theC);
}
};
// call methods in theA
}
}
public class ConcreteB extends AbstractB {
private final ConcreteC c;
public ConcreteB(ConcreteC c) {
super();
this.c = c;
}
public void bar() {
c.concreteCMethod();
}
}
public class ConcreteC {
public void concreteCMethod() { // was concreteAMethod(); moved and renamed
// ...
}
}
The client needs a few more lines than before. In my real-world code I needed to duplicate one final field in AbstractA and ConcreteC, but it made sense to do. All in all I consider it a low price for a design that is otherwise pure and simple.
I have made a class to include a custom title bar with my apps logo on it. This works well except that for the majority of my classes I need to be able to inherit that functionality as well as that of say a ListActivity. What to do?
Any help appreciated.
you should favor composition (and delegation) over inheritance :
public interface FirstClassInterface {
void method1();
}
public interface SecondClassInterface {
void method2();
}
public class FirstClass implements FirstClassInterface {
// ...
}
public class SecondClass implements SecondClassInterface {
// ...
}
public class FirstAndSecondClass implements FirstClassInterface , SecondClassInterface
{
private FirstClassInterface firstclass;
private SecondClassInterface secondclass;
public FirstAndSecondClass(FirstClassInterface firstclassinterface, SecondClassInterface secondclassinterface) {
this.firstclass= firstclassinterface;
this.secondclass= secondclassinterface;
}
public void method1() {
this.firstclass.method1();
}
public void method2() {
this.secondclass.method2();
}
public static void main(String[] args) {
FirstAndSecondClass t = new FirstAndSecondClass(new FirstClass(), new SecondClass());
t.method1();
t.method2();
}
}
In Java, you cannot have:
class MyClass extends ClassA, ClassB { ... }
Depending on what you are doing, it might be possible to use:
class ClassB extends ClassA { ... }
class MyClass extends ClassB { ... }