Design question - java - what is the best way to doing this? - java

I have a design problem.
I have two data objects which are instances of say class A and class B.
A and B don't have any behavior - they are java beans with getters and setters.
I have a Validation interface and 10 implementations of it defining different Validations.
I would like to specify in my properties file which Validation applies to which class.
Something like this:
class A XYZValidation,ABCValidation
class B: ABCValidation, PPPValidation, etc
How do I write my Validation class so that it serves objects that are instances of Class A OR ClassB, or just about any other Class C that I might want to add in future?
interface Validation {
public boolean check(??);
}
> Just wanted to add this line to say thank you to all those who have responded to this post and to say that I am loving my time here on this amazing website. Stackoverflow rocks!

Have you thought about using annotations to mark the fields you want to validate in your bean?
If you have 10 different validations you could specify 10 annotations. Then mark the fields using annotations:
#ValideStringIsCapitalCase
private String myString;
#ValidateIsNegative
private int myInt;
With reflection API iterate through all the fields and see if they are marked, something like this:
public static <T> validateBean(T myBean) throws IllegalAccessException {
Field[] fields = myBean.getClass().getDeclaredFields();
// This does not take fields of superclass into account
if (fields != null) {
for (Field field : allFields) {
if (field.isAnnotationPresent(ValideStringIsCapitalCase.class)) {
field.setAccessible(true);
Object value = field.get(existingEntity);
// Validate
field.setAccessible(false);
}
}
}
}
An option would be to mark the whole class with the validator you want to use.
EDIT: remember to include annotation:
#Retention(RetentionPolicy.RUNTIME)
for your annotation interface.
EDIT2: please don't modify the fields directly (as in the example above). Instead access their getters and setters using reflection.

I've probably misunderstood the question but would something like this suffice:
public class ValidationMappings {
private Map<Class, Class<Validation>[]> mappings = new HashMap<Class, Class<Validation>[]>();
public ValidationMappings() {
mappings.put(A.class, new Class[]{XYZValidation.class, ABCValidation.class});
mappings.put(B.class, new Class[]{ABCValidation.class, PPPValidation.class});
}
public Class[] getValidators(Class cls) {
if (!mappings.containsKey(cls)) return new Class[]{};
return mappings.get(cls);
}
}
When you want to get the list of validators for a particular class, you would then call getValidators(Class cls) and iterate over each validator and create an instance of each and call your check method.

something like this maybe?
interface Validation {
public boolean check(Validatable x);
}
interface Validatable {
}
class A implements Validatable {
...
}
class Validator {
public boolean validateObject(Validatable x){
boolean validated = true;
... //read config file, check which validation classes to call
//for each validation class v in the config file:
if(!v.check(x)) validated = false;
return validated;
}
}

If you just want it to deal with any object then it'll be Object's that your interface
public boolean check(Object o);
Unless you want to use some marker interface to tag classes that are suitable for validation

Did you mean:
public interface Validation<T> {
boolean check(T object)
}

First of all, I'd use the following interface
interface Validator {
boolean isValid(Object object);
}
to implicitly document what the return value actually means.
Secondly, I'd suggest to document in the interface what behavior is expected if the Validator doesn't know how to handle the given instance.
interface Validator {
/**
* #return false if this validator detects that the given instance is invalid, true if the given object is valid or this Validator can't validate it.
*/
boolean isValid(Object object);
}
That way, you'd simply have a List of Validators that you could throw your objects at.
The performance impact of incompatible Validators should be negligible if they are implemented properly, e.g. with an early instanceof.
On a side note, I'd use a List of Validators instead of a Set so you can order them according to complexity. Put the cheap (performance-wise) Validators at the start of the List as an optimization.
You could then use a general piece of code for validation, e.g.
public class Validators {
public static boolean isValid(Object o, Collection<Validator> validators) {
for(Validator current : validators) {
if(!current.isValid()) return false;
}
return true;
}
}
Depending on your use-case it might be a good idea to return something different than boolean in your interface. If you need information about what is wrong, e.g. to display it, you'd need to return that info instead.
In that case it might be a good idea to keep the above loop running so you'll get all validation errors instead of only the first.

A Visitor pattern would solve this
Calling the Visitor Validator it's possible to have this:
public interface Validatable {
public boolean validate(Validator v);
}
public interface Validator {
public boolean validate(A a);
public boolean validate(B b);
}
public class A implements Validatable {
public boolean validate(Validator v){
return v.validate(this);
}
}
public class B implements Validatable {
public void validate(Validator v) {
return v.validate(this);
}
}
// Default validator just doesn't know how to
// validate neither A's, nor B's
public class GenericValidator implements Validator {
public boolean validate(A a) {
throw new UnsupportedOperationException("Cannot validate A");
}
public boolean validate(B b) {
throw new UnsupportedOperationException("Cannot validate B");
}
}
// since XYZValidation is supposed to run only on A's
// it only overrides A validation
public class XYZValidation extends GenericValidator {
public boolean validate(A a) {
// validate a
return isVAlid(a);
}
}
// since ABCValidation is supposed to run on A's and B's
// it overrides A and B validation
public class ABCValidation extends GenericValidator {
public boolean validate(A a) {
// validate a
return isVAlid(a);
}
public boolean validate(B b) {
// validate b
return isVAlid(b);
}
}
// since ABCValidation is supposed to run only on B's
// it overrides A only B validation
public class PPPValidation extends GenericValidator {
public boolean validate(B b) {
// validate b
return isVAlid(b);
}
}

Related

In a Spring Boot application how can I scan for a method return type and the annoatation value using the return type annoatation as a filter?

trying to scan for return type objects that are annoated with a custom annoation but the ClassPathScanningCandidateComponentProvider does not find them even though package is correct and metadata shows the methods annoated with them.
I've added a filter to my existing ClassPathScanningCandidateComponentProvider to include return types on methods annotated with a custom annoation, i.e.
#Procedure(name="PROC_MAPPING_NAME")
#CursorList(cursorType=CursorObject.class)CursorHolder<CursorObject> getCursor(#Param("col_1") #NonNull String param);
Filter is added like so
ClassPathScanningCandidateComponentProvider scanner =
new ClassPathScanningCandidateComponentProvider(false);
//existing filters
....
//new filter
scanner.addIncludeFilter(new AnnotationTypeFilter(CursorList.class));
//scan packages
return Arrays.stream(packages)
.map(scanner::findCandidateComponents)
.flatMap(Collection::stream)
.map(BeanDefinition::getBeanClassName)
.map(name -> {
try {
return Class.forName(name);
}
catch (ClassNotFoundException e) {
//handle exception
}
}).collect(Collectors.toList());
Works fine for all the existing filters and the package where the new annotation is used is definitely included as I've stepped into the code. It just fails to meet the criteria required to be considered a match and returned.
I've also tested this annotation at class level and it is then found without issue. But, it does not seem to work at attribute level or method or param level.
So stupid question given the class name. Is the ClassPathScanningCandidateComponentProvider only suitable for scanning for annoation usage when the annotation is included at class level? i.e. only finds annoated components?
If that is the case has anyone any suggestions for finding annotations and the objects they annoate where the object is a return type? Or is this just not possible?
Thanks
It seems that AnnotationTypeFilter matches only classes as far as I investigated its javadoc and implementation.
Fortunately, we can customize AnnotationTypeFilter in order to make it match methods.
The following is an example.
public class CustomAnnotationTypeFilter extends AnnotationTypeFilter {
public CustomAnnotationTypeFilter(
Class<? extends Annotation> annotationType) {
super(annotationType);
}
#Override
protected boolean matchSelf(MetadataReader metadataReader) {
AnnotationMetadata metadata = metadataReader.getAnnotationMetadata();
return metadata.hasAnnotatedMethods(getAnnotationType().getName());
}
}
....
ClassPathScanningCandidateComponentProvider scanner =
new ClassPathScanningCandidateComponentProvider(false);
scanner.addIncludeFilter(new CustomAnnotationTypeFilter(MyAnnotationA.class));
....
Our CustomAnnotationTypeFilter matches a class like:
public class Hoge {
#MyAnnotationA String doSomething() {
return "";
}
}
NOTE
Declaring a method with annotations in front of it means to annotate the method (not the return type) with the annotations.
#Procedure(name="PROC_MAPPING_NAME")
#CursorList(cursorType=CursorObject.class)CursorHolder<CursorObject> getCursor(...) {
....
};
The example above means that you annotate getCursor method with Procedure and CursorList. In such cases, you need to check whether methods have an annotation when you create a custom filter.
EDIT_1 (2022/3/16)
I added some examples considering the comments below. The following CustomAnnotationTypeFilter matches Baz, Foo, Fuga and Hoge.
public interface SomeInterface {
#MyAnnotationA
void doSomething();
}
public class Baz {
public SomeInterface doSomething() {
return null;
}
}
public class Foo implements SomeInterface {
#Override
public void doSomething() {
}
}
public class Fuga implements IFuga {
#Override
public SomeInterface doSomething() {
return null;
}
}
public class Hoge {
#MyAnnotationA String doSomething() {
return "";
}
}
public class CustomAnnotationTypeFilter extends AnnotationTypeFilter {
public CustomAnnotationTypeFilter(
Class<? extends Annotation> annotationType) {
super(annotationType);
}
#Override
protected boolean matchSelf(MetadataReader metadataReader) {
if (super.matchSelf(metadataReader)) {
return true;
}
String className = metadataReader.getClassMetadata().getClassName();
try {
Class<?> clazz = ClassUtils.forName(className, getClass().getClassLoader());
if (annotationExistsOnAMethod(clazz)) {
System.out.printf("1: matches %s\n", className);
return true; // matches 'Hoge.java' and 'Foo.java'
}
for (Method m : clazz.getDeclaredMethods()) {
if (annotationExistsOnAMethod(m.getReturnType())) {
System.out.printf("2: matches %s\n", className);
return true; // matches 'Baz.java' and 'Fuga.java'
}
}
} catch (ClassNotFoundException e) {
// ignore
}
return false;
}
private boolean annotationExistsOnAMethod(Class<?> clazz) {
for (Method m : clazz.getDeclaredMethods()) {
if (AnnotationUtils.findAnnotation(m, this.getAnnotationType()) != null) {
return true;
}
}
return false;
}
}
Scanning components to find annotations is a complex problem. It is not equivalent to / similar to searching with grep command.
You have to explicitly specify the location that the target annotation is placed on. For example, if methods can be annotated with the annotation, you have to check methods explicitly like AnnotationUtils.findAnnotation(method, this.getAnnotationType()) (as the example above shows). Also you may have to check the return types like the example above in a certain situation.
It is helpful to use the utility classes like org.springframework.core.annotation.AnnotationUtils when searching for annotations. Because some methods of such utilities can find
annotations even when they are not directly present on the given target itself(See also its javadoc).

Java implementing business logic based on EnumType given as field of Object

I know my question title is not relevant to what I'm asking, but not getting any better title. But feel free to suggest title. (So it will be helpful for others as well)
Here is the scenario I'm having:
I've enum class as below
public enum CalendarBasis {
FISCAL_YEAR,
CALENDAR
}
This enum is used in multiple objects in project.
I want to know the best practice/design pattern to follow which will be helpful for having functionality based on value of enum. Today there are only two values in CalendarBasis but tomorrow there can be multiple values.
This is what I'm doing currently:
Consider I've Object SpecificElement which has CalendarBasis enum parameter.
public class SpecificElement {
private SpecificValue specificValue; //some object
// few more Objects defined
private CalendarBasis calendarBasis;
//getters & setters
}
Following function do some operations on SpecificElement based on type of calendarBasis.
public Foo doCalculations(SpecificElement specificElement)
{
if(specificElement.getCalendarBasis().equals(CalendarBasis.FISCAL_YEAR)){
//do something based on fiscal & return.
}
if(specificElement.getCalendarBasis().equals(CalendarBasis.CALENDAR)){
//do something based on CALENDAR & return.
}
}
I want to know if I can have something like multiple class Implementations based on Enum values & do operations related to that enum inside implementation class.
There are around 8-10 different functions as doCalculations which has business logic based on enum type.
The code structure I'm following doesn't seems to be good practice.
So it will be helpful if someone can give me light on structuring this kind of scenario.
To give a concrete example of Siddarth Sreeni's answer
You create an interface:
public interface Calculations {
Foo doCalculations(SpecificElement element);
}
Then you have your enum implement the interface:
public enum CalendarBasis implements Calculations {
FISCAL_YEAR {
#Override
public Foo doCalculations(SpecificElement element) {
return new OtherFoo();
}
},
CALENDAR {
#Override
public Foo doCalculations(SpecificElement element) {
return new Foo();
}
}
}
Your main doCalculations method would then look like:
public Foo doCalculations(SpecificElement specificElement) {
return specificElement.getCalendarBasis().doCalculations(specificElement);
}
I think you can use EnumMap. If your strategies are stateless (as appears to be the case in your examples), then you simply initialize a map with all of your strategies and use StrategyType to retrieve the one you want.
enum CalendarBasisStrategyType { FISCAL_YEAR, CALENDAR }
static EnumMap<CalendarBasisStrategyType, CalendarBasisStrategy> lookupStrategy = new EnumMap();
{
lookupStrategy.put(FISCAL_YEAR, new FiscalYearStrategyObject());
lookupStrategy.put(CALENDAR, new CalenderBasisStrategyObject());
}
CalendarBasisStrategy toStrategy(CalendarBasisStrategyType type) {
return lookupStrategy.get(type);
}
If it is not stateless then you can use Factory for Creating Objects.
enum CalendarBasisStrategyType { FISCAL_YEAR, CALENDAR }
static EnumMap<CalendarBasisStrategyType, CalendarBasisFactory> lookupFactory = new EnumMap();
{
...
}
CalendarBasisStrategy toStrategy(CalendarBasisStrategyType type) {
return lookupFactory.get(type).newInstance();
}
I would strongly consider using the Strategy pattern for this. This should help to keep your code clean and maintainable, by separating different calculations into their own classes. You can use a Factory to get the right type of calculation.
public enum CalendarBasis {
FISCAL_YEAR,
CALENDAR
}
public interface Calculation {
double performCalculation();
}
public class FiscalCalculation implements Calculation {
#Override
public double performCalculation() {
//Perform calculation.
}
}
public class CalendarCalculation implements Calculation {
#Override
public double performCalculation() {
//Perform calculation.
}
}
public class CalculationFactory {
public static Calculation getCalculation(CalendarBasis calendarBasis) {
switch (calendarBasis) {
case CALENDAR: return new CalendarCalculation();
case FISCAL_YEAR: return new FiscalCalculation();
default:
//Should not happen.
throw new IllegalArgumentException("Invalid basis: " + calendarBasis);
}
}
}
//Usage
double result = CalculationFactory.getCalculation(specificObject.getCalendarBasis()).performCalculation();

How to handle children classes with common method not in parent class?

I have the following auto-generated code:
EDIT: It's auto-generated so I'm not allowed to modify it. (If only it were that easy...)
abstract class Foo {
}
class Fuwa extends Foo {
String chocolate() {...}
String muffin() {...}
}
class Fuko extends Foo {
String chocolate() {...}
String cookie() {...}
}
The chocolate() method in both the child classes are literally (aside from variable names) line-for-line identical and essentially interchanable.
Based on client input, I want test the specified children of Foo and validate the response. Currently I have:
class FooFactory {
Foo createFoo(name) {
if (name.equals("fuwa")) {
...
// returns a Fuwa object
} else if (name.equals("fuko")) {
...
// returns Fuko object
}
}
}
class MuffinTester extends FooTester {
boolean test(Foo inputFoo) {
Result x = ((Fuwa) inputFoo).muffin();
return validate(x);
}
private validate(x) {...}
}
class CookieTester extends FooTester {
boolean test(Foo inputFoo) {
Result x = ((Fuko) inputFoo).cookie();
return validate(x);
}
private validate(x) {...}
}
class TesterFactory {
FooTester createTest(name) {
if (name.equals("muffin")) {
...
// returns MuffinTester object
} else if (name.equals("cookie")) {
...
// returns CookieTester object
} else if (name.equals("chocolate")) {
...
// returns ChocolateTester object
}
}
}
The client specifies the Foo and method to be tested and the FooFactory and TestFactory (respectively) instantiate the required objects (there is logic to make sure the request is valid and the Foo contains the method, eg. no testing cookie() on Fuwa).
The problem arises when I try to code ChocolateTester:
class ChocolateTester extends FooTester {
boolean test(Foo inputFoo) {
Result x = ((???) inputFoo).chocolate();
return validate(x);
}
private validate(x) {...}
}
I can't leave inputFoo as just Foo since the compiler doesn't like that it doesn't have a chocolate() method. And I can't cast inputFoo to Fuwa or Fuko since whichever one I don't cast it to gets annoyed that they're being confused with their sibling (even though they're identical when exposed to chocolate for all intents and purposes). It would be great if I could modify Foo, but since it's auto-generated I can't touch it.
The best I could come up with is a bunch of if/else statements:
class ChocolateTester extends FooTester {
boolean test(Foo inputFoo) {
Result x;
if (inputFoo instanceof Fuwa) {
x = ((Fuwa) inputFoo).chocolate();
} else if (inputFoo instanceof Fuko) {
x = ((Fuko) inputFoo).chocolate();
}
return validate(x);
}
private validate(x) {...}
}
But feels really hacky when there are some 15 or so Foo and I have to duplicate the giant if/else block in for other methods the children Foo have in common, say a cake() method. Moreover, this sounds like a maintenance nightmare when a new Foo named Futaro joins in and I have to update the if/else blocks in not only FooFactory but also in ChocolateTester and CakeTester and in any other common methods.
So...
I'm sorry for being so long winded, but basically I want to ask is there a better way to do this (that is not too hacky/unmaintainable)? Is there a simple annotation to force method call to a method which doesn't exist, or a way to cast an object to its actual type, or a use of reflection which can solve this?
Update: I ultimately decided to use reflection with method invocation, see below.
Yes there is!
You can create abstract methods inside of Foo like this:
abstract class Foo {
abstract String Chocolate();
}
OR you turn Foo into an Interface, forcing any implementing classes to have a chocolate() method:
interface Foo {
String chocolate();
}
class Fuwa implements Foo {
String chocolate() {...}
String muffin() {...}
}
class Fuko implements Foo {
String chocolate() {...}
String cookie() {...}
}
After automatically generating the code, you could post-process it to add a suitable interface to the child classes. The exact method you'd use to do this would depend on what build automation you're using already. For example, if you're using ant to run the axis2 code generator, then it'd be straightforward to add some additional steps to the code-generation target that changed each of the generated files.
I posed this question to my boss and what he suggested was that I use reflection to invoke the method.
So in this case:
class ChocolateTester extends FooTester {
boolean test(Foo inputFoo) {
Method chocolateMethod = inputFoo.getClass().getMethod("chocolate");
Result x = chocolateMethod.invoke(inputFoo);
return validate(x);
}
private validate(x) {...}
}
I would need to add some code validate that inputFoo indeed had a chocolate() method and to catch all the exceptions, but this seems like the best solution given the constraint that I cannot modify the auto-generated code.

Anonymous or real class definition when using visitor pattern?

When you use the Visitor pattern and you need to get a variable inside visitor method, how to you proceed ?
I see two approaches. The first one uses anonymous class :
// need a wrapper to get the result (which is just a String)
final StringBuild result = new StringBuilder();
final String concat = "Hello ";
myObject.accept(new MyVisitor() {
#Override
public void visit(ClassA o)
{
// this concatenation is expected here because I've simplified the example
// normally, the concat var is a complex object (like hashtable)
// used to create the result variable
// (I know that concatenation using StringBuilder is ugly, but this is an example !)
result.append(concat + "A");
}
#Override
public void visit(ClassB o)
{
result.append(concat + "B");
}
});
System.out.println(result.toString());
Pros & Cons :
Pros : you do not need to create a class file for this little behavior
Cons : I don't like the "final" keyword in this case : the anonymous class is less readable because it calls external variables and you need to use a wrapper to get the requested value (because with the keyword final, you can't reassign the variable)
Another way to do it is to do an external visitor class :
public class MyVisitor
{
private String result;
private String concat;
public MyVisitor(String concat)
{
this.concat = concat;
}
#Override
public void visit(ClassA o)
{
result = concat + "A";
}
#Override
public void visit(ClassB o)
{
result = concat + "B";
}
public String getResult()
{
return result;
}
}
MyVisitor visitor = new MyVisitor("Hello ");
myObject.accept(visitor);
System.out.println(visitor.getResult());
Pros & Cons :
Pros : all variables are defined in a clean scope, you don't need a wrapper to encapsulate the requested variable
Cons : need an external file, the getResult() method must be call after the accept method, this is quite ugly because you need to know the function call order to correctly use the visitor
You, what's your approach in this case ? Preferred method ? another idea ?
Well, both approaches are valid and imo, it really depends on whether you would like to reuse the code or not. By the way, your last 'Con' point is not totally valid since you do not need an 'external file' to declare a class. It might very well be an inner class...
That said, the way I use Visitors is like this:
public interface IVisitor<T extends Object> {
public T visit(ClassA element) throws VisitorException;
public T visit(ClassB element) throws VisitorException;
}
public interface IVisitable {
public <T extends Object> T accept(final IVisitor<T> visitor) throws VisitorException;
}
public class MyVisitor implements IVisitor<String> {
private String concat;
public MyVisitor(String concat) {
this.concat = concat;
}
public String visit(ClassA classA) throws VisitorException {
return this.concat + "A";
}
public String visit(ClassB classB) throws VisitorException {
return this.concat + "B";
}
}
public class ClassA implements IVisitable {
public <T> T accept(final IVisitor<T> visitor) throws VisitorException {
return visitor.visit(this);
}
}
public class ClassB implements IVisitable {
public <T> T accept(final IVisitor<T> visitor) throws VisitorException {
return visitor.visit(this);
}
}
// no return value needed?
public class MyOtherVisitor implements IVisitor<Void> {
public Void visit(ClassA classA) throws VisitorException {
return null;
}
public Void visit(ClassB classB) throws VisitorException {
return null;
}
}
That way, the visited objects are ignorant of what the visitor wants to do with them, yet they do return whatever the visitor wants to return. Your visitor can even 'fail' by throwing an exception.
I wrote the first version of this a few years ago and so far, it has worked for me in every case.
Disclaimer: I just hacked this together, quality (or even compilation) not guaranteed. But you get the idea... :)
I do not see an interface being implemented in your second example, but I believe it is there. I would add to your interface (or make a sub interface) that has a getResult() method on it.
That would help both example 1 and 2. You would not need a wrapper in 1, because you can define the getResult() method to return the result you want. In example 2, because getResult() is a part of your interface, there is no function that you 'need to know'.
My preference would be to create a new class, unless each variation of the class is only going to be used once. In which case I would inline it anonymously.
From the perspective of a cleaner design, the second approach is preferrable for the same exact reasons you've already stated.
In a normal TDD cycle I would start off with an anonymous class and refactored it out a bit later. However, if the visitor would only be needed in that one place and its complexity would match that of what you've provided in the example (i.e. not complex), I would have left it hanging and refactor to a separate class later if needed (e.g. another use case appeared, complexity of the visitor/surrounding class increased).
I would recommend using the second approach. Having the visitor in its full fledged class also serves the purpose of documentation and clean code. I do not agree with the cons that you have mentioned with the approach. Say you have an arraylist, and you don't add any element to it and do a get, surely you will get a null but that doesn't mean that it is necessarily wrong.
One of the points of the visitor pattern is to allow for multiple visitor types. If you create an anonymous class, you are kind of breaking the pattern.
You should change your accept method to be
public void accept(Visitor visitor) {
visitor.visit(this);
}
Since you pass this into the visitor, this being the object that is visited, the visitor can access the object's property according to the standard access rules.

Java - Method name collision in interface implementation

If I have two interfaces , both quite different in their purposes , but with same method signature , how do I make a class implement both without being forced to write a single method that serves for the both the interfaces and writing some convoluted logic in the method implementation that checks for which type of object the call is being made and invoke proper code ?
In C# , this is overcome by what is called as explicit interface implementation. Is there any equivalent way in Java ?
No, there is no way to implement the same method in two different ways in one class in Java.
That can lead to many confusing situations, which is why Java has disallowed it.
interface ISomething {
void doSomething();
}
interface ISomething2 {
void doSomething();
}
class Impl implements ISomething, ISomething2 {
void doSomething() {} // There can only be one implementation of this method.
}
What you can do is compose a class out of two classes that each implement a different interface. Then that one class will have the behavior of both interfaces.
class CompositeClass {
ISomething class1;
ISomething2 class2;
void doSomething1(){class1.doSomething();}
void doSomething2(){class2.doSomething();}
}
There's no real way to solve this in Java. You could use inner classes as a workaround:
interface Alfa { void m(); }
interface Beta { void m(); }
class AlfaBeta implements Alfa {
private int value;
public void m() { ++value; } // Alfa.m()
public Beta asBeta() {
return new Beta(){
public void m() { --value; } // Beta.m()
};
}
}
Although it doesn't allow for casts from AlfaBeta to Beta, downcasts are generally evil, and if it can be expected that an Alfa instance often has a Beta aspect, too, and for some reason (usually optimization is the only valid reason) you want to be able to convert it to Beta, you could make a sub-interface of Alfa with Beta asBeta() in it.
If you are encountering this problem, it is most likely because you are using inheritance where you should be using delegation. If you need to provide two different, albeit similar, interfaces for the same underlying model of data, then you should use a view to cheaply provide access to the data using some other interface.
To give a concrete example for the latter case, suppose you want to implement both Collection and MyCollection (which does not inherit from Collection and has an incompatible interface). You could provide a Collection getCollectionView() and MyCollection getMyCollectionView() functions which provide a light-weight implementation of Collection and MyCollection, using the same underlying data.
For the former case... suppose you really want an array of integers and an array of strings. Instead of inheriting from both List<Integer> and List<String>, you should have one member of type List<Integer> and another member of type List<String>, and refer to those members, rather than try to inherit from both. Even if you only needed a list of integers, it is better to use composition/delegation over inheritance in this case.
The "classical" Java problem also affects my Android development...
The reason seems to be simple:
More frameworks/libraries you have to use, more easily things can be out of control...
In my case, I have a BootStrapperApp class inherited from android.app.Application,
whereas the same class should also implement a Platform interface of a MVVM framework in order to get integrated.
Method collision occurred on a getString() method, which is announced by both interfaces and should have differenet implementation in different contexts.
The workaround (ugly..IMO) is using an inner class to implement all Platform methods, just because of one minor method signature conflict...in some case, such borrowed method is even not used at all (but affected major design semantics).
I tend to agree C#-style explicit context/namespace indication is helpful.
The only solution that came in my mind is using referece objects to the one you want to implent muliple interfaceces.
eg: supposing you have 2 interfaces to implement
public interface Framework1Interface {
void method(Object o);
}
and
public interface Framework2Interface {
void method(Object o);
}
you can enclose them in to two Facador objects:
public class Facador1 implements Framework1Interface {
private final ObjectToUse reference;
public static Framework1Interface Create(ObjectToUse ref) {
return new Facador1(ref);
}
private Facador1(ObjectToUse refObject) {
this.reference = refObject;
}
#Override
public boolean equals(Object obj) {
if (obj instanceof Framework1Interface) {
return this == obj;
} else if (obj instanceof ObjectToUse) {
return reference == obj;
}
return super.equals(obj);
}
#Override
public void method(Object o) {
reference.methodForFrameWork1(o);
}
}
and
public class Facador2 implements Framework2Interface {
private final ObjectToUse reference;
public static Framework2Interface Create(ObjectToUse ref) {
return new Facador2(ref);
}
private Facador2(ObjectToUse refObject) {
this.reference = refObject;
}
#Override
public boolean equals(Object obj) {
if (obj instanceof Framework2Interface) {
return this == obj;
} else if (obj instanceof ObjectToUse) {
return reference == obj;
}
return super.equals(obj);
}
#Override
public void method(Object o) {
reference.methodForFrameWork2(o);
}
}
In the end the class you wanted should something like
public class ObjectToUse {
private Framework1Interface facFramework1Interface;
private Framework2Interface facFramework2Interface;
public ObjectToUse() {
}
public Framework1Interface getAsFramework1Interface() {
if (facFramework1Interface == null) {
facFramework1Interface = Facador1.Create(this);
}
return facFramework1Interface;
}
public Framework2Interface getAsFramework2Interface() {
if (facFramework2Interface == null) {
facFramework2Interface = Facador2.Create(this);
}
return facFramework2Interface;
}
public void methodForFrameWork1(Object o) {
}
public void methodForFrameWork2(Object o) {
}
}
you can now use the getAs* methods to "expose" your class
You can use an Adapter pattern in order to make these work. Create two adapter for each interface and use that. It should solve the problem.
All well and good when you have total control over all of the code in question and can implement this upfront.
Now imagine you have an existing public class used in many places with a method
public class MyClass{
private String name;
MyClass(String name){
this.name = name;
}
public String getName(){
return name;
}
}
Now you need to pass it into the off the shelf WizzBangProcessor which requires classes to implement the WBPInterface... which also has a getName() method, but instead of your concrete implementation, this interface expects the method to return the name of a type of Wizz Bang Processing.
In C# it would be a trvial
public class MyClass : WBPInterface{
private String name;
String WBPInterface.getName(){
return "MyWizzBangProcessor";
}
MyClass(String name){
this.name = name;
}
public String getName(){
return name;
}
}
In Java Tough you are going to have to identify every point in the existing deployed code base where you need to convert from one interface to the other. Sure the WizzBangProcessor company should have used getWizzBangProcessName(), but they are developers too. In their context getName was fine. Actually, outside of Java, most other OO based languages support this. Java is rare in forcing all interfaces to be implemented with the same method NAME.
Most other languages have a compiler that is more than happy to take an instruction to say "this method in this class which matches the signature of this method in this implemented interface is it's implementation". After all the whole point of defining interfaces is to allow the definition to be abstracted from the implementation. (Don't even get me started on having default methods in Interfaces in Java, let alone default overriding.... because sure, every component designed for a road car should be able to get slammed into a flying car and just work - hey they are both cars... I'm sure the the default functionality of say your sat nav will not be affected with default pitch and roll inputs, because cars only yaw!

Categories

Resources