Skip to main content

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [List Home]
RE: [platform-ui-dev] Component framework proposal version 1.0.4 available


Ed,

Thanks for taking another look at this. See my responses below.

platform-ui-dev-admin@xxxxxxxxxxx wrote on 11/09/2004 04:38:07 PM:

> I looked at 1.0.4 and have a few comments and questions.

>  
> Would this make it easier to create and use reusable components like
> a Calendar widget or a Graph control? Would it be possible (or
> advisible) to make widgets from Labels and Combo boxes to TableTrees
> and StyledText follow the same component model?


I'd very much like for that to be the case, however it may be overkill in these situations. If you're simply creating a better Combo box, it would be simpler and more efficient to just write a new widget and instantiate it by calling its constructor.

The component framework is more useful these situations:
- Writing a parent that creates child components which it only knows about by ID.
- Writing components that are complex enough that they need localized interfaces to simplify resource management
- Writing components that support a higher-level protocol than what is provided by SWT or JFace (for example, a persistence interface).


> One of the major innovations seems to be that a Component has a
> constructor that takes some interface parameters, and someone
> discovers what those parameters are through reflection and makes
> sure they are available. That saves one assignment and cast per
> parameter but I'm wondering if it's worth it compared to passing an
> IAdaptable or a Map or PropertyBag containing all the needed interfaces.


That depends on what you mean by "worth it". You're right that this is essentially syntactic sugar and IAdaptable would work just as well. However, constructor injection has several benefits:
- Writing a component takes less code
- Instantiating a component takes less code
- Components take concrete interfaces rather than abstractions like IAdaptable.
- Components to not need to depend on the framework

The only cost is a small amount of (relatively simple) code in the framework.

For more on constructor injection, see www.picocontainer.org.

Consider the following snippets

// Alternative 1: taking arguments using literal classes
class Leash {
        Dog d;

        /**
             * Dog must not be null
          */
        public Leash(Dog dog) {
                d = dog;
        }
}

// Alternative 2: querying for arguments using IAdaptable
class Leash {
        Dog d;

        /**
             * Throws an exception of the given adaptable is not adaptable to Dog. The given adaptable must not be null.
             */
        public Leash(IAdaptable a) throws Exception {
                d = (Dog)a.getAdapter(Dog.class);
                if (d != null) {
                        throw new Exception("missing dependency");
                }
        }
}

Personally, I find alternative 1 easier to read and understand. Alternative 1 is also much easier to instantiate outside the framework. Note that the extra error checking is needed for alternative 2 since the Leash does not advertise its dependencies and would therefore be responsible for checking them itself.

> Are your "Derived Factories" or "Mutable Factories" the same as
> "Working Copies" elsewhere in Eclipse?


Not exactly. This is more like runtime inheritance. Clients can't implement IContainerFactory (in order to hide some implementation details), but they still need to be able to specialize its behavior. To do this, they create a derived factory and overload the services they want to specialize. Anything else gets delegated to the original.

This is a common area for confusion, so it might be refactored in the future.

> In section 2.3, why would it be a bad idea to simply pass the parent
> composite on to the component rather than creating a new composite
> or composite factory? Anyway isn't a CompositeFactory kind of like a
> Component itself?


I guess it wouldn't be catastrophic, but it would give the potential for components to leak widgets and listeners into their parent composite. Currently, views and editors are not responsible for disposing the widgets they create in their createChildControls method, which means that the same will be expected from new-style parts. It also ties in with the robustness requirement: a component shouldn't be able to leak by calling methods directly on one of the objects it gets in its constructor.

In the case of views, editors, and Composites, clients won't need to mess with CompositeAdapter since they will use a factory provided by the workbench that does this for them. If I'm instantiating a part I only need to supply the parent composite. If I'm writing a part, I'll be given my own Composite that is managed for me magically. If I'm writing the workbench, I need to use CompositeAdapter to supply the magic.

This section explains the general technique so that people can write their own factories that do the same type of magic. The actual protocol for instantiating a view would be closer to what you see in section 2.1.

> You have a couple of classes/interfaces, Site and IContainer, that
> have a dispose() method; was it your intent that they implement
> IDisposable? You mention implementing IDisposable elsewhere.


Actually, they do... but I simplified some of the interfaces for clarity in the doc. Well spotted. :-) The "real" IContainer interface looks like this:

/**
 * Wraps a component and all of its dependencies. IContainers are created
 * by an IContainerFactory and are destroyed by calling their dispose() method.
 *
 * Not intended to be implemented by clients.
 *
 * @since 3.1
 */
public interface IContainer extends IAdaptable, IDisposable {
}

>  
> You note that your adapters are "different from most other adapters
> in Eclipse" because they can keep state. Then later you have an
> possible optimization for adapters that don't keep state. Can you
> list any Eclipse adapters that keep state? Does "not keep state"
> mean the same as "not implement IDisposable"?


Perhaps I misunderstand the question. I'm not aware of any existing Eclipse adapters that keep any state. Like I said, these adapters are different. By "keep state", I meant something more like "allocate something that needs to be deallocated later". Yes, there would be a 1-to-1 correspondence between allocating things and implementing IDisposable. I'll try to clean up the terminology in the next pass.

>  
> In the org.eclipse.core.component.interface extension point does the
> interface element need an id? Maybe the interface attribute should
> be called id.


The interface element is the fully-qualified name of the Java interface that components will include in their constructor. An additional ID would not be used. It looks like this attribute could use more documentation.

I suspect you're commenting on the heavy usage of the word "interface". Would "specification" be better?

> "Service" is still used in a few places where I think you mean
> "Component". For example in section 2.4, "when it comes time to
> create the service". Also you still use "service interface" in a few places.

>  
> Typo in section 1, "couldcontribute".
>  

Agh. :-(

How embarrassing. I think this experience has taught me an important lesson about editing.

  - Stefan

Back to the top