1

Is there a design pattern that fits this description? A factory that creates classes that can be disabled and enabled. The users of the class don't know if the functionality is enabled or disabled--they just call methods on the class. What are appropriate names for this kind of factory and class? How do you make this pseudocode correct and thread-safe?

class FooFactory {
    static enabled;
    List foos = new ArrayList();
    getFoo() {
        Foo foo = new EnabledOrDisabledFoo(enabled);
        foos.add(foo);
        return foo;
    }
    setEnabled(boolean enabled) {
        for (Foo foo : foos)
            foo.setEnabled(enabled);
    }
}

class EnabledOrDisabledFoo implements Foo {
    private enabled;
    private Foo;
    EnabledOrDisabledFoo(boolean enabled) {
        this.enabled = enabled;
    }
    setEnabled(boolean enabled) {
        this.enabled = enabled;
    }
    doFoo() {
        if (enabled)
            foo.doFoo();
    }
}

class FooConsumer {
    Foo foo = FooFactory.getFoo();
    foo.doFoo();
}

class FooManager {
    FooFactory.setEnabled(true);
    FooFactory.setEnabled(false);
    FooFactory.setEnabled(true);
    FooFactory.setEnabled(false);
}

closed as primarily opinion-based by gnat, Bart van Ingen Schenau, David Arno, BobDalgleish, Robert Harvey May 8 at 16:52

Many good questions generate some degree of opinion based on expert experience, but answers to this question will tend to be almost entirely based on opinions, rather than facts, references, or specific expertise. If this question can be reworded to fit the rules in the help center, please edit the question.

  • Just to clarify the question. You need some components to be capable of being set as enabled or disabled, but avoiding consumers to be aware of this capability. Am I right? – Laiv May 8 at 9:31
  • 2
    can you please confirm or clarify: 1) it’s not classes that are disabled but parts of their methods ? 2) if the choice between enabled or disabled depends on the factory configuration (i.e. all the classes generated are either enabled or disabled) or if the factory needs to chose every time it has to create an object ? 3) once created, can an object be enabled/disabled dynamically later on ? – Christophe May 8 at 10:50
  • It looks like you merged the null object pattern with another implementation. I'd argue that you could better split responsibility by having two implementations of Foo: DefaultFoo (whatever the real name is) and NullObjectFoo, and then the factory is responsible for instantiating the correct implementation based on the enabled variable. However, this does mean that if you need to toggle the state on the fly on an existing instance, you might need a different strategy to handle this. – Vincent Savard May 8 at 16:06
2

What you describe would only be feasible for void methods, getting something would need to return some default.

To do that dynamically, one would use delegation and depending on a flag enable/disable the passing.

There is a related technique: the lookup/discovery of capabilities.

Instead of having a class FlyingAnimal, have a class Animal with a dynamic lookup of Flying.

I would consider testing capabilities/features:

interface Flying { void fly(); }
interface Swimming { void swim(); }

Animal animal = ...

Optional<Flying> flying = animal.lookup(Flying.class);
flying.ifPresent(f -> f.fly());    interface Flying { void fly(); }

Optional<Swimming> swimming = animal.lookup(Swimming.class);
swimming.ifPresent(sw -> sw.swim());

Animal need not implement any interface, but you can look up (lookup or maybe as) capabilities. This is extendible in the future, dynamic: can change at run-time.

Implementation as

private Map<Class<?>, ?> map = new HashMap<>();

public <T> Optional<T> lookup(Class<T> type) {
     Object instance = map.get(type);
     if (instance == null) {
         return Optional.empty();
     }
     return Optional.of(type.cast(instance));
}

<S> void register(Class<S> type, S instance) {
    map.put(type, instance);
}

The implementation does a safe dynamic cast, as register ensures the safe filling of (key, value) entries.

The advantage of a lookup mechanism (with Optional) is that its usage is optimally guarded.

On pattern naming: the original notion probably best is named delegation with a switch to a dummy/null.

0

I don't know if there is a name for this specifically. It seems like a simplified form of the Strategy Pattern but you could also maybe describe this as using the Decorator Pattern or a combination of the two.

The simplest thing to make this thread safe would be to do this:

class EnabledOrDisabledFoo implements Foo {
    private final AtomicBoolean enabled = new AtomicBoolean();
    private Foo;
    EnabledOrDisabledFoo(boolean enabled) {
        setEnabled(enabled);
    }
    setEnabled(boolean enabled) {
        this.set(enabled);
    }
    doFoo() {
        if (enabled.get())
            foo.doFoo();
    }
}

This will simply make sure that once set is called, all threads that subsequently read the value will see that value. If you have more complex threading coordination requirements, this may not suffice.

Not the answer you're looking for? Browse other questions tagged or ask your own question.