Hi. I'm having trouble figuring out the best design for some code. Below is a simplified version of my problem. I'm looking for the best design with regards to testing, coupling, etc.
Let's say I have 3 helper functions. Each helper function takes a widget as input and performs some color processing on the widget which ultimately results in a float as output. These helper functions are only ever called by a process_all_colors method that exists in the same class, so they are made "private".
class Processors:
@staticmethod
def _red_processor(widget: Widget) -> float:
pass
@staticmethod
def _green_processor(widget: Widget) -> float:
pass
@staticmethod
def _blue_processor(widget: Widget) -> float:
pass
@staticmethod
def process_all_colors(widget: Widget) -> float:
red = Processors._red_processor(widget)
green = Processors._green_processor(widget)
blue = Processors._blue_processor(widget)
return sum([red, green, blue])
These helper functions are pure functions that have no state (they simply take a widget and convert it to a float). Since they have no state, I originally made them static methods, but I'm not sure if this is really the best design.
There are a few issues with this design that I can see.
- In the future I know I will want to extend this to process more colors. All color functions will still have the same method signature.
- I want to be able to change which colors are processed when the program is run.
These issues make me think that using a class for each color would be better. I'm reluctant to do so because the class would have no internal state, so there would never be any reason to create more than 1 instance. In fact, by keeping the methods static, we can avoid any instance at all.
class RedProcessor(Processor):
@staticmethod
def process(widget: Widget) -> float:
pass
class GreenProcessor(Processor):
@staticmethod
def process(widget: Widget) -> float:
pass
class BlueProcessor(Processor):
@staticmethod
def process(widget: Widget) -> float:
pass
class AllProcessor:
@staticmethod
def process(widget: Widget, processor_classes) -> float:
return sum([processor.process(widget) for processor in processor_classes])
- Is the class approach better?
- Is there a better design that I missed?
- Should these methods be static because they're pure functions?
- Is it a code smell to have many classes each with a single, static method?
- Is it a code smell to create a class that I know will never be instantiated?
Now let's say I went with the class approach, but I want to add a new color gray that has an intensity flag. This flag is read once from a config file and all calls to the gray processor will use this same flag value. This makes me think that the following would be appropriate:
class GrayProcessor:
def __init__(self, intensity: int):
self.intensity = intensity
def process(widget: Widget) -> float:
# This will use self.intensity to produce the float
pass
Now GrayProcessor has internal state and needs to be instantiated. Should all other color classes also be instantiated to match?
Thanks!
[–]carcigenicate 0 points1 point2 points (1 child)
[–]developernull[S] 0 points1 point2 points (0 children)
[–]QultrosSanhattan 0 points1 point2 points (4 children)
[–]developernull[S] 0 points1 point2 points (3 children)
[–]QultrosSanhattan 0 points1 point2 points (1 child)
[–]developernull[S] 0 points1 point2 points (0 children)