Bug 147515 [DataBinding] separate run-time type information from IObservable
Observation: there are two usages of observables. 1. Programmatic usage. The observable is created by client code and its methods are invoked directly. The main benefit of the data binding library in this situation is the ability to use standard content providers, utilities, and transformations. RTTI is never needed for this use case since the client code would always know the type of each observable and its elements. 2. Abstract usage. The client code sets up bindings between things, but does not interact with the observables directly. The client would use observables more like unique identifiers - they would obtain it from a factory and pass it directly to a framework method that selects the correct binding for it. Client code would rarely call methods directly on the observable in this case. These aren't mutually exclusive. The same app will likely use observables in both ways - but I believe that they are the most common use cases. The problem: the RTTI complicates usage 1 even though it is only needed for usage 2. Goal: simplify usage 1 without restricting usage 2 in any way. Suggestion: - Create a new data type called IObservableHandle. It returns an observable and its RTTI: interface IObservableHandle { IObservable getObservable(); Object getValueType(); } - Remove the getElementType() method from IObservableSet and the getValueType() method from IObservableValue. In any situation where this information would be needed, the observable would be wrapped in an IObservableHandle and returned from IObservableHandle.getValueType(). - Change IObservableFactory to return an IObservableHandle rather than an IObservable. - Change any method that makes decisions based on the type of observable (like DataBindingContext.bind (...)) to take an IObservableHandle rather than an IObservable as an argument. Impact: - Any client who is using purely usage 2 would see little difference... but rather than working with IObservables, they'd be working with IObservableHandles. Whenever anyone obtains an observable from a factory, all the RTTI would be available. - Anyone who is implementing an observable or using usage 1 would be able to write simpler code, since their common currency would be the concrete observable interfaces, not IObservableHandle. - It would still be possible to mix-and-match. Someone who obtained an IObservableHandle from a factory and wanted to use it programmatically could do so by downcasting IObservableHandle.getObservable(). Someone who instantiated a concrete observable and wanted to pass it to a method that expects IObservableHandle could easily wrap it in an IObservableHandle. Scripting languages could obtain their observables from the factories, and so would always have the RTTI available for autoboxing.
bundles/org.eclipse.core.databinding/src/org/eclipse/core/databinding/observable/masterdetail/DetailObservableSet.java
/*******************************************************************************
 * Copyright (c) 2005, 2006 IBM Corporation and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *******************************************************************************/
package org.eclipse.core.databinding.observable.masterdetail;
import java.util.HashSet;
import java.util.Set;
import org.eclipse.core.databinding.observable.Diffs;
import org.eclipse.core.databinding.observable.set.IObservableSet;
import org.eclipse.core.databinding.observable.set.ISetChangeListener;
import org.eclipse.core.databinding.observable.set.ObservableSet;
import org.eclipse.core.databinding.observable.set.SetChangeEvent;
import org.eclipse.core.databinding.observable.value.IObservableValue;
import org.eclipse.core.databinding.observable.value.IValueChangeListener;
import org.eclipse.core.databinding.observable.value.ValueChangeEvent;
import org.eclipse.core.runtime.Assert;
/**
 * @since 3.2
 * 
 */
class DetailObservableSet extends ObservableSet {