Design Question - Class Must Implement Interface
I'm not sure how to describe this in summary, really. I'd say that I sort of want multiple inheritance, but I don't want to be shot. :-P So let me describe the situation:
I have an interface, DataEditingComponent<T>. The idea is that anything implementing the interface is capable of allowing the user to edit an object of type T. For example, a DataEditingComponent<Integer> would allow the user to input an integer. A DataEditingComponent<Map><SomeObj,Integer>> might represent an object capable of editing a table describing the number of instances of SomeObj. You get the idea. DataEditingComponent<T> describes three methods: getEditingData():T, setEditingData(T):void, and getDefaultEditingData():T. I'm assuming you can guess what those do.
Well, the practical application of this interface is in the use of a Swing application. It provides a very clean and standardized way of adjusting the contents of components which edit data. Obviously, a JTextField would work about as well as a DataEditingComponent<String>, but for more complicated components (DataEditingComponent<GameWorldMap>, for instance), the standardized interface is very helpful.
Since in practice everything that ever implements DataEditingComponent<T> extends JComponent, it would be nice to declare this as a requirement somehow. However, given that JComponent is extended into a number of various subclasses, I can't just go making DataEditingComponent<T> an abstract subclass.
So far, the only conclusion I've reached is that I can take each and every JComponent subclass and extend it into an abstract subclass which implements DataEditingComponent<T>... but that's very ugly and quickly leads to other problems. And presently, I'm left casting things from one to the other, with which I am also not happy.
So... any way out of this? Have I done something wrong design-wise? Or am I just stuck in a language limitation?
Thanks for reading!
[2034 byte] By [
tvynra] at [2007-10-3 3:35:18]

> I'm not sure how to describe this in summary, really.
> I'd say that I sort of want multiple inheritance,
> but I don't want to be shot. :-P So let me
> describe the situation:
>
> I have an interface, DataEditingComponent<T>. The
> idea is that anything implementing the interface is
> capable of allowing the user to edit an object of
> type T. For example, a DataEditingComponent<Integer>
> would allow the user to input an integer. A
> DataEditingComponent<Map><SomeObj,Integer>> might
> represent an object capable of editing a table
> describing the number of instances of SomeObj. You
> get the idea. DataEditingComponent<T> describes
> three methods: getEditingData():T,
> setEditingData(T):void, and
> getDefaultEditingData():T. I'm assuming you can
> guess what those do.
>
> Well, the practical application of this interface is
> in the use of a Swing application. It provides a
> very clean and standardized way of adjusting the
> contents of components which edit data. Obviously, a
> JTextField would work about as well as a
> DataEditingComponent<String>, but for more
> complicated components
> (DataEditingComponent<GameWorldMap>, for instance),
> the standardized interface is very helpful.
>
> Since in practice everything that ever implements
> DataEditingComponent<T> extends JComponent, it would
> be nice to declare this as a requirement somehow.
> However, given that JComponent is extended into a
> number of various subclasses, I can't just go making
> DataEditingComponent<T> an abstract subclass.
>
> So far, the only conclusion I've reached is that I
> can take each and every JComponent subclass and
> extend it into an abstract subclass which implements
> DataEditingComponent<T>... but that's very ugly and
> quickly leads to other problems. And presently, I'm
> left casting things from one to the other, with which
> I am also not happy.
>
> So... any way out of this? Have I done something
> wrong design-wise? Or am I just stuck in a language
> limitation?
Hmm. The component is part of the view. The data is part of the model. Putting them together seems to go against the whole Model-View-Controller concept. You may want to have a look at how Swing separates the editing from the rendering from the model for complicated widgets such as JTable. The editors hava methods such as getEditorComponent() which returns the Component used to edit the data. Everywhere you are currently adding DataEditingComponent instances to your GUI, you can instead call a getDataEditingComponent() method, which can require that the returned object is a JComponent.
Niceguy: You have a point that I don't have a very clean MVC separation; I'll have to look into that. Unfortunately, not very much of this application was designed with that kind of separation in mind and I've been unwinding things like that for a while now. :) I appreciate the pointer; you've definitely cleared some things up.
Nonetheless, I don't think that that really fixes the problem. Using a clearer distinction between the model and the view, I'd still want an interface which allowed me access to the data by parameterized type. For example, something like
DataEditingView<T>
getModel():DataEditingModel<T>
DataEditingModel<T>
getEditingData():T
setEditingData(T):void
getDefaultEditingData():T
where things like subclasses of JTextField or subclasses of JPanel implement DataEditingView<T> and where the DataEditingModel<T> is an interface allowing access to the data. It could even be a braindead container class, for all I care. But the problem still remains: I don't have any way of ensuring that DataEditingView<T> is only implemented by JComponents (or some other base class).
This isn't a terribly pressing issue, but littering casts about my code to address this makes me think "future maintenance nightmare." And I wouldn't be so concerned about it, except that this is not the first time I have wanted to declare this kind of requirement: "interface A must be implemented only by subclasses of B". I admit that it's rare and that it's probably a result of bad design, but this might explain why I'm kind of hanging onto the idea.
Your comment has made me rethink my approach, though. Thanks for that. :)
Ian: That's a handy little interface and that kind of freedom could be quite useful. Thanks. :)
tvynra at 2007-7-14 21:29:59 >
