Not sure if this is possible, but I have a case in which two interfaces have the same method. These are interfaces that are given, so I can't change them.
Given Interfaces
interface SomeGivenService {
boolean authenticate(String username, String password);
Object someSpecialMethod(Object param);
}
interface AnotherGivenService {
boolean authenticate(String username, String password);
String aGreatMethod();
String sayHello();
}
To consume this service, I created a class and did some handling in case this service throws an error.
class SomeGivenServiceConsumer {
SomeGivenService a;
public SomeGivenServiceConsumer(SomeGivenService a) {
this.a = a;
}
public authenticate(MyUserPassBean bean) {
try {
a.authenticate(bean.username, bean.password);
} catch (Exception e) {
throw new MyException();
}
...
}
}
class AnotherGivenServiceConsumer {
AnotherGivenService a;
public AnotherGivenServiceConsumer(AnotherGivenService a) {
this.a = a;
}
public authenticate(MyUserPassBean bean) {
try {
a.authenticate(bean.username, bean.password);
} catch (Exception e) {
throw new MyException();
}
...
}
}
Is it possible to avoid this code duplication in my consumers? I probably will have many of them and wanted to avoid this duplicated code. I initially thought of changing my consumer to receive an interface that implements this authentication, but as I can't change the given interfaces, not sure if this is even possible.
Is it possible to have a "Generic interface which has a method?" or use some design pattern? Any ideas? What I was trying:
class AnotherGivenServiceConsumer {
AnotherGivenService a;
GivenServiceAuthenticable b;
public AnotherGivenServiceConsumer(AnotherGivenService a,
GivenServiceAuthenticable b) {
this.a = a;
this.b = b;
}
public authenticate(MyUserPassBean bean) throws MyException {
return b.authenticate(bean.username, bean.password);
}
}
interface GivenServiceAuthenticable<T> {
boolean authenticate(T givenService, MyUserPassBean bean);
}
class GivenServiceAuthenticableImpl<T> implements GivenServiceAuthenticable<T> {
boolean authenticate(T givenService, MyUserPassBean bean) {
try {
//this won't compile as it's a generic class..
t.authenticate(bean.username, bean.password);
} catch (Exception e) {
throw new MyException();
}
...
}
}
Other problem is how to instantiate this object if I can't change it to implement my new objects?
You can use the template pattern to implement the common functionality in a base class, while delegating the single varying line to subclasses:
abstract class ConsumerBase {
public void authenticate(MyUserPassBean bean) {
try {
authenticate(bean.username, bean.password);
} catch (Exception e) {
throw new MyException();
}
//...
}
protected abstract boolean authenticate(String username, String password);
}
class SomeGivenServiceConsumer extends ConsumerBase {
SomeGivenService a;
public SomeGivenServiceConsumer(SomeGivenService a) {
this.a = a;
}
@Override
protected boolean authenticate(String username, String password) {
return a.authenticate(username, password);
}
}
class AnotherGivenServiceConsumer extends ConsumerBase {
AnotherGivenService a;
public AnotherGivenServiceConsumer(AnotherGivenService a) {
this.a = a;
}
@Override
protected boolean authenticate(String username, String password) {
return a.authenticate(username, password);
}
}
What you need to do is to use inheritance. Then deal with the error in the superclass ie
class SomeGivenServiceConsumer {
SomeGivenService a;
AnotherGivenService b;
public SomeGivenServiceConsumer(SomeGivenService a) {
this.a = a;
try{
authenticate(MyUserPassBean);
}catch (Exception e) {
System.out.println("Thrown exception has been caught : "+e.getMessage());
}
}
public authenticate(MyUserPassBean bean) throws MyException {
//your implementation here
}
}
class AnotherGivenServiceConsumer extends SomeGivenServiceConsumer{
public AnotherGivenServiceConsumer(AnotherGivenService b) {
super(someGivenService);//construct superclass
authenticate(MyUserPassBean);//call subclass authenticate method
}
@override
public authenticate(MyUserPassBean bean) throws MyException {
super.authenticate(MyUserPassBean);//call superclass method
//your implementation here
}
}
then you construct the subclass:
public static void main(String[] args) {
new AnotherGivenServiceConsumer(AnotherGivenService);
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.