How to deal with Java Polymorphism in Service Oriented Architecture - java

What is the path of least evil when dealing with polymorphism and inheritance of entity types in a service-oriented architecture?
A principle of SOA (as I understand it) is to have entity classes as mere data constructs, lacking in any business logic. All business logic is contained in narrow-scoped, loosely-coupled services. This means service implementations are as small as possible furthering the loose coupling, and means the entities avoid having to know about every behaviour the system may perform on them.
Due to Java's quite baffling decision to use the declared type when deciding which overloaded method to use, any polymorphic behaviour in the service implementations is instead replaced with a series of conditionals checking object.getClass() or using instanceof. This seems rather backward in an OOPL.
Is the use of conditionals the accepted norm in SOA? Should inheritance in entities be abandoned?
UPDATE
I definitely mean overloading and not overriding.
I define SOA to mean that behaviour of the system is grouped by use case into interfaces, and then the logic for these is implemented in one class per interface, generally. As such an entity class (say Product) becomes nothing more than a POJO with getters and setters. It absolutely should not contain any business logic related to a service, because then you introduce one focal point of coupling whereby the entity class needs to know about all business processes that may ever operate on it, completely negating the purpose of a loosely-coupled SOA.
So, being that one should not embed business process-specific behaviour in an entity class, one cannot use polymorphism with these entity classes - there is no behaviour to override.
UPDATE 2
The above behaviour is more simply explained as an overloaded path is chosen at compile-time, and an overridden path at run-time.
It'd be bad practice to have a subclass of your service implementation for each subtype of the domain model class it's acting on, so how do people get around the overloading-at-compile-time issue?

You can avoid this problem by designing the business logic in different classes based on the entity type, based on single responsibility principle it would be the best way to go when you place business logic in a service layer and use a factory to create logic implementation, for example
enum ProductType
{
Physical,
Service
}
interface IProduct
{
double getRate();
ProductType getProductType();
}
class PhysicalProduct implements IProduct
{
private double rate;
public double getRate()
{
return rate;
}
public double getProductType()
{
return ProductType.Physical;
}
}
class ServiceProduct implements IProduct
{
private double rate;
private double overTimeRate;
private double maxHoursPerDayInNormalRate;
public double getRate()
{
return rate;
}
public double getOverTimeRate()
{
return overTimeRate;
}
public double getMaxHoursPerDayInNormalRate;()
{
return maxHoursPerDayInNormalRate;
}
public double getProductType()
{
return ProductType.Service;
}
}
interface IProductCalculator
{
double calculate(double units);
}
class PhysicalProductCalculator implements IProductCalculator
{
private PhysicalProduct product;
public PhysicalProductCalculator(IProduct product)
{
this.product = (PhysicalProduct) product;
}
double calculate(double units)
{
//calculation logic goes here
}
}
class ServiceProductCalculator implements IProductCalculator
{
private ServiceProduct product;
public ServiceProductCalculator(IProduct product)
{
this.product = (ServiceProduct) product;
}
double calculate(double units)
{
//calculation logic goes here
}
}
class ProductCalculatorFactory
{
public static IProductCalculator createCalculator(IProduct product)
{
switch (product.getProductType)
{
case Physical:
return new PhysicalProductCalculator ();
case Service:
return new ServiceProductCalculator ();
}
}
}
//this can be used to execute the business logic
ProductCalculatorFactory.createCalculator(product).calculate(value);

It took me a while from reading this to work out what you were really asking for.
My interpretation is that you have a set of POJO classes where when passed to a service you want the service to be able to perform different operations depending on the the particular POJO class passed to it.
Usually I'd try and avoid a wide or deep type hierarchy and deal with instanceof etc. where the one or two cases are needed.
When for whatever reason there has to be a wide type hierarchy I'd probably use a handler pattern kind of like below.
class Animal {
}
class Cat extends Animal {
}
interface AnimalHandler {
void handleAnimal(Animal animal);
}
class CatHandler implements AnimalHandler {
#Override
public void handleAnimal(Animal animal) {
Cat cat = (Cat)animal;
// do something with a cat
}
}
class AnimalServiceImpl implements AnimalHandler {
Map<Class,AnimalHandler> animalHandlers = new HashMap<Class, AnimalHandler>();
AnimalServiceImpl() {
animalHandlers.put(Cat.class, new CatHandler());
}
public void handleAnimal(Animal animal) {
animalHandlers.get(animal.getClass()).handleAnimal(animal);
}
}

Due to Java's quite baffling decision to use the declared type when
deciding which overloaded method to use
Whoever gave you that idea? Java would be a worthless language if it were like that!
Read this: Java Tutorial > Inheritance
Here's a simple test program:
public class Tester{
static class Foo {
void foo() {
System.out.println("foo");
}
}
static class Bar extends Foo {
#Override
void foo() {
System.out.println("bar");
}
}
public static void main(final String[] args) {
final Foo foo = new Bar();
foo.foo();
}
}
The Output is of course "bar", not "foo"!!

I think there is a confusion of concerns here. SOA is an architectural way to solve interaction between components. Each component within a SOA solution will handle a context within a larger domain. Each context is a domain of it self. In other words, SOA is something that allows for lose coupling in between domain contexts, or applications.
Object Orientation in Java, when working in this kind of an environment, will apply to each domain. So hierarchies and rich domain objects modelled using something like domain driven design will live on a level below the services in a SOA solution. There is a tier between the service exposed to other contexts and the detailed domain model which will create rich objects for the domain to work with.
To solve each context/applications architecture with SOA will not provide a very good application. Just as solving the interaction between them using OO.
So to try to answer the bounty question more specifically:
It's not a matter of engineering around the issue. It's a matter of applying the correct pattern to each level of design.
For a large enterprise ecosystem SOA is the way I would solve interaction in between systems, for example HR system and payroll. But when working with HR (or probably each context within HR) and payroll I would use the patterns from DDD.
I hope that clears the waters a bit.

Having thought about this a bit more I've thought on an alternative approach that makes for a simpler design.
abstract class Animal {
}
class Cat extends Animal {
public String meow() {
return "Meow";
}
}
class Dog extends Animal {
public String bark() {
return "Bark";
}
}
class AnimalService {
public String getSound(Animal animal) {
try {
Method method = this.getClass().getMethod("getSound", animal.getClass());
return (String) method.invoke(this, animal);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
public String getSound(Cat cat) {
return cat.meow();
}
public String getSound(Dog dog) {
return dog.bark();
}
}
public static void main(String[] args) {
AnimalService animalService = new AnimalService();
List<Animal> animals = new ArrayList<Animal>();
animals.add(new Cat());
animals.add(new Dog());
for (Animal animal : animals) {
String sound = animalService.getSound(animal);
System.out.println(sound);
}
}

Related

Design Patterns - One public class utilizing many hidden classes

I have gone through http://www.dofactory.com/net/design-patterns in trying to find out the most efficient to create a design pattern in which "one visible class utilizes many hidden classes" to create a fluent API. Below is the code I currently have:
public class VisibleClass {
Private OrderClass order;
private ReceiptClass receipt;
public VisibleClass makeOrder() {
if (!(order instanceof OrderClass))
order = new OrderClass();
order.make();
return this;
}
public VisibleClass printReceipt() {
if (!(receipt instanceof ReceiptClass))
receipt = new ReceiptClass();
receipt.print();
return this;
}
}
class OrderClass implements IOrder {
public void make() {}
}
class ReceiptClass implements IReceipt {
public void print() {}
}
interface IOrder { void make(); }
interface IReceipt { void print(); }
Here is how I am currently using the API:
public static void main(String[] args) {
VisibleClass x = new VisibleClass();
x.makeOrder().printReceipt();
}
It this a good approach? Can a better approach be used for it?
*EDIT: Also, I should add that the VisibleClass will implement all methods of the hidden classes.
Your approach is quite good. Here some recommendations:
1 Change class member types to their interfaces as for 'Program to an interface, not an implementation' principle:
public class VisibleClass {
private IOrder order;
private IReceipt receipt;
2 Do you really need to check class types in makeOrder and printReceipt methods ? Creating instances after null check seems enough:
public VisibleClass makeOrder() {
if (null == order)
order = new OrderClass();
order.make();
return this;
}
public VisibleClass printReceipt() {
if (null == receipt)
receipt = new ReceiptClass();
receipt.print();
return this;
}
3 This approach is valid until methods of VisibleClass will be called by a single thread. If you're going to place it in a multi-thread program, you should ensure that there are only one instances of OrderClass and ReceiptClass each. There are 3 ways you can follow:
a. Create instaces of OrderClass and ReceiptClass in constructor and make VisibleClass singleton.
b. Make OrderClass and ReceiptClass singleton and remove new lines.
c. Create instances surrounded with synchronized block in makeOrder and printReceipt methods.
one visible class utilizes many hidden classes
don't do that with business classes. Fluent syntax's is great for configuration etc, but not for plain business code.
The reason is that the class itself losses control over it's state which can put it in an inconsistent state (i.e generate faulty results).
There is even a principle called Law of Demeter which is about just that.
If you have a business requirement that a receipt should be printed on a new order you should just return it as a return value.
var receipt = visibleClass.makeOrder();
As for using interfaces for entity/business classes, why do you do that? why would you want to abstract away those? The usually do not have any other dependencies or different types of implementations.
You can try using the Facade Design pattern
Or may be try using a Decorator Pattern

Calling different services from domain classes of same base class

The question is mostly a design question (somewhat related to ddd). Sorry about the contrived example:
Assume, you have (domain) classes representing different types of fruits: apple, cherry and so on. Now suppose you have to implement some behavior of pressing out the juice. A caller should be able to invoke squeezing without knowing which specific fruit he's got.
Where should I put this behavior?
Surely, one could define a fruit interface / base class function
Fruit#squeeze()
and let all subclasses implement their own behavior.
Now a caller could simply do something like this:
Fruit f = new Cherry();
f.squeeze();
But what should be done if squeezing isn't as simple and involves more complex behavior like calling different external services, for each a fruit a different one like
AppleJuicerService#squeeze(Apple a)
and
CherryJuicerService#squeeze(Cherry c)
? It feels wrong to call services from a domain class.
I've read about the double dispatch pattern which seems not to fit here, as every subclass needs a different service.
My question would be: What can be done here to get a "clean" design?
EDIT:
Thanks for all your answers so far. I'll try to clarify the problem a bit. I'll try to give another, hopefully less contrived example for the problem I'm trying to state here:
Consider a Message base class which allows to show its content as a String.
interface Message {
String showContent();
}
Now suppose we have different types of messages like an EMailMessage:
class EMailMessage implements Message {
//some specific parameters for email
private EmailAddress recipientEmail;
public String showContent() {
//here the content would be converted to string
return "the content of an EMail"
}
}
Another type would be an SMSMessage:
class SMSMessage implement SMSMessage {
//some specific parameters for SMS
private TelNumber recepientTelephoneNumber;
public String showContent() {
//here the content would be converted to string
return "the content of a SMS"
}
}
Furthermore suppose, Messages are modeled as Entities and therefore can be persisted in a database. Though quite technically, assume that some Dependency Injection Framework like Spring is used to inject dependencies.
In analogy to the fruit example, consider we have to implement a send() behaviour which sends the Message to the recipient. Furthermore, assume that sending an EMail involves different logic than an SMS. Now, the question: Where should one put the logic of sending a Message?
Usually I'd opt to create a service for sending an SMS for example which would encapsulate e.g. the API of an SMS service provider. Furthermore, I'd create another service to encapsulate sending an EMail.
interface SendMessageService<T extends Message> {
void send(T message);
}
class SendEmailService extends SendMessageService<EMailMessage> {
public void send(EMailMessage message) {
//send the EMail
}
}
class SendSMSService extends SendMessageService<SMSMessage> {
public void send(SMSMessage message) {
//send the SMS
}
}
The drawback of this approach is that you cannot send a Message without determining its concrete subclass, i.e. something like the following is not directly possible
List<Message> messages = //Messages of different types
SendMessageService service = //???
for (Message m : messages) {
service.send(m);
}
Surely one could create a factory for creating Services according to the specific type of message. But that somewhat means cloning the inheritance hierarchy of Message. Is there some better way to achieve the desired result? Or am I missing something? Or would it be better to somehow inject the service into the entity?
You can delegate the work to a SqueezeBehavior interface and let each implementation define how to squeeze a Fruit or specific Fruit. This is a raw idea (it means it can be improved but is good as a first step):
interface SqueezeBehavior<T> {
void squeeze(T squeezeMe);
}
interface FruitSqueezeBehavior<T extends Fruit> extends SqueezeBehavior<T> {
}
class FruitSqueezer implements FruitSqueezeBehavior<Fruit> {
public void squeeze(Fruit fruit) {
System.out.println("squizing any fruit");
}
}
class AppleSqueezer implements FruitSqueezeBehavior<Apple> {
public void squeeze(Apple apple) {
System.out.println("squizing apple");
}
}
class CherrySqueezer implements FruitSqueezeBehavior<Cherry> {
public void squeeze(Cherry cherry) {
System.out.println("squizing cherry");
}
}
class FruitService {
public void foo(Fruit fruit) {
FruitSqueezeBehavior fruitSqueezer = ...
fruitSqueezer.squeeze(fruit);
}
}
Have a baseclass Fruit which defines the standard behaviour. When you have to use a more complex implementation you can override the appropriate method.
class Fruit {
public void Squeeze(){
// Standard squeeze behaviour
}
}
class Apple extends Fruit {
#Override
public void Squeeze(){
// Complex squeeze behaviour
}
}
class Cherry extends Fruit {
// Nothing special, cherries are easy to squeeze
}
If you have to define specific implementations for specific types, you will always have to define the behaviour somewhere. If this is too much for one method then you can call a more detailed class to do it for you.
You could work with a factory and do something like this
class FruitManipulator {
void Squeeze(Fruit f){
// Switch over fruit, create new service depending on the type
}
}
interface JuiceService<T extends Fruit> {
void Squeeze(T f);
}
class AppleJuiceService implements JuiceService<Apple> {
void Squeeze(Apple apple){
// Do your thing
}
}
And use it like this:
FruitManipulator service = new FruitManipulator();
service.Squeeze(new Apple());
You might want to find a better example though: the Squeeze() analogy isn't easy to work with. Perhaps expand on what a squeeze actually means?
You may consider DomainEvents. This helps you decouple Domain models from external service(usually stateless bean need injected)
interface Fruit {
void squeeze();
}
class Apple implements Fruit {
#Override
public void squeeze(){
// domain rules validations
DomainEvents.raise(new AppleSequeezedEvent(this));
}
}
class Cherry extends Fruit {
#Override
public void squeeze(){
// domain rules validations
DomainEvents.raise(new CherrySequeezedEvent(this));
}
}
class Banana extends Fruit {
#Override
public void squeeze(){
// domain rules validations
// hmm...No one cares banana...
}
}
class DomainEvents {
private static List<DomainEventHandler> handlers = new ArrayList<DomainEventHandler>();
public static void register(DomainEventHandler handler) {
this.handler.add(handler);
}
public static void raise(DomainEvent event) {
for (DomainEventHander handler: handlers) {
if (handler.subscribe(event.getClass()) {
handler.handle(event);
}
}
}
}
Now when you test apple, you could register some handler mock/stub:
#Test
public void tellsAppleIsSqueezed() throws Throwable {
DomainEventHandler stub = new FruitSqueezedEventHandlerStub(Apple.class);
DomainEvents.register(stub );
Apple apple = new Apple();
apple.squeeze();
//assert state change of apple if any before you publishing the event
assertThat(stub.getSqueezed(), sameInstance(apple));
}
You can test the real handler in their own unit test cases.
But I think this solution add extra complexity.

Trouble implementing strategy and composite pattern to give varying behaviour in a game

I'm running into real trouble trying to complete a practical that requires using strategy and composite pattern. I am trying to create a collection of vehicles which can have different behavior depending on the surface they are on. However, these vehicles can have more than one behaviour on a surface - for example, they could have snow drive and rain drive at the same time, if the weather conditions are set to snow and rain.
I have a class called AbstractVehicle, which has two concrete subclasses, Car and Boat.
I then have an interface called IBehaviour. Implementing this interface is two abstract classes called LandBehaviour and WaterBehaviour (which are the top tier of the composite pattern). Each of these have a collection of subclasses. Focussing solely on LandBehaviour, its subclasses are SnowBehaviour, StandardBehaviour and a few others including LandAssembly.
The idea was that I would put the code for the upper-tier of composite in LandBehaviour. Then, each of the concrete subclasses would have empty implementations of the add, remove and list parts of composite, with the LandAssembly class containing the code needed to actually combine various behaviours together.
This is intended to produce the result that, for example, a car could have both StandardBehaviour and SnowBehaviour at the same time.
Rather than posting large amounts of code (and there is a lot of it), I was hoping for some feedback on the basic structure I am trying to implement. I am getting a few errors right now such as null pointer exceptions and rather than spent a long time trying to fix them, I wanted to get an idea on whether the layout of the project was right to begin with.
Edit: Adding code - which generates a null pointer exception
This is my AbstractVehicle class:
public AbstractVehicle (IBehaviour behaviourIn) {
behaviour = behaviourIn;
}
public void setBehaviour(IBehaviour ib) {
behaviour = ib;
}
public IBehaviour getBehaviour() {
return behaviour;
}
public void move() {
behaviour.ensureCorrectBehaviour();
}
The car subclass:
public Car () {
super(new StandardBehaviour());
}
The IBehaviour interface:
public interface IBehaviour {
public void ensureCorrectBehaviour();
}
The LandBehaviour abstract class:
public void ensureCorrectBehaviour() {
}
public ILandBehaviour () {
}
private ILandBehaviour landBehaviour;
public ILandBehaviour (ILandBehaviour landBehaviour) {
this.landBehaviour = landBehaviour;
}
public ILandBehaviour getBehaviour() {
return landBehaviour;
}
public abstract void addBehaviour(ILandBehaviour behaviour);
public abstract void removeBehaviour(ILandBehaviour behaviour);
public abstract ILandBehaviour[] getBehaviours();
An example of a concrete behaviour subclass (RacingBehaviour):
public RacingBehaviour(ILandBehaviour landBehaviour) {
super(landBehaviour);
}
public RacingBehaviour() {}
#Override
public void ensureCorrectBehaviour() {
System.out.println("Vehicle is racing.");
}
public void addBehaviour(ILandBehaviour behaviour) {}
public void removeBehaviour(ILandBehaviour behaviour) {}
public ILandBehaviour[] getBehaviours() {
return null;
}
And finally the LandAssembly class:
public class LandAssembly extends ILandBehaviour {
private List<ILandBehaviour> behaviours;
public LandAssembly(ILandBehaviour landBehaviour) {
super(landBehaviour);
behaviours = new ArrayList<ILandBehaviour>();
}
public LandAssembly() {}
public void addBehaviour(ILandBehaviour behaviour) {
behaviours.add(behaviour);
}
public void removeBehaviour(ILandBehaviour behaviour) {
behaviours.remove(behaviour);
}
public ILandBehaviour[] getBehaviours() {
return behaviours.toArray(new ILandBehaviour[behaviours.size()]);
}
}
I am using this runner:
AbstractVehicle aCar = new Car(120);
aCar.move();
ILandBehaviour snow = new SnowBehaviour();
ILandBehaviour racing = new RacingBehaviour();
ILandBehaviour as = new LandAssembly();
as.addBehaviour(snow);
as.addBehaviour(racing);
Before I implemented the composite, everything was fine. I was able to use the client to create a new car, call its move() method, then change its behaviour, call move() again and see the difference. I'm aware however that I'm now kinda leaving the ensureCorrectBehaviour() method in my implementation of the composite pattern, which is obviously wrong. I'm also aware that after doing this, the "new" part of the Car constructor didn't work - I had to add an empty constructor each behaviour.
I can see glaring problems in the code I've created, I just don't quite see how to fix them.
If you are concerned about the design patterns, a class diagram would be extremely useful. You have many features, and you group those features into higher levels of abstractions (such as snow/land/water/etc.) But your vehicle only takes in one behavior. Does a vehicle need to be able to have multiple features? (Surely it does as you mention).
You might consider having concretely-defined strategies in your class, where each implementation of the strategy can vary.
public abstract class Bird
{
protected BirdCallStrategy callStrat;
protected FlyStrategy flyStrat;
}
public class Duck
{
public Duck()
{
callStrat = new QuackStrategy();
flyStrategy = new FlySouthForWinterStrategy(TimeOfYear);
}
}
public class Chicken
{
public Chicken()
{
callStrat = new CluckStrategy();
flyStrat = new NoFlyStrategy();
}
}
This works well if you have distinct abstractions for your strategies. In this case Flying and BirdCalling have nothing to do with each other, but they are allowed to vary by implementation at runtime (Quacking, chirping or flying, not flying, etc.)
If however, you want to create varying instances on the fly without subtyping, you might want to look into the Decorator pattern. The decorator pattern allows you to apply any combination of "features" to an instance at run-time.
So you might end up with an object that is instantiated such as:
Window decoratedWindow = new HorizontalScrollBarDecorator (
new VerticalScrollBarDecorator(new SimpleWindow()));

Is this bad OO programming? Passing this down through methods

Ok, assume I have a class, X and X is something which has an aggregate relationship with other objects. Lets pretend X is a soccer stadium.
X is full of class spectators. However, the behaviour of each spectator for a particular activity differs. Instead of IF statements, I want the different behaviour to be within the spectator class, so that I can use dynamic binding.
However, the problem is that the behaviour the spectator performs affects the "soccer stadium" class. So I was thinking of passing "this" from the soccer stadium class, through a method, to the Spectator class, so that the spectator class can do something to the Soccer Stadium class?
public class SoccerStadium{
SpecatorInterface s = new Spectator();
public void SpectatorBehaviour(){
s.doSomething(this);
}
public void doSomethingthingBySpecator(){
}
}
public class Spectator implements SpecatorInterface{
public void doSomething(SoccerStadium s){
s.doSomethingthingBySpecator();
}
}
I only want to do this so that I can use dynamic binding and alter the behaviour in Specator.doSomething() so that I can have lots of different types of SpectatorSuperClass as an attribute passed to SoccerStadium and then have the different behaviour.
EDIT: What if I passed the reference of the Stadium to the Specator through the Spectator constructor, instead of passing this?
This isn't so much "bad oo programming" as it is tightly coupled. There's nothing inherently wrong with passing around this pointers, but it can become a mess very very quickly. We can't really say more without more information.
I see no problem with the usage of this as a parameter. Nevertheless, I don't like the new Spectator() call that was hard coded in your SoccerStadium class. I believe you should have a Factory with a createSpectator method that could receive a parameter indicating which type of spectator you intend to create.
To me, this kind of two-way circular relationship is bad news. What if Spectators want to go to the Theatre instead?
I'd decouple the relationship by making the Stadium a subscriber to Spectator dispatched events.
public class SoccerStadium
{
ISpectator s = new Spectator();
public SoccerStadium()
{
s.DidSomething+=DoSomethingthingBySpecator;
}
public void SpectatorBehaviour()
{
s.DoSomething();
}
public void DoSomethingthingBySpecator(object sender,EventArgs e)
{
Console.WriteLine("spectator did something");
}
}
public interface ISpectator
{
event EventHandler DidSomething;
void DoSomething();
}
public class Spectator:ISpectator
{
public event EventHandler DidSomething;
public void DoSomething()
{
var ev=DidSomething;
if(ev!=null)
{
ev(this,EventArgs.Empty);
}
}
}
...and so the Spectator now has a means of communicating to anything that's interested, but doesn't need to know a thing about it.
As people have said, there's absolutely nothing wrong tight tight coupling and what you are doing. However, if you want a little bit of decoupling, use the classic visitor pattern.
public interface SpectatorVisitor {
...
void visit(Spectator spectator);
}
public class Spectator {
...
public void accept(SpectatorVisitor visitor) {
visitor.visit(this);
}
}
public class Stadium {
...
spectator.accept(new StadiumSpectatorVisitor());
}
The visit method signature could be altered to accept some kind of state object as well if you need to. Otherwise you could simply define the relevant methods on the Spectator class, and make the visitor collect up the information needed to alter the stadium.
For instance:
public class Spectator {
private Team supports;
public Team getSupports() {
return supports;
}
public void accept(SpectatorVisitor visitor) {
visitor.visit(this);
}
}
public class SupportedTeamVisitor {
private Map<Team, AtomicLong> supportCount = new HashMap<Team, AtomicLong>();
public void visit(Spectator spectator) {
Team supports = spectator.getSupports();
if (! supportCount.contains(supports)) {
supportCount.put(team, new AtomicLong(0));
}
supports.get(team).incrementAndGet();
}
public Map<Team, AtomicLong> getSupportCount() {
return supportCount;
}
}
public class Stadium {
public long getSupportCount(Team team) {
SupportTeamVisitor visitor = new SupportedTeamVisitor();
for (Spectator spectator : spectators) {
spectator.accept(visitor);
}
AtomicLong count = visitor.getSupportCount().get(team);
return (count == null) ? 0 : count.get();
}
}
Make sense?
Your implementation is absolutely fine, I have seen that kind of thing before. Yes you can hold on to the Stadium reference, by passing it through the Spectator constructor, that would probably be cleaner than sending through the reference every time you need it.
However, I don't like it very much; I prefer inner classes. It's not completely clear what you're trying to do, but something like this is possible:
public class Outer {
private int someVariable=0;
public void someMethod(){
ExtendsInner ei = new ExtendsInner();
ei.innerMethod();
System.out.println(someVariable);
}
private void anotherMethod(){
someVariable++;
}
public abstract class Inner {
public abstract void innerMethod();
}
public class ExtendsInner extends Inner{
public void innerMethod(){
anotherMethod();
someVariable++;
}
}
public static void main(String[] args){
Outer o = new Outer();
o.someMethod();
}
}
Unfortunately, you would then have to have all of your "spectator" classes inside your other class, which could lead to one really long file, and thus, ugly code.
However, I think you should definitely avoid doing both things, as it will most definitely make your code overly complicated.
As Matt said, what you are describing is the visitor pattern. Nevertheless, I don't think that's your best alternative (As Falmarri said, that kind of design tends to be tightly coupled, and you end up putting to much logic in your business object, breaking SoC, SRP, etc..).
The fact that the behavior of each spectator for a particular activity differs, doesn't mean that the logic should be included (nor pass) through the spectator class. There are a lot of different ways to avoid those IF statements. I'd suggest you go with something like this link suggest which is far more powerfull than the if statements, visitor pattern, or all the other alternatives, and it's really easy to implement it in another class, and maintain all those goods OOP principles (which are there for a reason).

What is the Best Way to Extend Functionality?

I've run into a situation in which I was to extend the functionality of a given class, but I'm not sure of the best way to go about this. I started by invoking functionality "upwards" and have now switched to "downwards", but I see issues with both. Let me explain what I mean. First, the "upwards" approach:
public class ParentValidator
{
public void validate() {
// Some code
}
}
public class ChildValidator extends ParentValidator
{
#Override
public void validate() {
super.validate();
// Some code
}
}
public class GrandchildValidator extends ChildValidator
{
#Override
public void validate() {
super.validate();
// Some code
}
}
This functions perfectly well, but it requires that I always remember to place super.validate() in my method body or the logic in the parent class(es) won't be executed. In addition, extension in this manner can be considered "unsafe" due to the fact that a child class could actually replace/modify the code defined in the parent class. This is what I call invoking methods "upwards" because I'm invoking methods from higher level classes as I go.
To counter these shortfalls, I decided to make ParentValidator.validate() final and have it invoke a different method. Here's what my code was modified to:
public class ParentValidator
{
public final void validate() {
// Some code
subValidate();
}
protected void subValidate() {}
}
public class ChildValidator extends ParentValidator
{
#Override
public final void subValidate() {
// Some code
subSubValidate();
}
protected void subSubValidate() {}
}
public class GrandchildValidator extends ChildValidator
{
#Override
public void subSubBalidate() {
// Some code
subSubSubValidate();
}
protected void subSubSubValidate();
}
This is what I was referring to when I say that I'm calling downwards as each class invokes methods on classes "down" the inheritance chain.
Using this approach, I can be guaranteed that the logic in the parent class(es) will be executed, which I like. However, it doesn't scale well. The more layers of inheritance I have, the uglier it gets. At one level, I think this is very elegant. At two levels, it starts to look shoddy. At three or more, it's hideous.
In addition, just as I had to remember to invoke super.validate() as the first line of any of my children's validate methods, I now have to remember to invoke some "subValidate" method at the end of any of my parent's validate methods, so that didn't seem to get any better.
Is there a better way to do this type of extension that I haven't even touched on. Either of these approaches have some serious flaws and I'm wondering if there's a better design pattern I could be using.
In what you describe as your first approach you are using simple inheritance, your second approach is closer to what the Gang of Four [GoF] called a Template Method Pattern because your parent class is using the so-called Hollywood Principle: "don't call us, we'll call you".
However, you could benefit from declaring the subvalidate() method as abstract in the parent class, and by this, make sure all subclasses are forced to implement it. Then it would be a true template method.
public abstract class ParentValidator
{
public final void validate() {
//some code
subValidate();
}
protected abstract void subValidate() {}
}
Depending on what you are doing there are other patterns that could help you do this in a different manner. For instance, you could use a Strategy Pattern to peform the validations, and by this favoring composition over inheritance, as suggested before, but a consequence is that you will need more validation classes.
public abstract class ParentValidator
{
private final ValidatorStrategy validator;
protected ParentValidator(ValidatorStrategy validator){
this.validator = validator;
}
public final void validate() {
//some code
this.validator.validate();
}
}
Then you can provide specific validation strategies for every type of Validator that you have.
If you want to get the best of both worlds you might considering implementing the solution as a Decorator Pattern where subclasses can extend the functionality of a parent class and still stick to a common interface.
public abstract class ValidatorDecorator implements Validator
{
private final Validator validator;
protected ParentValidator(Validator validator){
this.validator = validator;
}
public final void validate() {
//some code
super.validate(); //still forced to invoke super
this.validator.validate();
}
}
All patterns have consequences and advantages and disadvantages that you must consider carefully.
I'd prefer to 1) program against interfaces, and 2) opt for composition over inheritance. This is how I have done. Some people like it, some do not. It works.
// java pseudocode below, you'll need to work the wrinkles out
/**
* Defines a rule or set of rules under which a instance of T
* is deemed valid or invalid
**/
public interface ValidationRule<T>
{
/**
* #return String describing invalidation condition, or null
* (indicating then that parameter t is valid */
**/
String apply(final T t);
}
/**
* Utility class for enforcing a logical conjunction
* of zero or more validatoin rules on an object.
**/
public final class ValidatorEvaluator
{
/**
* evaluates zero or more validation rules (as a logical
* 'AND') on an instance of type T.
**/
static <T> String apply(final T t, ValidationRule<T> ... rules)
{
for(final ValidationRules<T> v : rules)
{
String msg = v.apply(t);
if( msg != null )
{
return msg; // t is not valid
}
}
return null;
}
}
// arbitrary dummy class that we will test for
// i being a positive number greater than zero
public class MyFoo
{
int i;
public MyFoo(int n){ i = n; }
///
}
public class NonZeroValidatorRule implements ValidatorRule<MyFoo>
{
public String apply(final MyFoo foo)
{
return foo.i == 0 ? "foo.i is zero!" : null;
}
}
// test for being positive using NonZeroValidatorRule and an anonymous
// validator that tests for negatives
String msg = ValidatorEvaluator.apply( new MyFoo(1),
new NonZeroValidatorRule(),
new ValidatorRule<MyFoo>()
{
public String apply(final MyFoo foo)
{
return foo.i < 0 ? "foo.i is negative!" : null;
}
}
);
if( msg == null )
{
\\ yay!
...
}
else
{
\\ nay...
someLogThingie.log("error: myFoo now workie. reason=" + msg );
}
More complex, non-trivial evaluation rules can be implemented this way.
The key here is that you should not use inheritance unless there exists a is-a relationship. Do not use it just to recycle or encapsulate logic. If you still feel you need to use inheritance, then don't go overkill trying to make sure that every subclass executes the validation logic inherited from the superclass. Have implementations of each subclass do an explicit execution on super:
public class ParentValidator
{
public void validate() { // notice that I removed the final you originally had
// Some code
}
}
pubic class ChildValidator extends ParentValidator
{
#Override
public void validate() {
// Some code
super.validate(); // explicit call to inherited validate
// more validation code
}
}
Keep things simple, and don't try to make it impossible or fool-proof. There is a difference between coding defensively (a good practice) and coding against stupid (a futile effort.) Simply lay out coding rules on how to subclass your validators. That is, put the onus on the implementors. If they cannot follow the guidelines, no amount of defensive coding will protect your system against their stupidity. Ergo, keep things clear and simple.
I prefer to using composition over inheritance if your subSubSubValidate is related general functionality. You can extract new class and move it there than you can use it without inheritance in the other classes.
There is also
"Favor 'object composition' over
'class inheritance'." (Gang of Four
1995:20)
maybe a look at the visitor pattern may help you to develop your pattern.
Here are some information on it : http://en.wikipedia.org/wiki/Visitor_pattern

Categories

Resources