Skip to content

Instantly share code, notes, and snippets.

@mahenzon
Last active April 15, 2023 17:36
Show Gist options
  • Save mahenzon/4716d793c11a3dedda01f83404a6d115 to your computer and use it in GitHub Desktop.
Save mahenzon/4716d793c11a3dedda01f83404a6d115 to your computer and use it in GitHub Desktop.
SOLID Principles Python examples
Display the source blob
Display the rendered blob
Raw
{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# SOLID Principles example\n",
"\n",
"\n",
"## 1. Single Responsibility Principle\n",
"\n",
"\n",
"### 1.1 Single Responsibility Principle violation\n",
"\n",
"```python\n",
"class Animal:\n",
" def __init__(self, name):\n",
" self.name = name\n",
"\n",
" def make_sound(self):\n",
" print(self.name, \"makes sound...\")\n",
"\n",
" @classmethod\n",
" def get_from_db(cls, name):\n",
" print(\"find\", name, \"in db\", cls)\n",
"\n",
" def save_to_db(self):\n",
" print(\"save to db\", self)\n",
"```\n",
"\n",
"\n",
"### 1.2 Following the Single Responsibility Principle\n",
"\n",
"\n",
"```python\n",
"class Animal:\n",
" def __init__(self, name):\n",
" self.name = name\n",
"\n",
" def make_sound(self):\n",
" print(self.name, \"makes sound...\")\n",
"\n",
"\n",
"class AnimalDB:\n",
"\n",
" @classmethod\n",
" def get_from_db(cls, name):\n",
" print(\"find\", name, \"in db\", cls)\n",
"\n",
" @classmethod\n",
" def save_to_db(cls, animal):\n",
" print(\"save to db\", animal)\n",
"```\n",
"\n",
"\n",
"## 2. Open Closed Principle\n",
"\n",
"\n",
"### 2.1 Open Closed Principle violation\n",
"\n",
"```python\n",
"def get_animal_sound(animal):\n",
" if animal.name == \"lion\":\n",
" return \"roar\"\n",
" if animal.name == \"cat\":\n",
" return \"meow\"\n",
"```\n",
"\n",
"### 2.2 Following the Open Closed Principle\n",
"\n",
"```python\n",
"class Animal:\n",
" def __init__(self, name, sound):\n",
" self.name = name\n",
" self.sound = sound\n",
" \n",
" def make_sound(self):\n",
" print(self.name, \"makes sound\", self.sound)\n",
" \n",
"\n",
"lion = Animal(\"lion\", \"roar\")\n",
"cat = Animal(\"cat\", \"meow\")\n",
"print(lion.sound)\n",
"# roar\n",
"lion.make_sound()\n",
"# lion makes sound roar\n",
"print(cat.sound)\n",
"# meow\n",
"cat.make_sound()\n",
"# cat makes sound meow\n",
"```\n",
"\n",
"\n",
"## 3. Liskov Substitution Principle\n",
"\n",
"\n",
"### 3.1 Liskov Substitution Principle violation\n",
"\n",
"```python\n",
"def get_animal_tail_info(animal):\n",
" if isinstance(animal, Lion):\n",
" return animal.get_lion_tail_info()\n",
" if isinstance(animal, Cat):\n",
" return animal.get_cat_tail_info()\n",
"```\n",
"\n",
"### 3.2 Following the Liskov Substitution Principle\n",
"\n",
"\n",
"```python\n",
"class Animal:\n",
" def get_tail_info(self):\n",
" return \"\"\n",
"\n",
"\n",
"class Lion(Animal):\n",
" def get_tail_info(self):\n",
" return \"Lion has a big and heavy tail...\"\n",
"\n",
"\n",
"class Cat(Animal):\n",
" def get_tail_info(self):\n",
" return \"Cat has a nice and furry tail...\"\n",
"\n",
"\n",
"def get_animal_tail_info(animal: Animal):\n",
" return animal.get_tail_info()\n",
"```\n",
"\n",
"\n",
"## 4. Interface Segregation Principle\n",
"\n",
"\n",
"### 4.1 Following the Interface Segregation Principle\n",
"\n",
"\n",
"```python\n",
"from abc import abstractmethod\n",
"\n",
"\n",
"class MessagingDevice:\n",
"\n",
" @abstractmethod\n",
" def send_email(self, recipient, email_object):\n",
" pass\n",
"\n",
" @abstractmethod\n",
" def send_sms(self, recipient, sms_object):\n",
" pass\n",
"\n",
"\n",
"class Smartphone(MessagingDevice):\n",
" \"\"\"\n",
" Just a regular smartphone\n",
" \"\"\"\n",
"\n",
" def send_email(self, recipient, email_object):\n",
" print(self, \"send email\", email_object, \"to\", recipient)\n",
"\n",
" def send_sms(self, recipient, sms_object):\n",
" print(self, \"send sms\", sms_object, \"to\", recipient)\n",
"\n",
"\n",
"class PDA(MessagingDevice):\n",
" \"\"\"\n",
" A personal digital assistant (PDA),\n",
" also known as a handheld PC\n",
" \"\"\"\n",
"\n",
" def send_email(self, recipient, email_object):\n",
" print(self, \"send email\", email_object, \"to\", recipient)\n",
"\n",
" def send_sms(self, recipient, sms_object):\n",
" print(self, \"send sms\", sms_object, \"to\", recipient)\n",
"```\n",
"\n",
"\n",
"\n",
"## 5. Dependency Inversion Principle\n",
"\n",
"\n",
"### 5.1 Dependency Inversion Principle violation\n",
"\n",
"```python\n",
"class LightBulb:\n",
" def turn_on(self):\n",
" print(\"LightBulb turned on\")\n",
"\n",
" def turn_off(self):\n",
" print(\"LightBulb turned off\")\n",
"\n",
"\n",
"class PowerSwitch:\n",
" def __init__(self, light_bulb: LightBulb):\n",
" self.light_bulb = light_bulb\n",
" self.on = False\n",
"\n",
" def toggle(self):\n",
" if self.on:\n",
" self.light_bulb.turn_off()\n",
" self.on = False\n",
" else:\n",
" self.light_bulb.turn_on()\n",
" self.on = True\n",
"```\n",
"\n",
"### 5.2 Following the Dependency Inversion Principle\n",
"\n",
"\n",
"```python\n",
"\n",
"# Creating an abstraction\n",
"\n",
"from abc import abstractmethod\n",
"\n",
"\n",
"class Switchable:\n",
" @abstractmethod\n",
" def turn_on(self):\n",
" pass\n",
"\n",
" @abstractmethod\n",
" def turn_off(self):\n",
" pass\n",
"\n",
"\n",
"# Implementing the Switchable interface\n",
"\n",
"class LightBulb(Switchable):\n",
" def turn_on(self):\n",
" print(\"LightBulb turned on\")\n",
"\n",
" def turn_off(self):\n",
" print(\"LightBulb turned off\")\n",
"\n",
"\n",
"class PowerSwitch:\n",
" def __init__(self, client: Switchable):\n",
" if not isinstance(client, Switchable):\n",
" raise TypeError(\"expected Switchable, got\", client)\n",
"\n",
" self.client = client\n",
" self.on = False\n",
"\n",
" def toggle(self):\n",
" if self.on:\n",
" self.client.turn_off()\n",
" self.on = False\n",
" else:\n",
" self.client.turn_on()\n",
" self.on = True\n",
"```"
]
},
{
"cell_type": "code",
"execution_count": null,
"outputs": [],
"source": [],
"metadata": {
"collapsed": false
}
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3 (ipykernel)",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.11.2"
}
},
"nbformat": 4,
"nbformat_minor": 1
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment