#๐Ÿ”’ Design pattern: Simple factory

25 messages ยท Page 1 of 1 (latest)

inland light
#

The website had the code written in c++ but i used converted to make it python

from abc import ABC, abstractmethod

class Door(ABC):
    @abstractmethod
    def get_width(self):
        pass
    
    @abstractmethod
    def get_height(self):
        pass

class WoodenDoor(Door):
    def __init__(self, width, height):
        self.width = width
        self.height = height
    
    def get_width(self):
        return self.width
    
    def get_height(self):
        return self.height

class DoorFactory:
    @staticmethod
    def make_door(width, height):
        return WoodenDoor(width, height)

# Make me a door of 100x200
door = DoorFactory.make_door(100, 200)

print('Width:', door.get_width())
print('Height:', door.get_height())

# Make me a door of 50x100
door2 = DoorFactory.make_door(50, 100)

Can anyone explain me more about the asbtract method? I dont understand why its used in the inheritance but never is called super. Also why this pattern is good and why its usefull? I think many people reading this code would say why not call it directly and remove the factory code

surreal hawkBOT
#

@inland light

Python help channel opened

Remember to:

  • Ask your Python question, not if you can ask or if there's an expert who can help.
  • Show a code sample as text (rather than a screenshot) and the error message, if you've got one.
  • Explain what you expect to happen and what actually happens.

:warning: Do not pip install anything that isn't related to your question, especially if asked to over DMs.

stuck wave
#

the main reason for the factory pattern, is to decrease coupling.
Your actual user code:


# Make me a door of 100x200
door = DoorFactory.make_door(100, 200)

print('Width:', door.get_width())
print('Height:', door.get_height())

# Make me a door of 50x100
door2 = DoorFactory.make_door(50, 100)
``` ... doesn't use the "Door" or "WoodenDoor" class anywhere *directly*, and therefor there is less coupling between your user code, and the classes that you use.
That makes those classes easier replaceable by only adjusting the factory code.
#

also, an abstract method is a method, that needs to be implemented by subclasses. so the parent method usually doesn't have any code in them and calling them with super() is pointless (nothing to run in the parent)

inland light
#

but if let say you want all the objects to have the same method it would make sense to put that method in the abstract class and call super?

#

also could you explain what is decrease coupling means? (Not native speaker)

stuck wave
#

yes. and then you'd need to remove the "@abstractmethod" decorator, so it won't cause errors.

inland light
#

but only for that single method right

stuck wave
#

yes

north perch
#

I will point out that an abstract method in Python can in fact have an implementation, and can be called with super. It's not needed in this case

stuck wave
# inland light also could you explain what is decrease coupling means? (Not native speaker)

regarding coupling:
your user code could have:

door = WoodenDoor(100, 200)
``` instead of `DoorFactory.make_door(100, 200)`
but then your user code depends on a specific class (WoodenDoor), and if you ever wanted to replace that class with another one (e.g. MetalDoor), then you'd have to replace *all occurences* of WoodenDoor in your code with the new class.
You *coupled* your user code with the class - they "stick together" more tightly, in a sense.
By using a factory, you loosen that coupling up a bit, making it easier to replace the class, by only having to change the factory method.
north perch
#

Another small detail: In Python, an abstract class has to have an abstract method. If you inherited from ABC but didn't write any abstract method, it wouldn't be considered an abstract class

atomic ingot
#

This DoorFactory.make_door would serve as a documented entrypoint for your users, I suppose. You might throw in some other argument for the material, and then conditionally return a door of different types.

But nothing really stops an intrepid user from pulling the WoodenDoor class itself and using it more directly.

north perch
#

In practice

inland light
#

Oh, interesting

north perch
#

inspect wouldn't say it's abstract, and iirc you would be able to initialize the class

atomic ingot
#

!e

from abc import ABC, abstractmethod

class Door(ABC):
    pass

door = Door()
print("Yep")
surreal hawkBOT
atomic ingot
#

By contrast, trying to instantiate some class with abstractmethods that haven't been overridden, throws an error.

inland light
#

Thank you all for help ๐Ÿ˜„

#

!close

surreal hawkBOT
#
Python help channel closed

This help channel has been closed and it's no longer possible to send messages here. If your question wasn't answered, feel free to create a new post in #1035199133436354600. To maximize your chances of getting a response, check out this guide on asking good questions.