To interface or not to interface

Michel Fortin michel.fortin at michelf.com
Wed May 26 07:20:31 PDT 2010


On 2010-05-26 06:55:14 -0400, Jacob Carlborg <doob at me.com> said:

> On 2010-05-25 17.03, Michel Fortin wrote:
>> On 2010-05-25 10:01:48 -0400, Jacob Carlborg <doob at me.com> said:
>> 
>>> Now Item could be an interface but it don't have to be. I suggest you
>>> have a look at Apple's documentation of NSTableView:
>> 
>> What Cocoa is doing is basically allowing 'optional' methods in an
>> interface (a protocol in Objective-C). Taking your example, the
>> NSTableViewDataSource protocol contains a lot of functions to provide
>> the required data to a table. But many of them are optional: for
>> instance a data source that does not implement the
>> "...setObjectValue..." method will prevent the table's content from
>> being edited, one that doesn't implement the
>> "...sortDescriptorsDidChange..." method prevents the table from being
>> sorted by clicking on its column headers, one that doesn't implement the
>> various methods for drag and drop will prevent rows from being dragged.
> 
> I've always thought that this design and the similar Java uses with 
> interfaces, anonymous classes and adapters is just a design chosen 
> because the languages are limited, don't support delegates.

Indeed.

Well, I think you could use runtime-reflection to achieve the same 
thing in Java, but that would make your interfaces "informal", in the 
sense that you just can't put those optional functions in the 
interfaces. (And it'd uglify the code a lot.) Technically, this is what 
was done prior Mac OS X 10.6 with informal protocols; I say "almost" 
since the method signatures being added as unimplemented categories to 
NSObject, they could still checked for correctness by the compiler.


>> Perhaps interfaces could be allowed to have optional methods that would
>> require you to check if they're implemented before use.
> 
> How would you check if a method is implemented or not ?

In Objective-C, it's quite easy. For instance, I've made my own 
subclass of NSTableView querying the delegate for a background color 
for a given row. So here's how you use the delegate:

	id delegate = [self delegate];
	
	if ([delegate 
respondsToSelector:@selector(tableView:backgroundColorForRow:)]) {
		NSColor *color = [delegate tableView:self backgroundColorForRow:row];
		...draw background color...
	}

In D you can't do that currently, but here's how it could be added. 
First add an optional attribute for interface members:

	interface TableDelegate {
		...
		@optional NSColor backgroundColorForRow(NSTableView table, size_t row);
	}

Classes implementing the interface can omit the @optional methods. When 
omitted, the interface function is null. When using the interface, you 
must check first if the optional function is implemented by making sure 
the address isn't null:

	TableDelegate delegate = this.delegate;
	
	if (&delegate.backgroundColorForRow != null) {
		NSColor color = delegate.backgroundColorForRow(this, row);
		...draw background color...
	}

This would work somewhat similarily to weak-linked symbols.

-- 
Michel Fortin
michel.fortin at michelf.com
http://michelf.com/



More information about the Digitalmars-d mailing list