Skip to content

Instantly share code, notes, and snippets.

@1oglop1
Last active September 20, 2021 05:29
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save 1oglop1/088f07c40678d4875c1c6ea606fadbb9 to your computer and use it in GitHub Desktop.
Save 1oglop1/088f07c40678d4875c1c6ea606fadbb9 to your computer and use it in GitHub Desktop.
What pattern should I use?
import enum
from dataclasses import dataclass
# ========= Helper code to set the scene =========
# fake data loaded from csv
DATA = [
{"object_id": "1", "state": "0"},
{"object_id": "2", "state": "1"},
{"object_id": "3", "state": "2"},
{"object_id": "4", "state": "0"},
]
class Reason(str, enum.Enum):
"""Django model CSV reasons."""
accepted = "0"
rejected_reason_1 = "1"
rejected_reason_2 = "2"
class Status(str, enum.Enum):
"""Django model states"""
another_state = "0"
yet_another_state = "1"
accepted = "2"
rejected_reason_1 = "3"
rejected_reason_2 = "4"
@dataclass
class MyObj:
"""Fake Django model."""
object_id: str
state: str
def set_state_in_db(state: str):
"""Fake ORM method."""
print(f"setting state to {state}")
def send_mail(msg: str):
"""Fake method to send email."""
print(msg)
# ========= Implementation =========
def original_code():
"""Original code before refactoring."""
for line in DATA:
item = MyObj(**line)
if item.state == Reason.accepted:
set_state_in_db(Status.accepted)
if item.state in [
Reason.rejected_reason_1,
Reason.rejected_reason_2,
]: # imagine more reasons here
if item.state == Reason.rejected_reason_1:
set_state_in_db(Status.rejected_reason_1)
msg = f"Long email template with obj_id {item.object_id} reason 1."
elif item.state == Reason.rejected_reason_2:
set_state_in_db(Status.rejected_reason_2)
msg = f"Long email template with obj_id {item.object_id} reason 2."
send_mail(msg)
if __name__ == "__main__":
original_code()
import enum
from dataclasses import dataclass
# ========= Helper code to set the scene =========
# fake data loaded from csv
DATA = [
{"object_id": "1", "state": "0"},
{"object_id": "2", "state": "1"},
{"object_id": "3", "state": "2"},
{"object_id": "4", "state": "0"},
]
class Reason(str, enum.Enum):
"""Django model CSV reasons."""
accepted = "0"
rejected_reason_1 = "1"
rejected_reason_2 = "2"
class Status(str, enum.Enum):
"""Django model states"""
another_state = "0"
yet_another_state = "1"
accepted = "2"
rejected_reason_1 = "3"
rejected_reason_2 = "4"
@dataclass
class MyObj:
"""Fake Django model."""
object_id: str
state: str
def set_state_in_db(state: str):
"""Fake ORM method."""
print(f"setting state to {state}")
def send_mail(msg: str):
"""Fake method to send email."""
print(msg)
# ========= Implementation =========
def reject_action_1(object_id: str):
set_state_in_db(Status.rejected_reason_1)
return f"Long email template with obj_id {object_id} reason 1." # imagine 10+ lines email
def reject_action_2(object_id: str):
set_state_in_db(Status.rejected_reason_2)
return f"Long email template with obj_id {object_id} reason 2." # imagine 10+ lines email
STATES = {
Reason.rejected_reason_1: reject_action_1,
Reason.rejected_reason_2: reject_action_2,
}
def my_version():
"""My version of refactored original_code."""
for line in DATA:
item = MyObj(**line)
if item.state == Reason.accepted:
set_state_in_db(Status.accepted)
continue
csv_state = Reason(item.state)
msg = STATES[csv_state](item.object_id)
send_mail(msg)
if __name__ == "__main__":
# ========= expected output =========
# setting state to 2
# setting state to 3
# Long email template with obj_id 2 reason 1.
# setting state to 4
# Long email template with obj_id 3 reason 2.
# setting state to 2
my_version()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment