I'm designing an API that receives several event types all inheriting from a common base class. So lets say EventA and EventB inherit from BaseEvent
These events need to go trough several different processors.
So I though the visitor pattern would be a good choice here.
So the BaseEvent would look something like this:
public class BaseEvent implements Visitable {
void visit(Visitor visitor) {
visitor.visit(this);
}
}
So now I have an API that includes the Visitable and the Visitor types, but they are not really related to the API.
the processing is only done on the receiving side.
So I though about defining the API types without the Visitor interfaces and to define new types that include the visitors on the receiver of the events
But then I have to translate the API types to the new types and I don't see a way to do it without using instanseof for every event type
Does anyone see a solution for this?
Or maybe some other design that can solve the problem?
Thanks
Edit (Adding Some more info):
The events just hold information and on the receiver side they need to go through the processors.
I currently have 3 types of events (but that is likely to grow),
and 2 processors (this can also change but less likely)
I wanted to use the visitor pattern cause it forces me to add new methods to the processors when new events are added
If I just override the process() method for each type I will only catch errors in runtime when new events are added
I'm not sure what your use-case or architecture looks like, but I had a similar issue I think, with a trade routing system. There were events defined for routing a trade, getting acknowledgements, getting executions, etc. Events were only dumb objects, and there were processors with lots of if statements with instanceofs.
We decided to redesign the whole thing using "real" objects instead of events and processors. This means the "events" are no longer just holders of information, but they can "process themselves". Since they (at least in our use-case) had all the necessary information, they can actually process themselves better than one or multiple "external" processors.
There were multiple curious sideffects:
Dependencies became much clearer and easier.
We got rid of most of getters/setters, because asking an object for all of its information became unnecessary. This I found pretty cool.
So basically instead of a "bean" like this:
public class LimitOrderExecution ... {
private int executedAmount;
private int remainingAmount;
private BigDecimal executionPrice;
private Order order;
...more fields...
... setter / getter for everything ...
}
We now have:
public class LimitOrderExecution ... {
...fields...
public void apply() {
...applies itself using other objects...
}
}
There are several options:
instanceof
instanceof may not be that bad. Neither in regards of performance, nor from a coding-style POV. So why even use some workaround, if you don't need to?
Method overriding
Simply override the method for each Event that needs to be processed separately:
class EventReceiver{
void eventReceived(BaseEvent e){
}
void eventReceived(EventA e){
}
...
}
Same could of course be done for your visitor-pattern. Though the visitor-pattern would be rather superfluous here.
Another event-structure
If you don't want to distinguish your events by type, just add a variable that allows identification of the event without instanceof. Though that'd just be a workaround to the instanceof operator.
Related
I have been told at some stage at university (and have subsequently read in upteen places) that using instanceof should only be used as a 'last resort'. With this in mind, is anyone able to tell be if the following code I have is a last resort. I have had a look around on stack overflow but cannot quite find a similar scenario - perhaps I have missed it?
private void allocateUITweenManager() {
for(GameObject go:mGameObjects){
if (go instanceof GameGroup) ((GameGroup) go).setUITweenManager(mUITweenManager);
}
}
where
mGameObjects is an array, only some of which are GameGroup type
GameGroup is a subclass of abstract class GameObject.
GameGroup uses interface UITweenable which has method setUITweenManager()
GameObject does not use interface UITweenable
I suppose I could equally (and probably should) replace GameGroup in my code above with UITweenable - I would be asking the same question.
Is there another way of doing this that avoids the instanceof? This code cannot fail, as such (I think, right?), but given the bad press instanceof seems to get, have I committed some cardinal sin of OOP somewhere along the line that has me using instanceof here?
Thanks in advance!
I learned about Visitor pattern in Compiler class at university, I think it might apply in your scenario. Consider code below:
public class GameObjectVisitor {
public boolean visit(GameObject1 obj1) { return true; }
.
.
// one method for each game object
public boolean visit(GameGroup obj1) { return true; }
}
And then you can put a method in GameObject interface like this:
public interface GameObject {
.
.
public boolean visit(GameObjectVisitor visitor);
}
And then each GameObject implements this method:
public class GameGroup implements GameObject {
.
.
.
public boolean visit(GameObjectVisitor visitor) {
visitor.visit(this);
}
}
This is specially useful when you've complex inheritance hierarchy of GameObject. For your case your method will look like this:
private void allocateUITweenManager() {
GameObjectVisitor gameGroupVisitor = new GameObjectVisitor() {
public boolean visit(GameGroup obj1) {
obj1.setUITweenManager(mUITweenManager);
}
};
for(GameObject go:mGameObjects){
go.visit(gameGroupVisitor);
}
}
EDIT
There are two primary things you can do here to relieve yourself of this specific instance of instanceof. (pun?)
Do as my initial answer suggested and move the method you are targeting up to the class you are iterating. This isn't ideal in this case, because the method doesn't make sense to the parent object, and would be polluting as Ted has put it.
Shrink the scope of the objects you are iterating to just the objects that are familiar with the target method. I think this is the more ideal approach, but may not be workable in the current form of your code.
Personally, I avoid instanceof like the plague, because it makes me feel like I completely missed something, but there are times where it is necessary. If your code is laid out this way, and you have no way to shrink the scope of the objects you are iterating, then instanceof will probably work just fine. But this looks like a good opportunity to see how polymorphism can make your code easier to read and maintain in the future.
I am leaving the original answer below to maintain the integrity of the comments.
/EDIT
Personally, I don't think this is a good reason to use instanceof. It seems to me that you could utilize some polymorphism to accomplish your goal.
Have you considered making setUITweenManager(...) a method of GameObject? Does it make sense to do this?
If it does make sense, you could have your default implementation do nothing, and have your GameGroup override the method to do what you want it to do. At this point, your code could just look like this then:
private void allocateUITweenManager() {
for(GameObject go:mGameObjects){
go.setUITweenManager(mUITweenManager);
}
}
This is polymorphism in action, but I am not sure it would be the best approach for your current situation. It would make more sense to iterate the Collection of UITweenable objects instead if possible.
The reason why instanceof is discouraged is because in OOP we should not examine object's types from outside. Instead, the idiomatic way is to let object themselves act using overriden methods. In your case, one possible solution could be to define boolean setUITweenManager(...) on GameObject and let it return true if setting the manager was possible for a particular object. However if this pattern occurs in many places, the top-level classes can get quite polluted. Therefore sometimes instanceof is "lesser evil".
The problem with this OPP approach is that each object must "know" all its possible use cases. If you need a new feature that works on your class hierarchy, you have to add it to the classes themselves, you can't have it somewhere separate, like in a different module. This can be solved in a general way using the visitor pattern, as others suggested. The visitor pattern describes the most general way to examine objects, and becomes even more useful when combined with polymorphism.
Note that other languages (in particular functional languages) use a different principle. Instead of letting objects "know" how they perform every possible action, they declare data types that have no methods on their own. Instead, code that uses them examines how they were constructed using pattern matching on algebraic data types. As far as I know, the closest language to Java that has pattern matching is Scala. There is an interesting paper about how Scala implements pattern matching, which compares several possible approaches: Matching Objects With Patterns. Burak Emir, Martin Odersky, and John Williams.
Data in object-oriented programming is organized in a hierarchy of classes. The problem of object-oriented pattern matching is how to explore this hierarchy from the outside. This usually involves classifying objects by their run-time type, accessing their members, or determining some other characteristic of a group of objects. In this paper we compare six different pattern matching techniques: object-oriented decomposition, visitors, type-tests/typecasts, typecase, case classes, and extractors. The techniques are compared on nine criteria related to conciseness, maintainability and performance. The paper introduces case classes and extractors as two new pattern-matching methods and shows that their combination works well for all of the established criteria.
In summary: In OOP you can easily modify data types (like add subclasses), but adding new functions (methods) requires making changes to many classes. With ADT it's easy to add new functions, but modifying data types requires modifying many functions.
The problem with instanceof is that you can suffer from future object hierarchy changes. The better approach is to use Strategy Pattern for the cases where you are likely to use instanceof. Making a solution with instanceof you are falling into a problem Strategy is trying to solve: to many ifs. Some guys have founded a community. Anti-IF Campaign could be a joke but untipattern is serious. In a long term projects maintaining 10-20 levels of if-else-if could be a pain. In your case you'd better make a common interface for all objects of your array and implement setUITweenManager for all of them through an interface.
interface TweenManagerAware{
setUITweenManager(UITweenManager manager);
}
It is always a bit "fishy" to me to mix objects of different classes in the same Collection. Would it be possible / make sense to split the single Collection of GameObjects into multiple Collections, one of mere GameObjects, another of UITweenables? (e.g. use a MultiMap keyed by a Class). Then you could go something like:
for (UITweenable uit : myMap.get(UITweenable.class)) {
uit.setUITweenManager(mUITweenManager);
}
Now, you still need an instanceof when you insert into the map, but it's better encapsulated - hidden from the client code who doesn't need to know those details
p.s. I'm not a fanatic about all the SW "rules", but Google "Liskov Substitution Principle".
You could declare setUITweenManager in GameObject with an implementation that does nothing.
You could create an method that returns an iterator for all UITweenable instances in array of GameObject instances.
And there are other approaches that effectively hide the dispatching within some abstraction; e.g. the Visitor or Adapter patterns.
... have I committed some cardinal sin of OOP somewhere along the line that has me using instanceof here?
Not really (IMO).
The worst problem with instanceof is when you start using it to test for implementation classes. And the reason that is particularly bad is that it makes it hard to add extra classes, etcetera. Here the instanceof UITweenable stuff doesn't seem to introduce that problem, because UITweenable seems to be more fundamental to the design.
When you make these sorts of judgement, it is best to understand the reasons why the (supposedly) bad construct or usage is claimed to be bad. Then you look at you specific use-case and make up whether these reasons apply, and whether the alternatively you are looking at is really better in your use-case.
You could use the mGameObjects container for when you need to do something on all game objects and keep a separate container only for GameGroup objects.
This will use some more memory, and when you add/remove objects you have to update both containers, but it shouldn't be a noticeable overhead, and it lets you loop very efficiently through all the objects.
The problem with this approach is that it doesn't usually appear at one place only in your code and thus makes it more or less painful to add another implementations of the interface in the future. Whether to avoid it depends on your consideration. Sometimes YAGNI can be applied an this is the most straightforward way.
Alternatives had been suggested by others, for example the Visitor pattern.
I have another suggestion of a way to avoid instanceof.
Unless you are using a generic factory, at the moment when you create a GameObject you know what concrete type it is. So what you can do is pass any GameGroups you create an observable object, and allow them to add listeners to it. It would work like this:
public class Game {
private void makeAGameGroup() {
mGameObjects.add(new GameGroup(mUITweenManagerInformer));
}
private void allocateUITweenManager() {
mUITweenManagerInformer.fire(mUITweenManager);
}
private class OurUITweenManagerInformer extends UITweenManagerInformer {
private ArrayList<UITweenManagerListener> listeners;
public void addUITweenManagerListener(UITweenManagerListener l) {
listeners.add(l);
}
public void fire(UITweenManager next) {
for (UITweenManagerListener l : listeners)
l.changed(next);
}
}
private OurUITweenManagerInformer mUITweenManagerInformer = new OurUITweenManagerInformer();
}
public interface UITweenManagerInformer {
public void addUITweenManagerListener(UITweenManagerListener l);
}
public interface UITweenManagerListener {
public void changed(UITweenManager next);
}
What draws me to this solution is:
Because a UITweenManagerInformer is a constructor parameter to GameGoup, you cannot forget to pass it one, whereas with an instance method you might forget to call it.
It makes intuitive sense to me that information that an object needs (like the way a GameGroup needs knowledge of the current UITweenManager) should be passed as a constructor parameter -- I like to think of these as prerequisites for an object existing. If you don't have knowledge of the current UITweenManager, you shouldn't create a GameGroup, and this solution enforces that.
instanceof is never used.
I'm looking for a clean design to emulate Visitor functionality without the many drawbacks it has.
In Java, the traditional implementations (as the described in GoF) resort to double dispatch to get rid of if-elses. To solve this, I've seen some implementations that use reflection to avoid modifications on the "Visitable" classes, but these rely on hardcoded strings when looking for method names. Although quite useful, I still think that they are not clean design.
Is it possible to emulate the same idea using data structures and/or good OO-design? It doesn't have to be a pattern, just I'm looking for examples where a similar problem is solved (e.g.: using a Map<Class<T>,SomeFunctionObject>).
UPDATE Something like this:
public abstract class BaseVisitor<T> {
private final TypesafeHeterogeneusMap map;
protected BaseVisitor(){
map = inflateFunctions();
}
public <E extends T> void process(E element){
if(element == null){
throw new NullPointerException();
}
boolean processed = false;
#SuppressWarnings("unchecked")
Class<? super T> sc = (Class<? super T>) element.getClass();
while(true){
if(sc != null){
FunctionObject<? super T> fo2 = map.get(sc);
if(fo2 != null){
fo2.process(element);
processed = true;
break;
}
sc = sc.getSuperclass();
} else {
break;
}
}
if(!processed) System.out.println("Unknown type: " + element.getClass().getName());
}
abstract TypesafeHeterogeneusMap inflateFunctions();
}
Actually is a mix of Template pattern and Command pattern, I think. Feel free to post your suggestions on how to enhance it.
You could just make all your Visitor implementations extend a base class, which provides a default implementation for every type of Visitable:
public interface AnimalVisitor {
void visitHorse(Horse horse);
void visitDog(Dog dog);
}
public class BaseAnimalVisitor implements AnimalVisitor {
public void visitHorse(Horse horse) {
// do nothing by default
}
public void visitDog(Dog dog) {
// do nothing by default
}
}
Then, when a new class Cat is introduced, you add the visitCat(Cat cat) method to the interface and the base class, and all the visitors are left unchanged and still compile. If they don't want to ignore cats, then you override the visitCat method.
Although it's not the answer you're looking for: Consider using a higher-level, less verbose language than Java. You will find that things like the Visitor pattern start to seem irrelevant. Of course, if you want to define logic for traversing a data structure in one place, and define what to do with the elements of the data structure (based on their types) somewhere else, and make it possible to mix-and-match traversal/processing strategies, you can do that. But you can do it using just a small amount of straightforward code, nothing that you would think of calling a "pattern".
I came from a C/Java programming background and started learning various dynamic languages a few years ago. It was mind-blowing to realize how much you can do in a few lines of code.
For example, if I was to emulate the Visitor pattern in Ruby:
module Enumerable
def accept_visitor(visitor)
each do |elem|
method = "visit#{elem.class}".to_sym
elem.send(method,elem) if elem.respond_to? method
end
end
end
To explain: in Ruby, an Enumerable represents anything which can be iterated over. In those 8 lines of code, I have made every kind of object which can be iterated over accept Visitors. Whether I plan to have 5, 10, or 100 different classes accept Visitors, those 8 lines are all that are needed.
Here's a sample Visitor:
class CatCounter
attr_reader :count
def initialize; #count = 0; end
def visitCat; #count += 1; end
end
Note that the Visitor doesn't have to define methods for all the different types of Visitables. Each Visitor just has to define methods for the types of Visitables it is interested in; it can ignore the rest. (Which means you don't have to modify a bunch of existing code if you add a new type of Visitable.) And any Visitor can interoperate with any object which accepts Visitors.
Just in those few lines of code, all the problems you mentioned with the Visitor pattern have been overcome.
Don't get me wrong; Java is a great language for some things. But you need to choose the right tool for the job. The fact that you are fighting so much to overcome the limitations of your tool might indicate that in this case, a different tool is called for.
#MisterSmith, since you have to use Java, and presumably you do have good reasons for using Visitor, I am going to propose another possible solution.
Let's separate our minds from the way Visitor is usually implemented and go back to the reason why people use Visitors in the first place. Although I mentioned it already in my other answer, the point of Visitor is to make it possible to mix-and-match traversal and processing logic.
"Traversal logic" could mean logic for traversing different types of data structures, or traversing the same data structure in a different order. Or it could even include traversal strategies which apply certain filters to the elements returned, etc.
Implicit in Visitor is the idea that the processing we apply to each element is going to depend on its class. If what we do to each element doesn't depend on its class, there is no reason to use Visitor. Unless we want to do a "switch" on element class, we need to use virtual method calls to do this (which is why the usual Java implementation uses double dispatch).
I propose that we can split the Visitor pattern into 3 rather than 2 parts:
An Iterator object which implements a certain traversal
An object which implements the strategy of "deciding what to do with an element based on its class" (the part which normally requires double dispatch). Using reflection, we can make a general-purpose class which does this. A simple implementation would use a Map, or you could make something which generates bytecode dynamically (I forget the platform method in Java which lets you load raw bytecodes as a new Class, but there is one). OR! OR, you could use a dynamic, JVM-hosted language like JRuby or Clojure to write #2, compile to bytecode, and use the resulting .class file. (This file would probably use the invokedynamic bytecode, which as far as I know, is not accessible from Java -- the Java compiler never emits it. If this has changed, please edit this post.)
The Visitors themselves. In this implementation, Visitors won't have to subclass from a common superclass, nor will they have to implement methods for elements they're not interested in.
Keeping the traversal in a general-purpose Iterator allows you to do other things with it (not just accepting Visitors).
There are a couple ways the 3 pieces could be tied together; I'm thinking #2 will wrap #3 (taking it as a constructor argument). #2 will provide a public method which takes an Iterator as an argument, and applies the Visitor to it.
The interesting part is #2. I may edit this post later to add a sample implementation; right now I have some other things to do. If someone else comes up with an implementation, please add it here.
I am trying to understand where good contracts end and paranoia starts.
Really, I just have no idea what good developer should care about and what shall he leave out :)
Let's say I have a class that holds value(s), like java.lang.Integer. Its instances are aggregated by other objects (MappedObjects), (one-to-many or many-to-many), and often used inside MappedObjects' methods. For performance reasons, I also track these relationships in TreeMap (guava MultiMap, doesn't matter) in addition, to be able to get fast iterations over MappedObjects bound to some range of Integer keys.
So, to keep system in consistent state, I should modify MappedObject.bind(Integer integer) method to update my Map like:
class MappedObject {
public void bind (Integer integer) {
MegaMap.getInstance().remove(fInteger, this);
fInteger = integer;
MegaMap.getInstance().add(fInteger, this);
}
...
private Integer fInteger;
}
I could just make abstract MappedObject class with this final method, forcing other to inherit from it, but it is rude. If I will define MappedObject as interface with method bind() and provide skeletal implementation -- other developer might later just forget to include it in object and implement method by himself without Map updating.
Yes, you should force people to do the right thing with your code. A great example of letting people do the wrong thing is the servlet method init( ServletConfig config ) that expected you would store the servlet config yourself but, obviously, a lot of people forgot to store the config and when running their servlets just failed to work.
When defining APIs, you should always follow the open-closed principle, your class should be open for extension and closed for modification. If your class has to work like this, you should only open extension points where they make sense, all the other functionality should not be available for modification, as it could lead to implementation issues in the future.
Try to focus on functionality first and leave all unnecessary things behind. Btw you can't prohibit reflection so don't worry too much on misuse. On the other hand your API should be clear and straightforward so users will have clear idea, what they should and what they shouldn't do with it.
I'd say your classes should be designed for as simple use as possible.
If you allow a developer to override methods you definitely should document the contract as good as possible. In that case the developer opts to override some basic functionality and thus is responsible to provide an implementation that adheres to the contract.
In cases where you don't want the developer to override parts of the functionality - for security reasons, if there is no sensible alternative etc. - just make that part final. In your case, the bind method might look like this:
class MappedObject {
public final void bind (Integer integer) {
MegaMap.getInstance().remove(fInteger);
internalBind( integer );
MegaMap.getInstance().add(fInteger);
}
protected void internalBind( Integer integer ) {
fInteger = integer;
}
...
private Integer fInteger;
}
Here you'd allow the developer to override the internalBind() method but ensure that bind() will do the mapping.
To summarize: Make using and extending classes as easy as (sensibly) possible and don't have the developer to copy lots of boiler plate code (like the map updates in your case) in case he just wants to override some basic functionality (like the actual binding).
At least you should do really everything that prevents bugs but cost no effort.
For example: use primitive types (int) instead of wrappers (Integer) if the variable is not allowed to be null.
So in your bind method. If you not have intended to bind null, then use int instead of Integer as parameter type.
If you think your API users are stupid, you should prohibit wrong usage. Otherwise you should not stand in their way to do things they need to do.
Domumentation and good naming of classes and methods should indicate how to use your API.
Hallo,
I have a little design decision today: There is an existing interface, called 'TargetSystem' which only have one method 'getName()'. There are no other common information about these target systems.
Now I have a new kind of target systems that need authentication.
I have to know whether a target system needs authentication or not (the frontend have to show a password dialog for those). If it needs authentication, I have to set the username and password.
My design decision: Should I extend the existing interface with methods 'needsAuthentication' and 'setUsernameAndPassword' or creating a new interface extending the old one with only the method 'setUsernameAndPassword', getting the authentication need by instanceof.
Important: There is no need to be downwards compatible or any other reason not to touch the old interface! I just discussing with a co-worker, which way is generally the nice one: creating interfaces with names like 'ObjectWithFeatureX', 'ObjectWithFeatureY' or creating methods like 'hasFeatureX', 'hasFeatureY'.
I don't really agree with with Peter. Sometimes, the instanceof can even play a central role in the design.
Personnaly, I love the following pattern (flameproof suit: "on"):
interface Authentifiable {
void authentify(...)
}
interface Stateful {
void saveState(...)
void loadState(...)
}
interface MyOtherAspect {
...
}
And then, in the code:
void someCode()
{
for (Server s : servers)
{
if (s instanceof Authentifiable)
((Authentifiable) s).authentify(...)
if (s instanceof Stateful)
((Stateful) s).load(...)
...
}
for (GridSystem gs : grids)
{
if (gs instanceof Authentifiable)
((Authentifiable) gs).authentify(...)
if (gs instanceof Stateful)
((Stateful) gs).load(...)
...
}
}
This enables you to have completely orthogonal "aspects" working on any object. You can have object implementing feature A & B, others B & C and others A & C. ...or any combination of any features.
If you have many such features, this comes in particularly handy. Making one big interface for all of them where implementing objects just handle all these features with empty stubs might be ugly.
Plus, here, you can check whether a particular object has a particular feature, which you can use directly, for example to split a list of objects into two bunches, one with feature X and the other without, in order to process them differently.
The parts of the system operating on these features simply need to check if the object has properties A, B or C by checking with instanceof. This is scalable, backward compatible and easy.
That said, it is a very specific way for handling things and not necessarily suited for general purpose stuff. It is especially suited if you have a lot of orthogonal features applying on several distinct objects.
Ask a question yourself: AuthenticationSystem is-a TargetSystem?
A solution without downcast:
interface TargetSystem{
//Each TargetSystem needs a sort of authentication anyway
boolean authentication(AuthenticationContext context);
...
}
class NormalTargetSystem implements TargetSystem{
boolean authentication(AuthenticationContext context){
//dummy authentication
return true;
}
...
}
class AuthenticationTargetSystem implements TargetSystem{
boolean authentication(AuthenticationContext context){
//real authentication
}
...
}
In general, if you have a a good design you don't need instanceof.
IMHO: instanecof should only be used for classes/interfaces you cannot change.
Can you have just setUsernameAndPassword() and the implementations which don't need it just ignore it? A more common approach would be to have setUsername() and setPassword() (however I prefer the all in one method approach as it doesn't make much sense to change just one)
creating interfaces with names like 'ObjectWithFeatureX', 'ObjectWithFeatureY' or creating methods like 'hasFeatureX', 'hasFeatureY'.
I would say neither. ;) Where ever possible the caller should not have code like
if(a instanceof NeedsUsername) {
((NeedsUsername) a).setUsername(username);
}
or
if(a.needUsername()) {
a.setUsername(username);
}
it should just have
a.setUsername(username);
EDIT: You need some sort of listener for events such as failed passwords. You could have a listener like
public interface AuthenticationListener {
public void firstUsernamePassword();
public void failedAuthentication(String reason);
}
which way is generally the nice one: creating interfaces with names like 'ObjectWithFeatureX', 'ObjectWithFeatureY' or creating methods like 'hasFeatureX', 'hasFeatureY'.
Another question you might ask yourself is about the future plans. Do you plan to have even more features? If you can see the possibility of one day having ObjectWithFeatureXAndFeatureY, you might wish to consider the Decorator design pattern.
This example of adding multiple features like scrollbars to windows show the good use of decorator pattern. http://en.wikipedia.org/wiki/Decorator_pattern#Motivation
Just be careful not to overdesign if you are sure you will never need this much functionality and can just use simple inheritance.
You can always refactor to a system with no checks, but often this conflicts with a nice tiered approach.
Eg: in your case, if you want to show a login dialog only if the target system requires it, you could have an interface method init() which shows the authentication dialog in one case and does nothing in the other. But then you're mixing gui code in your target system, which is not what you want. You can start hassling aroudn with callbacks and all, but in the end, there's no simple way around it.
So here's one approach I like
public interface Authenticating {
void authenticate(String username, String password);
}
public interface TargetSystem {
String getName();
/**
* #return the authentication interface of this object, or
* null if authentication is not required.
*/
Authenticating getAuthenticationInterface();
}
...
Authenticating auth = targetSystem.getAuthenticationInterface();
if (auth!=null) {
String user = null;
String pass = null;
// show login dialog and get response
auth.authenticate(user, pass);
}
...
This way, you can only call the authenticate method if it is needed. You might need to think of better names though :)
In this case, I would not let one interface extend the other. The target system can implement both interfaces and just return itself, or it could return an anonymous inner class. But that's completely up to its implementor.
What exactly is the point of bound properties? To me they seem to be a less type-safe version of events using EventObjects - it seems a bit weak to be using string equality checking for event.getPropertyName().
Why would you use one over the other?
The whole point of Java Beans is that a system (GUI Builder, in particular) can examine a Java Bean and configure it without any previous knowledge of that component.
Although this is fairly cool, it's really only useful in this specific situation and these days annotations would work MUCH better.
So the reason they use bound properties was simply to support this drop-in GUI component technology, and I wouldn't really prefer it over events unless you need to support a reflective gui-building system.
Response to #Mike rodent
Let's say you allow your user to create a class that you will control. This class has a "Main" and can handle a couple events.
Normally you have your user do something like this:
class UserClass(someClass) {
void mainMethod() {
someClass.addEventListener(new EventListener() {
public void eventsHappen(Event e){
event1(e)
}
}
}
someClass.addDifferentEventListener(new DifferentEventListener() {
public void eventsHappen(DifferentEvent e){
event2(e)
}
}
}
}
public void event1(Event e) {
//java code for event 1
}
public void event2(DifferentEvent e) {
// java code for event 2
}
}
Anyway, you get the idea. Of course, you assume that this class is registered somewhere--probably in an xml/config file. You read it, instantiate it and execute the mainMethod(defined by agreement or by interface) and it registers itself and starts getting calls to the event handlers.
Now here's how you can accomplish the same thing with annotations: (You might recognize the pattern--it's pretty much how Junit annotates tests.)
class UserClass() {
#Event1
void event1Method(Event e) {
event1's code
}
#Event2
void event2Method(AnotherEvent e) {
event2's code
}
}
This is much more straight-froward and removes most of the boilerplate, and it also removes the need for an agreement or interface, annotations are more clearly defined and independant. (You don't actually even NEED the event annotations if you care to inspect the parameters being passed into the methods, but dragons lie in that general direction).
You still need the class registered somewhere, but this time you just scan each method for your event annotations and register them yourself. Since it's only a few lines of code to read and process a class like this, why restrict this pattern to unit testing?
Another thing I found really neat, I used this pattern for Groovy classes that were "plugged-in" to my Java program. Since I was compiling all the classes in a given directory anyway, scanning for annotations was trivial.. The effect to the user is that he drops in (or edits) a properly annotated groovy text file and my code immediately compiles, integrates and starts calling their event handlers.
I think that JavaBeans specification was designed with generic object handling in mind. By example, putting a JavaBean in a IDE and using a visual property editor to configure it. In that case the IDE will use the general PropertyChangeEvent and so on.
Or if you want to copy equal named properties from a bean to another... it's another case of bean use (BeanUtils class).
But, if you plan to do specific things, as Noel Ang says I'd recommend strong-typing.
JavaBeans is a specification. It defines a bound property as that whose modification results in a notification being emitted, and a PropertyChangeEvent is the sanctioned notification entity.
So the putative JavaBeans-spec bean editor is supposed to listen for PropertyChangeEvents. Beyond the need to work with that spec, I wouldn't use it, myself.