Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Stay SOLID and DRY with coroutines and functions as methods in python

I have that Code example:

from time import sleep
import asyncio

class bird:

    def __init__(self, sleeptime=1):
        self.var = sleeptime

    def wait_meep(self):
        sleep(self.var)
        print("Meep")

    def do_sth(self):
        print("Dop Dop Do do ...")


class bird_async:

    def __init__(self, sleeptime=1):
        self.var = sleeptime

    async def wait_meep(self):
        await asyncio.sleep(self.var)
        print("Meep")

    def do_sth(self):
        print("Dop Dop Do do ...")

As you can see, both clients are mostly identical and shall contain the same name (so that everyone knows what to expect). Now I want to be DRY and write bird_async(bird). Because every extension in bird shall be used in bird_async as well. This is possible, but my coworker says, it is not SOLID, because I have overwritten wait_meep. Now I am looking for different soultions and found abstract classes. What I don't know is, if creating an abstract class birdBase(ABC) would be SOLID as well. I would overwrite there as well, because first it was a function and then a couroutine, or am I wrong here?

What could be a SOLID and DRY solution to get those both classes together, without renaming the methods?

like image 553
zonk Avatar asked Aug 27 '20 11:08

zonk


Video Answer


1 Answers

The DRY solution is some kind of subclassing as you already did.

I think a "SOLID" solution is very hard to achieve under your condition. Fact is, you have two functions wait_meep, which have actually different signature and semantics. Namely, the first one blocks for the sleep interval, which can be arbitrary long. The second one OTOH is async, i.e. needs special calling semantics and runs concurrently.

A somewhat comparable case is the Queue class from the standard library. There you have get and get_nowait methods which do the same, in different ways. Second example could be __iter__ and __aiter__ methods.

So I think the only "correct" solution would be renaming one of the methods. Which would have the side effect that you could write it all as one class, i.e. reduce number of moving parts.

like image 182
Torben Klein Avatar answered Sep 25 '22 02:09

Torben Klein