Trying to figure out which structure is cleaner between using a specialized function or using parameters to accomplish the same thing (see code example below).

Essentially, I can reduce the number of abstract methods in my interface by adding parameters (as in the BufferParameter case). If the methods themselves got too big (in terms of parameters and/or lines of code), then I'd swap over to explicit functions (as in BufferMethod case).

Is my logic sound here, or should I always prefer the BufferMethod case?

class BufferBase(object):
    __metaclass__ = ABCMeta

    @abstractmethod
    def clear(self):
        pass

    def clearall(self):
        """Only used in the `BufferMethod` class."""
        pass

class BufferParameter(BufferBase):
def clear(self, buffer_idx='all'):
    """Accepts either a buffer integer index or the string 'all'."""
    if buffer_idx == "all":
        for buff in self.buffers:
            buff.clear()
        return

    self.buffers[buffer_idx].clear()

class BufferMethod(BufferBase):
    def clear(self, buffer_idx):
        self.buffers[buffer_idx].clear()

    def clearall(self):
        for buff in self.buffers:
            buff.clear()

Examples of use:

bp = BufferParameter()
bm = BufferMethod()

for b in bp.buffers:
    b.write('foo')

for b in bm.buffers:
    b.write('foo')

bm.append('bar', buffer_idx=6)
bp.append('bar', buffer_idx=6)

print(bm.read(buffer_idx=6))
print(bp.read(buffer_idx=6))

print(bm.read(buffer_idx='all'))
print(bp.readall())

bm.clear('all')
bp.clearall()
  • As a sidenote - this applies to nearly every method in the base class, so either I have twice as many methods or each method has a special parameter. – Nick Sweet Nov 1 at 17:32
  • It's hard to tell right now. Can you post some sample code how these classes would be used? As with any question about the public interface of a class, knowing how the objects get used is essential. – Greg Burghardt Nov 2 at 12:06
  • @GregBurghardt I've added an example of use to the question. Hope that helps clarify! – Nick Sweet Nov 6 at 16:29

You should prefer the BufferMethod approach over the BufferParameter approach.

Methods should ideally do only one thing. Here, you are implementing two very different behaviors: clearing one particular buffer by index, and clearing all buffers. It's clearer and cleaner to have separate methods for them.

  • I completely agree with the "one thing" approach (thank you Uncle Bob), but I didn't want to be dogmatic about it, especially given the fact that they're both inheriting from an interface which may not have a clearall method for each subclass in the future. – Nick Sweet Nov 6 at 16:32

Your Answer

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

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