Need an advice on structuring interfaces - java

I have a structure like follows
Interface A
Interface B extends Interface A
abstract Class C implements Interface B
now concrete Class D extends Class C
Now I am using Interface B in a different class and returning the concrete class D object.
Interface B contains getters and setters and modifying methods.
What I want is that I want to take out all the getters from Interface B somehow and put them in a separate interface so that when I return a concrete object I don't have access to the setters and modifiers of Interface B. But I want to use Interface B as my return object with this newly built read-only concrete object. I am not get any idea about how to achieve this?

One way to achieve this would be to create a read-only wrapper object which implements interface B, propagates the getters to the wrapped object and raises an exception (like IllegalAccessEXception or InvalidStateException) from within the setters and modifiers.

It sounds like you are referring to the Proxy design pattern : http://en.wikipedia.org/wiki/Proxy_pattern.
In your case, you want Interface B to support getting/setting of certain fields, but you want it to provide a specific proxy for setting and getting those fields, rather then directly editing them.
This is rarely done, but you can create an inner-interface, which is specific and local to the interface you want to support. For example :
public interface Proxiable {
public static interface Proxy
{
}
public ProxySub getProxy();
}
Thus, your interface is defining a proxy interface - and anyone who extends your interface will have to provision a Proxy provider.
However, unless you have a REALLY good reason for doing this, you might be overabstracting. Interfaces are generic enough that it is usually sufficient to leave the details of HOW methods are implemented to subclasses, rather than forcing this superstructure at the interface level.

Elaborating on the excellent suggestion by #rsp :
Create a "read-only" interface
public interface MyInterfaceRO {
public int getFoo();
public String getBar();
// etc...
}
Create the "read-write" interface, corresponding to your B
public interface MyInterfaceRW extends MyInterfaceRO {
public void setFoo(int foo);
public void setBar(String bar);
// ...
}
IMO, the simplest way to do what you want (prevent modification) is to just return MyInterfaceRO. The caller (unless they do a cast) will have no ability to call setFoo(), in fact, in their IDE they won't even see .setFoo() as an option.
I don't understand why you really want to return a type B (my RW above), but, if you do, you are stuck with the caller having the ability to see and call setFoo(). Probably your best bet would be to follow the precedent set in java's Collections and throw an UnsupportedOperationException. As a convenience, you could offer a method
public boolean isModifiable();
but you can't force the caller to use and respect that.

Related

what design pattern can I use to create an object that implements a specific interface or multiple or any combination among the available interfaces?

what design pattern can I use to create an object that implements a specific interface or multiple or any combination among the available interfaces? for Example say I have the following
interface A {
void foo();
}
interface B {
void bar();
}
interface C {
void car();
}
class Agent {
}
I want to be able to say give me object of class Agent that implements interface A?
or
I want to be able to say give me object of class Agent that implements interfaces B?
or
I want to be able to say give me object of class Agent that implements interfaces C?
or
I want to be able to say give me object of class Agent that implements interfaces A,B?
or
I want to be able to say give me object of class Agent that implements interfaces B,C?
or
I want to be able to say give me object of class Agent that implements interfaces A,C?
or
I want to be able to say give me object of class Agent that implements interfaces A,B,C?
or
In general what I am looking for is to create an object which can have the functionality from any combination of interfaces.
Java is a statically typed language (see this question for details). This means that a variable you describe has a type which includes a set of interfaces that are implemented. So it does not make a lot of sense to say that you want an object of a certain class to vary the interfaces it implements.
Having said that, I suspect you are trying to use interface for something for which it is not intended. For example if you want a class whose objects can have various capabilities that are determined when the object is created then there are design patterns that might work for you.
Without knowing your needs it's hard to suggest specifics but here's a possible model:
interface A {
void foo();
}
interface B {
void bar();
}
class Agent {
private Optional<A> delegateA = Optional.empty();
private Optional<B> delegateB = Optional.empty();
public void addA(A delegate) {
delegateA = Optional.of(delegate);
}
public boolean implementsA() {
return delegateA.isPresent();
}
public void foo() {
delegateA.ifPresent(A::foo);
}
}
Agent agent = new Agent();
agent.addA(() -> System.out.println("foo"));
agent.implementsA();
agent.foo();
The best solution I can think of would be to have Agent implement all of your interfaces, then to use it as needed with your desired interface, such as:
A agentUsingA = new Agent();
You would then only be able to call the methods implementedfrom A.
However:
This is a really bad way of using interfaces. One of the main ideas of an interface in java is to act as a sort of "contract". For example:
Say you have two classes: AEncryptor and BEncryptor. Both of these classes implement the interface EncryptService, which has the method .encrypt(String text).
So, say you have a method somewhere called encryptString(EncryptService service, String textToBeEncrypted). This method takes an encrypting service and uses it to encrypt the string textToBeEncrypted. All this method will do is call service.encrypt(textToBeEncrypted);
Now, encryptString() dosen't care how service will encrypt the string, all it knows is that when it calls .encrypt(textToBeEncrypted) on it, it will encrypt the text.
So AEncryptor and BEncryptor could encrypt the text completely differently, but because they implement EncryptService, we know that it's encrypt method will be there, and that by calling it, it will encrypt the text.
In you're example, we won't really know what we can call on Agent, we wont have any assurance that a method (Say, .encrypt()) will actually be there.
For more information on interfaces, have a look into Oracle tutorials here and here. ;)

java - connecting interface to class member

Say I have an interface A and a class B that implements it.
Now, I also have some class C which extends class D (which means that it can't also extends B) but I also need there the functionality of interface A.
The solution I know is to have a member of A instantiated by B in C (which will implement A) and when implementing the functions of A call the matching function from the member of A.
Is there any way to create some connection between the functions of A and the member inside C? (so that java will know that every time it needs to call a function from A it will directly go and and run the matching function from the A member without me needing to write the code for it for every function of A)
A big thank you is waiting to each one of the helpers...
No. As already stated delegation must be implemented manually.
Having said that, you have a few options to simplify this: If you're working with Eclipse, select Source|Generate Delegate Methods... and select your member variable. Eclipse will then generate all the delegate methods for you. I don't know about other IDEs, but I would be surprised, if NetBeans et al. would not have a similar feature.
Another option, if you actually want to decorate existing collection classes, consider Google Guava's Google Guava's Collection Helpers.
Last, but not least, you could consider restructing your code and decorate your classes using Advices. Advices stem from Aspect Oriented Programming (AOP) and typically use a proxying mechanism to enrich original target classes. This is a rather advanced technique, but if you are determined to go down this road, have a look at Spring's AOP support.
So to sum up, here is your class hierarchies:
package common;
public interface A
{
void doStuff();
}
package commom.impl;
public class B implements A
{
void doStuff() {}
}
package real.service;
public class D
{
void doSomeRealStuff() {}
}
package real.service;
public class C extends D
{
void doSomeRealStuffForGood() {}
}
Assuming that each class is declared in its own source file.
Just to recall from the OP, I assume you need B stuff in C and not really A stuff. Because A is nothing but a contract and you need then the real implemting class to be fetched inside your C class in order to call the declared methods on.
In such a case, you may need to use the Inversion of Responsability approach, so that you declare an instacne of type B inside your C clas then you layer each method from B with a one having the same signature and that do nothing but delegate the real call to the instance member:
package real.service;
import common.A;
import common.impl.B;
public class C extends D
{
private A delegate;
public C ()
{
delegate = new B();
}
void doStuff() {
delegate.doStuff(); // Call the real delegate method when doStuff is called on an isntance of C.
}
void doSomeRealStuffForGood() {}
}
Note that this is a legal OO concept, since you are following an HAS-a even though some could consider it a high coupling.
Otherwise if you are not tied to the B class, and you may drop the declare methods in there for some others, you can declare an inner class that implements the A interface the way you need.
Edit:
Java does not support multiple inheritance, though you have provided a common contract in your A interface, so if you need all those methods (behavior) to be availble in your C class, it would be better to implement it directely and override all the interface methods.

Interface method referencing a concrete class as parameter causes coupling?

I was thinking about programming to interfaces and not to concrete classes, but I had a doubt: should any interface method be able to hold references to concrete classes?
Suppose the following scenarios:
1)
public interface AbsType1 {
public boolean method1(int a); // it's ok, only primitive types here
}
2)
public interface AbsType2 {
public boolean method2(MyClass a); // I think I have some coupling here
}
Should I choose a different design here in order to avoid the latter? e.g.
public interface MyInterface {} // yes, this is empty
public classe MyClass implements MyInterface {
// basically identical to the previous "MyClass"
}
public interface AbsType2 {
public boolean method2(MyInterface a); // this is better (as long as the
// interface is really stable)
}
But there's still something that doesn't convince me... I feel uncomfortable with declaring an empty interface, though I saw someone else doing so.
Maybe and Abstract Class would work better here?
I am a little bit confused.
EDIT:
Ok, I'll try to be more specific by making an example. Let's say I'm desining a ShopCart and I want of course to add items to the cart:
public interface ShopCart {
public void addArticle(Article a);
}
Now, if Article were a concrete class, what if its implementation changes over time? This is why I could think of making it an Interface, but then again, it's probably not suitable at least at a semantic level because interfaces should specify behaviours and an Article has none (or almost none... I guess it's a sort of entity class).
So, probably I'm ending up right now to the conclusion that making Article an abstract class in this case would be the best thing... what do you think about it?
I would use interfaces because composition is much better than inheritance. "Should any interface method be able to hold references to concrete classes ?", why it shouldn't? Some classes within package are coupled, it's a fact and common use technique. When you marked this relation in interface then you see on which classes is dependent your implementation. Dependency or composition relations are not inheritance so a i would avoid abstract class.
In my opinion Interfaces are fine for all types where the implementation may vary. But if you define a module which introduces a new type, that isn't intended to have alternative implementations then there is no need to define it as an Interface in the first place. Often this would be over-design in my opinion. It depends on the problem domain and often on the way how support testing or AOP-weaving.
For example consider a 2D problem domain where you need to model a Location as a type. If it is clear that a Location is always represented by a x and y coordinate, you may provide it as a Class. But if you do not know which properties a Location could have (GPS data, x, y, z coordinates, etc.) but you rely on some behavior like distance(), you should model it as an Interface instead.
If there are no public methods which AbsType would access in MyClass then the empty interface is probably not a good way to go.
There is no interface declaration (contract) for static methods, which otherwise might make sense here.
So, if AbsType is not going to use any methods from MyClass/MyInterface, then I assume it's basically only storing the class object for some other purpose. In this case, consider using generics to make clear how you want AbsType to be used without coupling closely to the client's code, like
public class AbsType3<C extends Class<?>> {
public boolean method3(T classType) {...}
}
Then you can restrict the types of classes to allow if needed by exchanging the <C extends Class<?>> type parameter for something else which may also be an interface, like
<C extends Class<Collection<?>>>.
Empty interfaces are somewhat like boolean flags for classes: Either a class implements the interface (true) or it doesn't (false). If at all, these marker interfaces should be used to convey an significant statement about how a class is meant to be (or not to be) used, see Serializable for example.

How to restrict object creation with generics?

I want to have a type hierarchy where only Foo objects are in control of the creation of Bar objects. E.g:
public abstract class Foo<F extends Foo<F>> {
public abstract Bar<F> makeBar();
}
public abstract class Bar<F extends Foo<F>> {}
Now a subclass of Foo could implement a subclass of Bar and give it back:
public class FooImpl extends Foo<FooImpl> {
private static class BarImpl extends Bar<FooImpl> {}
#Override
public Bar<FooImpl> makeBar() { return new BarImpl(); }
}
However that does still allow the creation of Bars elsewhere:
public class FakeBar extends Bar<FooImpl> {}
How can I restrict Bar<FooImpl> (using only the type system, not runtime checks) in a way that it must be created by an instance of FooImpl, and cannot be created in any other place?
This isn't something the type system can (or should) do. You want access restrictions, use Java's access modifiers. But I don't think those can implement your very specific and unusual requirements either.
Actually, I don't think they can be implemented at all: you want a class to be publically visible and non-final, yet allow the ability to call its constructors and to extend it only to a specific class and its subclasses?
Sorry, no can do. What would be the point anyway?
That doesn't work (with the limitation: type system only, no runtime checks). We can either disallow subclassing in general (final class) or allow it. If a (public) class is not final, any other class may subclass.
You could try playing with annotations - like inventing an annotation, that lists allowed classname, but this depends on processing the annotations.
Example:
#AllowedSubclasses(classnames="com.example.FooBar; *.AnyFooBar; com.example.foobars.*")
public abstract class Bar<F extends Foo<F>> {}
The annotation processor then would throw an error, if any other class subclasses this annotated class.
What about a mixed approach: annotate your internal methods with "HANDS OFF" in the javaDoc and document, that any violation will result in runtime exceptions. After the method has been called, you can verify within the method, if the caller is an instance of one of the classes, that are allowed to use this feature.
Well instead of relying on generics etc, a simpler way to accomplish this is to enforce that you need an instance of Foo to create a Bar
public Bar(Foo foo){...}
This way, no one can create a bar independently of Foo. This couples the 2 classes, and indicates to users of this fact as well. There are other ways to accomplish this as well... this is just one example
You can make makeBar a concrete method which calls a protected abstract makeBar0 which does the actual creation. makeBar() can take the result and check it the object any way you wish.
public abstract class Foo<F extends Foo<F>> {
public Bar<F> makeBar() {
Bar<F> bar = makeBar0();
// check bar
return bar;
}
}
If you prefer you could add a check on the creation of Foo which may be more performance. i.e. check the return type of makeBar0();

Can you force a java object into implementing an interface at runtime?

Right now I the following:
1) A java interface.
2) A concrete java class that does not implement the aforementioned interface, but does contain a method signature matching every one of the methods defined in the interface.
Since I am unable to change the implementation of item 2, I would like to know if it is possible to make a method that accepts an instance of item 1 as an argument accept item 2 without a class cast exception.
It feels like the various weaving/coercion/AOP mechanics in Spring should make this possible, but I don't know how to do it.
Is there a way to make this happen?
Can you force a java object into implementing an interface at runtime?
Yes, using dynamic proxies or byte-code rewriting. However, to me it seems like you're looking for the Adapter pattern.
You can't make the object itself implement the interface, but you could use something like Proxy to create an object which implements the interface and uses reflection to call the appropriate member on the original object.
Of course, if it's just the one interface type and the one concrete type, you could easily write such a wrapper without using Proxy:
public class BarWrapper implements Foo
{
private final Bar bar;
public BarWrapper(Bar bar)
{
this.bar = bar;
}
public int someMethodInFoo()
{
return bar.someMethodInFoo();
}
// etc
}
This should be solvable with an adapter.
Have an other class defined that implements your interface and delegates to the real object:
class YourAdapter implements YourInterface {
private final YourClass realObject;
public YourAdapter(YourClass realObject) {
this.realObject = realObject;
}
#Override
public methodFromInterface() {
// you said the class has the same method signatures although it doesn't
// implement the interface, so this should work fine:
realObject.methodFromInterface();
}
// .......
}
Now, given a method that expects YourInterface and an object of type YourClass:
void someMethod(YourInterface param) {}
void test() {
YourClass object = getFromSomewhere();
someMethod( YourAdapter(object) );
}
You can probably do what you want with Javassist, either by modifying the class's bytecode or creating a wrapper/proxy class.
Basically there are two ways:
a) write a decorator around your Object that implements the interface and delegates to your object (this can be done either by using proxies or by writing a simple adapter class)
b) change the byte code. Spring AOP is not powerful enough to do that, but the AspectJ compiler is. It's a one-liner:
declare parents: YourClass implements YourInterface;
Since you don't have access to the class source you will have to either use Load Time Weaving or weave the library jar. All of this is explained well in AspectJ in Action by Ramnivas Laddad

Categories

Resources