What is a good design for an interface with additional components?

Suppose I have an interface that supports several potential operations:

interface Frobnicator {
    int doFoo(double v);
    int doBar();
}

Now, some instances will support only one or the other of these operations. They can support both. The client code will not necessarily know until it actually receives one of the corresponding factories, through dependency injection or wherever it receives instances.

I see several ways to handle this. One, which seems to be a common tactic accepted in the Java API, is to simply have an interface as shown above and use unsupported methods UnsupportedOperationException. However, this has the disadvantage that it does not work with an error - the client code cannot determine whether it will doFoowork until it tries to call doFoo.

This can be supplemented with the methods supportsFoo()and supportsBar(), defined to return true, if the corresponding method works do.

, doFoo doBar FooFrobnicator BarFrobnicator . null, . instanceof, Frobnicator :

interface Frobnicator {
    /* Get a foo frobnicator, returning null if not possible */
    FooFrobnicator getFooFrobnicator();
    /* Get a bar frobnicator, returning null if not possible */
    BarFrobnicator getBarFrobnicator();
}

interface FooFrobnicator {
    int doFoo(double v);
}

interface BarFrobnicator {
    int doBar();
}

FooFrobnicator BarFrobnicator Frobnicator, get* as*.

: Frobnicator frobnicator, frobnicators ( as*). . , Frobnicator FrobnicatorEngine.

- , ? ? , ( , ), - , . , , : Frobnicator, (, doFoo , Foo), ..

: - . FooFrobnicator BarFrobnicator, , Guice-modules-as-configuration, (, factory/builder, ). , factory, frobnicators, ( , Guice), , : " frobnicator ". , , , .

+5
6

, , , FooImpl Foo, Foo. , , , ( ).

- FooFactory Foo, , Foos.

, ? , , .

, getFooFrobnicator() getBarFrobnicator(). , Frobnicator frobnicate, FrobnicatorHolder.

Frobnicator, , Frobnicators, - .

public interface Frobnicator{
   public void frobnicate();
}

public interface FooFrobnicator{
   public void doFoo();
}

public interface BarFrobnicator{
   public void doBar();
}

if (frobnicator instanceof FooFrobnicator) { ((FooFrobnicator) frobnicator).doFoo() }, .

. .

+3

. , , , , Java API, , , , UnsupportedOperationException. , , - , doFoo , doFoo.

, . HttpServlet.

.

public interface Frobnicator {
    int doFoo(double v);
    int doBar();
}

public abstract class BaseFrobnicator implements Frobnicator {
    public int doFoo(double v) {
        throw new UnsupportedOperationException();
    }
    public int doBar() {
        throw new UnsupportedOperationException();
    }
}

/**
 * This concrete frobnicator only supports the {@link #doBar()} method.
 */
public class ConcreteFrobnicator extends BaseFrobnicator {
    public int doBar() {
        return 42;
    }
}

UnsupportedOperationException . a RuntimeException, " ". , (.. ), , . .

+4

FooFrobnicator BarFrobnicator. , .

(), .

+2

-, UnsupportedOperationExceptions? , .

, - , -, , , , . , , , .

interface Frobnicator {}

interface FooFrobnicator extends Frobnicator {
    void doFoo();
}

interface BarFrobnicator extends Frobnicator {
    void doBar();
}

Edit:

- , false, . :

interface Frobnicator 
{
    boolean doFoo();
    boolean doBar();
}

class FooFrobnicator implements Frobnicator 
{
    public boolean doFoo() { code, code, code; return true; }
    public boolean doBar() { return false; }
}
+1

supports*(),

, , Frobnicator ( , , ) FooFrobnicator BarFrobnicator, , . :

interface FooFrobnicator {
    doFoo();
}

interface BarFrobnicator {
    doBar();
}

public class Client {
     ...
     FooFrobnicator fooFrobnicator;
     public void setFooFrobnicator(FooFrobnicator fooFrobnicator) {
         this.fooFrobnicator = fooFrobnicator;
     }

     BarFrobnicator barFrobnicator;
     public void setBarFrobnicator(BarFrobnicator barFrobnicator) {
         this.barFrobnicator = barFrobnicator;
     }
     ...
     public void doSomething() {
         ...
         if (fooFrobnicator != null) { ... }
         ...
         if (barFrobnicator != null) { ... }
     }
}
...
public class FrobnicatorImpl implements FooFrobnicator, BarFrobnicator { ... }
...
public void doSomething() {
    ...
    FrobnicatorImpl impl = new FrobnicatorImpl();
    Client client = new Client();        
    client.setFooFrobnicator(impl);
    client.setBarFrobnicator(impl);
    ...
}
0

, . . ( , , ). / , .

-1

All Articles