interface fulfillment using fields - a java language proposition - part 2 of 2

Friday, July 11, 2008

I'm proposing a new keyword in Java class definitions, via. It essentially provides a methodology to simply and maintainably perform automatic delegation of interface methods to member fields. Part one introduced the concept, while part two will delve into more of the finer points.

Inheritance model integrity


The integrity of the inheritance model is maintained, as a class using via can also subclass another class, eg:
public class Laptop extends Computer implements Chargeable via this.internalBattery

And this class can even be subclassed itself:
public class MacBook extends Laptop

As seen in Part one, the classes compile to a traditional POJO so inheritance is not adversely affected. Of course any class can only extend one class, but
via can wrap many classes.

An illustration: If obj.method() is invoked and Obj uses via
  • an implementation of method() defined by Obj is looked for first.

  • If not found, then tries Obj.super.method() and so on up to Object.method() when not found.

  • If not found in the object's hierarchy up to and including Object then its implemented interfaces are searched (and the method invoked on the corresponding field).

  • If Obj's interfaces don't define it then work up the inheritance tree again, checking for any interfaces fulfilled with via.

  • In the situation where two or more interfaces are mapped with via in the same class and define the same method, obviously the JVM wouldn't know which field to invoke the method on. In this case a compiler error will be thrown. The solution is to explicitly override the method in Obj.


IOC and DI


What about the IOC pattern? As far as I see it, via is an awesome tool to use with IOC patterns, such as the Spring Framework. The idea with the IOC pattern (or Dependency Injection (DI)) is that any implementation class that fulfils the required interface can be swapped in at runtime. As far as I know DI can't be used to inject in a class to be subclassed, as the inheritance is defined as the subclassing of a given concrete class. As we saw in Part one, via basically lets us subclass interfaces. This means that a given interface can have our extra functionality or handling (using via), but that interface can be any class, it's just whatever the IOC container passes in. Very cool.


Multi-class interface fulfilment


Part one mentioned the idea of fulfilling an interface by the combining of two or more classes. The problem this is trying to solve is basically that to implement one interface method might require the help of a number of private methods. This then encourages splitting up interfaces so that the implementation classes don't suffer from unreadability and complexity. The problem this creates is that the exposed interfaces then increase in number and each is more basic than it need be.
The idea is that an interface can be defined with as many methods as the pure design requires, without concern about the resulting complexity of any implementors. Using via, a single class can implement an interface and define a number of implementation classes that combine to fulfil it. Here's a full example:
// first two package-visible interfaces
interface PackageIface1 {
void setName(String name);
}

interface PackageIface2 {
void setNumber(int number);
}

// now the public interface that combines them
public interface PublicIface extends PackageIface1, PackageIface2 {}

// the implemetation classes (package-visible)
class PackageClass1 implements PackageIface1 {
public void setName(String name) {...}
}

class PackageClass2 implements PackageIface2 {
public void setNumber(int number) {...}
}

// and the integration class that brings them all together
public class PublicClass implements PublicIface via this.pkgIface1Obj & this.pkgIface2Obj {
// class just defines the two fields and constructor(s)
}

(Note: The '&' symbol is arbitrarily chosen and could be anything that makes sense and is acheivable).
So the PublicIface is the only interface that needs to be exposed publicly. The PublicClass will be a fixed implementation to use. Discrete functionality subsets of PublicIface can be changed by swapping in a different implementation of PackageIface1 or PackageIface2 that get passed to PublicClass's constructor. And there is no limit to the number of classes that can be used to fulfil the main interface, provided that each one exclusively implements an interface that is extended by the main interface.


I may be way off track, but I dreamed this up when coming across the same problem for the tenth time in an enterprise Java project using Spring, and it just seems to fit. It may be that there are techniques or patterns out there that mean I can do all this already, or just that I should be slapped for suggesting such things. All feedback welcome.

interface fulfillment using fields - a java language proposition - part 1 of 2

I'm proposing a new keyword in Java class definitions, via. It essentially provides a methodology to simply and maintainably perform automatic delegation of interface methods to member fields.

This provides:

  1. Encouragement for coding to interfaces over inheritance
  2. Object wrappers that do not need to subclass the wrapped object, yet still expose the wrapped object's methods directly (exposed as 'is-a' rather than having to manually delegate because of 'has-a')
  3. Can 'swap out' the effective superclass (like subclassing an interface, not a class)
  4. Advantages of multiple-inheritance
  5. and potentially: Interface fulfillment by combining two or more classes

Here's an example of what it might look like:
public class Car implements Driveable via this.vehicle {

Which says, I have a class, Car, which implements the interface Driveable. Car as an object definition may not fulfill all (or any) of the requirements for Driveable, but via its field 'vehicle', the contract is met.

And the code for Car might look like:
{
private Driveable vehicle;

public Car() {
this.vehicle = new DefaultCar();
}

public void doCarStuff() {...}
}

So we can see here that the requirements for the Driveable interface can be met by anything that can be assigned to the 'vehicle' field. In this case a new instance of DefaultCar. As with any class, Car can also define any other additional members as well (e.g. doCarStuff()), enriching the functionality of DefaultCar (as subclassing would). It is essentially a methodology for automatic and type-safe delegation. But we gain nothing in this example, we may as well just extend the DefaultCar class. To get the advantages we need to make some changes...
{
private Driveable vehicle;

public Car() {
this.vehicle = new DefaultCar();
}

public Car(Driveable driveableClass) {
this.vehicle = driveableClass;
}

public void doCarStuff() {...}
}

In this way Car's new functionality can enrich any implementation of Driveable. At runtime we can instantiate different instances of Car, each of which could have a unique implementation of Driveable. Swapping in different driveableClass objects could be useful for endowing different classes with the same extra features. Also for testing, Mocks or test doubles can be passed to the constructor so that only the added features are under test.

In this example Car could also override any of the Driveable methods, as with traditional class inheritance. More on overriding in Part two.


Under the hood


So how is it working? I imagine the compiler would generate bytecode representing the code below. You could write this yourself, but it would be messy and require duplication.
Firstly an example of the Driveable interface:
public interface Driveable {

void setSpeed(int speed);

boolean isMoving();
}


Then the effective resulting code (ie the developer wouldn't see it written like this):
public class Car implements Driveable via this.vehicle {
private Driveable vehicle;

public Car() {
this.vehicle = new DefaultCar();
}

public Car(Driveable driveableClass) {
this.vehicle = driveableClass;
}

public void doCarStuff() {...}

//delegation
public void setSpeed(int speed) {
this.vehicle.setSpeed(speed);
}

//delegation
public boolean isMoving() {
return this.vehicle.isMoving();
}



Multiple inheritance


While some debate the merits of multiple inheritance, this is often imitated by subclassing and using an inner class that has subclassed also. The via keyword, however, allows us to do this directly.
public class Car implements Driveable via this.vehicle,
Runnable via this.runner {


The construct would not break existing Java inheritance relationships, as a class can both extend a class as well as use interface fulfillment via fields, and a class that uses that construct can itself be subclassed.


More to follow...


More benefits and some finer points will follow in Part 2, including benefit [5] hinted at earlier...

debug sound in linux - first steps!!

Wednesday, July 09, 2008

My sound stopped after having worked for 6 months. I hadn't run any updates, and even tried booting into previous kernels to check, but that didn't help. Finally I discovered the answer, but not thanks to internet searching. Here are the requirements:

  1. If you are running linux
  2. If you have Windows on another partition you can dual boot into
  3. If sound works ok in Windows
and here is the first 2 steps:
  1. Check for a hardware mute switch and/or volume control on the machine (especially laptops) - this will affect Windows as well, so if it's currently working there then this won't be the problem
  2. Boot into Windows. Unmute the sound. Try linux again
So that was my problem. I had muted sound whilst in Windows, not realising that Windows can hardware-mute the sound card, something that linux doesn't have control over. So when re-booting into linux, it thought it was playing sound fine, but I could hear nada. Hope this helps someone :)

The silver-lining in this exercise in frustration was fixing my VLC performance. I had noticed for a few weeks that music and movies played in VLC would be silent for the first 10s or so. Running VLC in terminal gave complaints about pulseaudio not found.
Solution here for me was to go into the VLC preferences> Output Modules and check the box for advanced options. Change 'Audio Output Module' from default to 'ALSA audio output'.
The alternative option would be to install pulseaudio (sudo aptitude install pulseaudio). It seems pulseaudio is the new default sound server in Ubuntu and provides more advanced sound functionality, particularly when it comes to combining sounds, so this may be the best chouce.