0

I am trying to convince others that the following first code snippet is bad practice and the second snippet is best practice.

Bad practice:

// There is only one implementation of Adapter
public function setAdapter(Adapter $adapter)
{
    $this->adapter = $adapter;
}
public function persist(Entity $entity): void
{
    if ($this->env->dryMode === true) {
        return;
    }
    $this->adapter->persist($entity);
}

Best practice:

// Can inject different adapters, also something like a `DryModeDbAdapter`,
// that simply does nothing when `persist` is called.
public function setAdapter(AdapterInterface $adapter)
{
    $this->adapter = $adapter;
}
public function persist(Entity $entity): void
{
    $this->adapter->persist($entity);
}

I need references that back my thesis. Do you know any? Is there a specific keyword that refers to this programming situation? Like "implementation configuration agnostic" or something.

2 Answers 2

5

It looks like the refactoring you are proposing to change from what you say is bad practice to what you say is good is what Fowler calls replace conditional with polymorphism.

Whether or not its an improvement is context dependent, but that should be enough to help you find more discussion.

3
  • Exactly the kind of reference I was looking for.
    – Daniel W.
    Mar 8, 2022 at 16:29
  • Well, using a lot of ifs in a lot of places is error prone and difficult to maintain. Do you really have a doubt about the polymorphic alternative?
    – Christophe
    Mar 8, 2022 at 19:31
  • 1
    @Christophe I like the refactoring in general, I don't think it's always useful. In this case I think it's probably good but I don't have enough information to be sure.
    – bdsl
    Mar 8, 2022 at 21:30
1

A key question here is when dryMode is known. If it's only known after the adapter is constructed the polymorphic solution wont work.

The polymorphic solution allows you to add more cases later without changing existing, tested, deployed code. You have to ask yourself if those cases are likely to be needed. Booleans have few values so don't really indicate many cases have been anticipated.

The polymorphic solution isn't free. It takes more code, more time to create, more time to read and understand. Yes there's amazing flexibility here. But it comes at a cost. Be sure it's worth it.


There are many boolean toggles "liveMode", "dryMode", "devOnly", - Daniel W.

That is not encouraging.

A polymorphic solution works best when one property can take on many states. Not when many properties are on or off independently. I mean, you can make it work but, yuck.

2
  • Thanks for your feedback! dryMode is known at very early stage (it's in the environment). The real code is complex, with several different environments and configurations. There are many boolean toggles "liveMode", "dryMode", "devOnly", ... in the same module. Considering the complexity, it's definitively worth using polymorphism over conditions in the implementation. The difficult task is to convince the team, not the implementation ;)
    – Daniel W.
    Mar 8, 2022 at 16:22
  • @DanielW. Updated. Mar 8, 2022 at 17:58

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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