I've never been so good at design because there are so many different possibilities and they all have pros and cons and I'm never sure which to go with. Anyway, here's my problem, I have a need for many different loosly related classes to have validation. However, some of these classes will need extra information to do the validation. I want to have a method validate that can be used to validate a Object and I want to determine if an Object is validatable with an interface, say Validatable. The following are the two basic solutions I can have.
interface Validatable {
public void validate() throws ValidateException;
}
interface Object1Validatable {
public void validate(Object1Converse converse) throws ValidateException;
}
class Object1 implements Object1Validatable {
...
public void validate() throws ValidateException {
throw new UnsupportedOperationException();
}
}
class Object2 implements Validatable {
...
public void validate() throws ValidateException {
...
}
}
This is the first solution whereby I have a general global interface that something that's validatable implements and I could use validate() to validate, but Object1 doesn't support this so it's kind of defunc, but Object2 does support it and so may many other classes.
Alternatively I could have the following which would leave me without a top level interface.
interface Object1Validatable {
public void validate(Object1Converse converse) throws ValidateException;
}
class Object1 implements Object1Validatable {
...
public void validate(Object1Converse converse) throws ValidateException {
...
}
}
interface Object2Validatable {
public void validate() throws ValidateException;
}
class Object2 implements Object2Validatable {
...
public void validate() throws ValidateException {
...
}
}
I think the main problem I have is that I'm kind of stuck on the idea of having a top level interface so that I can at least say X or Y Object is validatable.
what about this :
interface Validatable {
void validate(Validator v);
}
class Object1 implements Validatable{
void validate(Validator v){
v.foo
v.bar
}
}
class Object1Converse implements Validator{
//....
}
class Object2 implements Validatable{
void validate(Validator v){
//do whatever you need and ingore validator ?
}
}
What do you care if Object2 receives an unneeded argument ? if it is able to operatee correctly without it it can just ignore it right ?
If you are worried about introducing an unneeded dependency between object2 and Object1Converse then simply specify an interface to decouple them and use that as the validator.
Now I must add that having a mixed model where you have both object able to self validate and object which need external state information to validate sounds weird.
care to illustrate ?
Perhaps the apache commons validator project would be useful here - either directly or as a model for how to attack your problem. They effectively have a parallel set of objects that do the validation - so there is no interface on the objects, just the presence/absence of a related validator for the object/class.
This is in C#, but the same ideas can certainly be implemented in many other languages.
public class MyClass {
//Properties and methods here
}
public class MyClassValidator : IValidator<MyClass> {
IList<IValidatorError> IValidator.Validate(MyClass obj) {
//Perform some checks here
}
}
//...
public void RegisterValidators() {
Validators.Add<MyClassValidator>();
}
//...
public void PerformSomeLogic() {
var myobj = new MyClass { };
//Set some properties, call some methods, etc.
var v = Validators.Get<MyClass>();
if(v.GetErrors(myobj).Count() > 0)
throw new Exception();
SaveToDatabase(myobj);
}
As simple solution to the "can an object be validated" problem is to add a third interface.
This third interface is an empty one that parents both of the others, meaning you can just check against that interface (Assuming you aren't worried about someone spoofing being validate-able), and then iteratively check against the possible validation interfaces if you need to actually validate.
Example:
interface Validateable
{
}
interface EmptyValidateable inherits Validateable //Or is it implements?
{
void validate() throws ValidateException;
}
interface Objectvalidateable inherits Validateable
{
void validate(Object validateObj);
}
Related
While trying to program to interfaces, I regularly find myself in the following situation:
I have several very similar classes representing containers or algorithms for different types.
I would like to define a common interface for these classes.
Consider, e.g., a string container.
Such a container will likely have string processing methods.
Since those methods are easily represented using generic interfaces, I am ignoring them.
Here, I want to focus on methods that can be used to process or provide references to other string containers:
public class StringContainer {
StringContainer produce() {
return new StringContainer();
}
void consume(StringContainer stringContainer) {
}
}
This class can be used just fine in code like:
public class Main {
public static void main(String[] args) {
StringContainer stringContainer = new StringContainer();
stringContainer.produce();
stringContainer.consume(stringContainer);
}
}
The problem is: I'm using a concrete class and not an interface to refer to the string container.
What if I want to introduce a double container or a list container later and want to leave the rest of the code as is?
Maybe generics could form a solution to this problem?
Here is my try.
I first define a generic container class:
interface Container<T> {
Container<T> produce();
void consume(Container<T> container);
}
I then create type-specific implementations of the form:
public class StringContainer implements Container<String> {
#Override
public Container<String> produce() {
return new StringContainer();
}
#Override
public void consume(Container<String> container) {
}
public void consume(StringContainer container) {
}
}
The above classes can be used as follows:
public class Main {
public static void main(String[] args) {
Container<String> stringContainer = new StringContainer();
stringContainer.produce();
stringContainer.consume(stringContainer);
}
}
However, the above approach has several drawbacks:
The consume(Container<String> container) method accepts other types than StringContainer.
In consume(Container<String> container), the parametrized type Container<String> has to be used when processing container. I can't assign it to StringContainer variables (without type checks or casts).
The alternative consume(StringContainer container) method is defined for StringContainer objects, but can't be called from a Container<String> reference.
Finally, to me, the line Container<String> stringContainer = new StringContainer(); has an awkward-looking notation that suggests a diamond operator is missing in new StringContainer().
What is the idiomatic way to define a general interface for several type-specific classes, which doesn't have (all) the above drawbacks?
Should I ignore point 4 and address points 1 and 2 by adding type checks/casts, throwing an UnsupportedOperationException or IllegalArgumentException in case passed objects aren't StringContainers?
Or is there another way to use generics? Can type bounds help me, for example?
Or should I look for a solution outside of generics?
Update:
Based on the answers given so far, I have come to realize that I had conflicting goals:
On the one hand, I wanted to restrict the types accepted by container methods (as described by points 1 and 2).
On the other hand, I wanted to address and pass container types using an interface reference (as hinted at by point 3 and my implicit desire to keep the second main method as is).
I now see that these goals cannot both be reached statically.
Since I don't want to rephrase my question in retrospect, I'll forget about my second (rather implicit) goal and mark the first-posted solution that addressed points 1 and 2 as the answer.
Is this what you're looking for? It's called a recursive type bound.
interface Container<T extends Container<T>> {
T produce();
void consume(T container);
}
class StringContainer implements Container<StringContainer> {
#Override
public StringContainer produce() {
return new StringContainer();
}
#Override
public void consume(StringContainer container) {
}
}
It seems that you have two APIs, and you should treat them separately with separate interfaces. Yes, you can merge them into the same interface with distinct method names.
I think you should have two interfaces for your "containers" and for your "containers of containers". Here's what I'd make it:
interface Container<T> {
T produce();
void consume(T container);
}
interface MetaContainer<T, R extends Container<T>> {
R produceContainer();
void consumeContainer(R container);
}
class StringContainer implements Container<String>, MetaContainer<String, StringContainer> {
#Override
public String produce() {
return "";
}
#Override
public void consume(String container) {
}
#Override
public StringContainer produceContainer() {
return this;
}
#Override
public void consumeContainer(StringContainer container) {
}
}
I implemented both interfaces using the same class to emulate your StringContainer class.
I do have a service which needs to handle two types of meal.
#Service
class MealService {
private final List<MealStrategy> strategies;
MealService(…) {
this.strategies = strategies;
}
void handle() {
var foo = …;
var bar = …;
strategies.forEach(s -> s.remove(foo, bar));
}
}
There are two strategies, ‘BurgerStrategy’ and ‘PastaStrategy’. Both implements Strategy interface with one method called remove which takes two parameters.
BurgerStrategy class retrieves meals of enum type burger from the database and iterate over them and perform some operations. Similar stuff does the PastaStrategy.
The question is, does it make sense to call it Strategy and implement it this way or not?
Also, how to handle duplications of the code in those two services, let’s say both share the same private methods. Does it make sense to create a Helper class or something?
does it make sense to call it Strategy and implement it this way or not
I think these classes ‘BurgerStrategy’ and ‘PastaStrategy’ have common behaviour. Strategy pattern is used when you want to inject one strategy and use it. However, you are iterating through all behaviors. You did not set behaviour by getting one strategy and stick with it. So, in my honour opinion, I think it is better to avoid Strategy word here.
So strategy pattern would look like this. I am sorry, I am not Java guy. Let me show via C#. But I've provided comments of how code could look in Java.
This is our abstraction of strategy:
public interface ISoundBehaviour
{
void Make();
}
and its concrete implementation:
public class DogSound : ISoundBehaviour // implements in Java
{
public void Make()
{
Console.WriteLine("Woof");
}
}
public class CatSound : ISoundBehaviour
{
public void Make()
{
Console.WriteLine("Meow");
}
}
And then we stick with one behaviour that can also be replaced:
public class Dog
{
ISoundBehaviour _soundBehaviour;
public Dog(ISoundBehaviour soundBehaviour)
{
_soundBehaviour = soundBehaviour;
}
public void Bark()
{
_soundBehaviour.Make();
}
public void SetAnotherSound(ISoundBehaviour anotherSoundBehaviour)
{
_soundBehaviour = anotherSoundBehaviour;
}
}
how to handle duplications of the code in those two services, let’s say both share the same private methods.
You can create one base, abstract class. So basic idea is to put common logic into some base common class. Then we should create abstract method in abstract class. Why? By doing this, subclasses will have particular logic for concrete case. Let me show an example.
An abstract class which has common behaviour:
public abstract class BaseMeal
{
// I am not Java guy, but if I am not mistaken, in Java,
// if you do not want method to be overriden, you shoud use `final` keyword
public void CommonBehaviourHere()
{
// put here code that can be shared among subclasses to avoid code duplication
}
public abstract void UnCommonBehaviourShouldBeImplementedBySubclass();
}
And its concrete implementations:
public class BurgerSubclass : BaseMeal // extends in Java
{
public override void UnCommonBehaviourShouldBeImplementedBySubclass()
{
throw new NotImplementedException();
}
}
public class PastaSubclass : BaseMeal // extends in Java
{
public override void UnCommonBehaviourShouldBeImplementedBySubclass()
{
throw new NotImplementedException();
}
}
I have an interface called Section and MapSection which extends section. I have a list of Sections and if it is a MapSection I need to do some additional processing. I can thing of two ways to handle this. I can add a boolean isAMapSection() to the Section interface but that leads to alot of isA.. if I add more types. The other way I could think of is instanceof check but my OOP senses think this is not great either.
curSection instanceof MapSection
which one of these is the right way? or is there another way?
As mentioned above by Oliver Charlesworth's comment, you could use a Visitor Design Pattern to give your code to do different actions depending on the type involved, without having to use a bunch of instanceof's or class equals.
For example, say you have two similar interfaces, Section and MapSection, where for grins will give MapSection one additional method:
interface Section {
void someMethod();
void accept(SectionVisitor visitor);
}
interface MapSection extends Section {
void additionalProcessingMethod();
}
We'll also give Section the accept(...) method to allow action by a Visitor of type SectionVisitor whose interface looks like:
interface SectionVisitor {
void visit(Section section);
void visit(MapSection mapSection);
}
The visit method will hold code that knows which methods to call depending on the type passed into it.
A very simple concrete example could look like:
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
public class VisitorTest {
public static void main(String[] args) {
Random random = new Random();
List<Section> sectionList = new ArrayList<>();
for (int i = 0; i < 10; i++) {
Section section = random.nextBoolean() ? new ConcreteSection() : new ConcreteMapSection();
sectionList.add(section);
}
SectionVisitor visitor = new ConcreteSectionVisitor();
for (Section section : sectionList) {
section.accept(visitor);
}
}
}
interface Section {
void someMethod();
void accept(SectionVisitor visitor);
}
interface MapSection extends Section {
void additionalProcessingMethod();
}
interface SectionVisitor {
void visit(Section section);
void visit(MapSection mapSection);
}
class ConcreteSection implements Section {
#Override
public void someMethod() {
System.out.println("someMethod in ConcreteSection");
}
#Override
public void accept(SectionVisitor visitor) {
visitor.visit(this);
}
}
class ConcreteMapSection implements MapSection {
#Override
public void someMethod() {
System.out.println("someMethod in ConcreteMapSection");
}
#Override
public void additionalProcessingMethod() {
System.out.println("additionalProcessingMethod in ConcreteMapSection");
}
#Override
public void accept(SectionVisitor visitor) {
visitor.visit(this);
}
}
class ConcreteSectionVisitor implements SectionVisitor {
#Override
public void visit(Section section) {
section.someMethod();
}
#Override
public void visit(MapSection mapSection) {
mapSection.someMethod();
mapSection.additionalProcessingMethod();
}
}
Best way might be to add a method "additionalProcessing" to Section. Implement this method to do your additional processing in MapSection, and leave it blank in your other implementations
Sometimes it's fine to have an isXXX method (and the corresponding asXXX method is nice too), but it really depends on how open-ended your object hierarchy is.
For example in StAX the XMLEvent interface will have descendants that represent the different types of events that can come from an XML document. But the list of those types is closed (no-one's going to radically change the XML format any time soon) and very short (there are about 10 different types of events in the StAX API), so it's fine. These interfaces also define the primary nature of their implementations, you wouldn't realistically just tag an object with an XMLEvent interface like you do with Serializable or Iterable.
If your interface is more "behavioural" (for want of a better word), more optional (like Comparable) or too open-ended (like LayoutManager), things like the visitor or the strategy pattern may be more appropriate.
Judging just by the names Section and MapSection, your model seems to belong to the first category but really only you can make that decision. What I definitely wouldn't do is leave it to the client of the code to fool around with instanceof calls. One way or another the solution should be part of Section.
Given the following Class and Service layer signatures:
public class PersonActionRequest {
PersonVO person
// ... other fields
}
public class MyServiceLayerClass {
public void requestAction(PersonActionRequest request)
{
PersonVO abstractPerson = request.getPerson();
// call appropriate executeAction method based on subclass of PersonVO
}
private void executeAction(PersonVO person) {}
private void executeAction(EmployeeVO employee) {}
private void executeAction(ManagerVO manager) {}
private void executeAction(UnicornWranglerVO unicornWrangler) {}
}
As discussed here, java will select the best method based on type info at compile time. (Ie., it will always select executeAction(PersonVO person) ).
What's the most appropriate way to select the correct method?
The internet tells me that using instanceof gets me slapped. However, I don't see the appropraite way to select the method without explictly casting abstractPerson to one of the other concrete types.
EDIT: To Clarify - The VO passed in is a simple ValueObject exposed for web clients to instantiate and pass in. By convention it doesn't have methods on it, it's simply a data structure with fields.
For this reason, calling personVO.executeAction() is not an option.
Thanks
Marty
If executeAction was a method in a base class or interface that was common to PersonVO, EmployeeVO, ManagerVO and UnicornWranglerVO, you could just call abstractPerson.executeAction() instead of having multiple overridden methods.
Your principle obstacle to polymorphism here seems to be a 'dumb-struct' data object + 'manager class' service non-pattern. The "more polymorphic' approach would be for execute() to be a method that the various person implementations override.
Assuming that can't change, the way you do multiple dispatch in Java is with visitor-looking callbacks.
public interface PersonVisitor {
void executeAction(EmployeeVO employee);
void executeAction(ManagerVO manager);
void executeAction(UnicornWranglerVO unicornWrangler);
}
public abstract class PersonVO {
public abstract void accept(PersonVisitor visitor);
}
public class EmployeeVO extends PersonVO {
#Override
public void accept(PersonVisitor visitor) {
visitor.executeAction(this);
}
}
public class MyServiceLayerClass implements PersonVisitor {
public void requestAction(PersonActionRequest request)
{
PersonVO abstractPerson = request.getPerson();
abstractPerson.accept(this);
}
public void executeAction(EmployeeVO employee) {}
public void executeAction(ManagerVO manager) {}
public void executeAction(UnicornWranglerVO unicornWrangler) {}
}
You could change the way you are approaching the design and use a Visitor, passing the executor into the Person and have the person type determine which to call.
The Visitor pattern is often used to overcome Java lacking double-dispatch.
I would explicitly cast the abstractPerson. Not only does it ensure the JVM gets the right method, it makes it a hell of a lot easier to read and ensure you know what's going on.
In Java i have abstract class named Operation and three its subclasses called OperationActivation, OperationPayment and OperationSendEmail.
ADDED FROM COMMENT: Operation* objects are EJB Entity Beans so I can't have business logic inside them.
No I want to create processor class like this:
public class ProcessOperationService {
public void processOperation(Operation operation) {
out.println("process Operation");
process(operation);
}
public void process(OperationActivation operationActivation) {
out.println("process Activation");
}
public void process(OperationPayment operationPayment) {
out.println("process Payment");
}
public void process(OperationSendEmail operationSendEmail) {
out.println("process OperationSendEmail");
}
}
Processing each operation requires different logic so I want to have three different methods , one for each operation.
Of course this code doesn't compile. Am I missing something or it can't be done that way?
You are mixing up overloading and polymorphic method handling. When you overload methods based on the parameter type, that is static polymorphism. Those methods should be called from code that knows at compile-time what the type is. You could possibly do the following, but it wouldn't be clean object-oriented code:
public class ProcessOperationService {
public void processOperation(Operation operation) {
out.println("process Operation");
if (operation instanceof OperationActivation)
process((OperationActivation)operation);
else if (operation instanceof OperationPayment)
process((OperationPayment)operation);
...
}
public void process(OperationActivation operationActivation) {
out.println("process Activation");
}
...
}
It would be much better to let the automatic run-time polymorphism work, by doing as Brian Agnew suggested, and making process be a method of each Operation subtype itself.
Shouldn't your Operation* objects be doing the work themselves ? So you can write (say)
for (Operation op : ops) {
op.process();
}
You can encapsulate the logic for each particular operation in its own class, and that way everything related to OperationPayment remains in the OperationPayment class. You don't need a Processor class (and so you don't need to modify a Processor class everytime you add an Operation)
There are more complex patterns to enable objects to mediate wrt. what they need to execute, but I'm not sure you need something that complex at this stage.
Assumption: Operation* objects are subclasses of Operation
Unless the processOperation(Operation) method is performing some common functionality, you could just remove it and expose the process(Operation) methods.
The Command Pattern (JavaWorld Explanation) might be useful, but it's tricky to tell exactly what properties you want from your question.
The problem with the code is that any object that matches one of the process(Operation*) methods will also match the process(Operation) method. As there are 2 methods that can be used, the compiler is warning you of an ambiguous situation.
If you really want/need the code above, I would suggest implementing the process(Operation*) methods, and modify the process(Operation) method so it is called processCommon(Operation). Then, the first thing each process(Operation*) does is call processCommon.
Alternatively, you can code exactly as Avi said, using instanceof comparisons.
Neither is ideal, but it will accomplish what you want.
So you have an abstract class called 'Operation' and it has 3 classes extending it. Not sure if this is what you are after but I'd imagine it be designed something like this:
Operation.java
public abstract class Operation {
public abstract void process();
}
OperationActivation.java
public class OperationActivation extends Operation {
public void process() {
//Implement OperationActivation specific logic here
}
}
OperationPayment.java
public class OperationPayment extends Operation {
public void process() {
//Implement OperationPayment specific logic here
}
}
OperationSendEmail.java
public class OperationSendEmail extends Operation {
public void process() {
//Implement OperationSendEmail spepcific logic here
}
}
ProcessOperationService.java
public class ProcessOperationService {
public void processOperation(Operation operation) {
out.println("process Operation");
operation.process();
}
}
Won't the Visitor pattern be of use here ?
The class Operation can declare an "accept" method that takes a Visitor object and the subclasses can have provide the implementation :
public interface IOperationVisitor {
public void visit (OperationActivation visited);
public void visit (OperationPayment visited);
public void visit (OperationSendEmail visited);
}
abstract class Operation {
public void accept(IOperationVisitor visitor)();
}
class OperationActivation extends Operation {
public void accept(IOperationvisitor visitor) {
visitor.visit(this);
}
}
Similarly define "accept" method for classes OperationPayment and OperationSendEmail ..
Now your class can implement the visitor :
public class ProcessOperationService implements IOperationVisitor {
public void processOperation(Operation operation) {
operation.accept(this);
}
public void visit (OperationActivation visited) {
// Operation Activation specific implementation
}
public void visit (OperationPayment visited) {
// OperationPayment specific implementation
}
public void visit ((OperationSendEmail visited) {
// (Operation SendEmail specific implementation
}
}