🔧 AI Nachrichten Major AI platforms go down in unprecedented simultaneous outage(03.09.2026 um 17:34 Uhr)
🔧 AI Nachrichten ChatGPT, Claude, and Grok Down? Users Report Widespread Outages(03.09.2026 um 19:14 Uhr)
🔧 AI Nachrichten OpenAI Launches GPT-6 Astra, Says We May Have Entered the AGI Era(03.09.2026 um 22:08 Uhr)
🔧 AI Nachrichten Claude Comes to CarPlay as Fifth Major AI Chatbot App(05.09.2026 um 05:31 Uhr)
🔧 AI Nachrichten OpenAI’s GPT-6 Astra Is AGI, Says NVIDIA CEO Jensen Huang(07.09.2026 um 06:31 Uhr)
🔧 AI Nachrichten Blame AI companies for Mac mini and Mac Studio shortage(31.08.2026 um 10:32 Uhr)
🔧 AI Nachrichten Major AI platforms go down in unprecedented simultaneous outage(03.09.2026 um 17:34 Uhr)
🔧 AI Nachrichten ChatGPT, Claude, and Grok Down? Users Report Widespread Outages(03.09.2026 um 19:14 Uhr)
🔧 AI Nachrichten OpenAI Launches GPT-6 Astra, Says We May Have Entered the AGI Era(03.09.2026 um 22:08 Uhr)
🔧 AI Nachrichten Claude Comes to CarPlay as Fifth Major AI Chatbot App(05.09.2026 um 05:31 Uhr)
🔧 AI Nachrichten OpenAI’s GPT-6 Astra Is AGI, Says NVIDIA CEO Jensen Huang(07.09.2026 um 06:31 Uhr)
🔧 AI Nachrichten Blame AI companies for Mac mini and Mac Studio shortage(31.08.2026 um 10:32 Uhr)

🔧 Programmierung 🕛 kürzlich 9 Min Lesezeit
0

SOLID Design Principles: Stop Writing Code That Breaks When You Touch It

↗ Quelle (dev.to)
🗣️ Stimme:
📑 Inhaltsübersicht

Guidelines, not rules. Here's the difference — and why it matters.









What is SOLID?



SOLID is a set of software design guidelines — not hard rules, but principles that guide how we organize our code.



The goal is simple: as your codebase grows and your team scales, things should get easier to change, not harder. SOLID is what makes that possible.



Five principles. One goal. Let's walk through each one with real code.









S — Single Responsibility Principle




A class, function, or method should have one and only one reason to change.







The Violation






CODE
class Bird:
def __init__(self, name: str, bird_type: str):
self.name = name
self.bird_type = bird_type

def make_sound(self):
# two jobs — deciding the type AND making the sound
if self.bird_type == "parrot":
print("Squawk!")
elif self.bird_type == "eagle":
print("Screech!")
elif self.bird_type == "owl":
print("Hoot!")
else:
print("...")






make_sound() has two responsibilities — deciding which bird type it is AND making the sound. That's two reasons to change. Add a new bird? Touch make_sound(). Change how sounds work? Touch make_sound() again. Two different reasons, one method. SRP violated.






The Fix






CODE
from abc import ABC, abstractmethod

class Bird(ABC):
def __init__(self, name: str):
self.name = name

@abstractmethod
def make_sound(self):
pass

class Parrot(Bird):
def make_sound(self):
print("Squawk!")

class Eagle(Bird):
def make_sound(self):
print("Screech!")

class Owl(Bird):
def make_sound(self):
print("Hoot!")

# Usage
birds = [Parrot("Polly"), Eagle("Sam"), Owl("Oliver")]
for bird in birds:
bird.make_sound()






Now each class has one responsibility. Parrot.make_sound() only changes if parrots change how they sound. Nothing else touches it.









O — Open/Closed Principle




A class should be open for extension but closed for modification.




SRP and OCP go hand in hand. When you fixed SRP in the Bird example above — you also fixed OCP.






The Violation






CODE
class BirdSoundService:
def make_sound(self, bird_type: str):
if bird_type == "parrot":
print("Squawk!")
elif bird_type == "eagle":
print("Screech!")
# adding a new bird = modifying this existing class






Every time a new bird arrives, you open this class and add another elif. You're modifying existing, working code. That's an OCP violation — and a regression risk.






The Fix






CODE
from abc import ABC, abstractmethod

class Bird(ABC):
@abstractmethod
def make_sound(self):
pass

class Parrot(Bird):
def make_sound(self):
print("Squawk!")

class Eagle(Bird):
def make_sound(self):
print("Screech!")

# Adding a new bird — zero changes to existing code
class Flamingo(Bird):
def make_sound(self):
print("Honk!")

class BirdSoundService:
def make_sound(self, bird: Bird):
bird.make_sound() # polymorphism handles it






New bird? New class. Existing code untouched. That's OCP.






Inheritance vs Composition



OCP can be achieved two ways — inheritance and composition. For larger codebases and larger teams, composition is safer.



Inheritance creates tight coupling. Change the parent and every subclass is potentially affected. When multiple developers are pushing code simultaneously, one change in the parent ripples through the entire hierarchy.



Composition injects behaviour instead:




CODE
class Bird:
def __init__(self, sound_behaviour):
self.sound = sound_behaviour

def make_sound(self):
self.sound.execute()

class ScreechSound:
def execute(self):
print("Screech!")

class SilentSound:
def execute(self):
print("...")

eagle = Bird(sound_behaviour=ScreechSound())
rubber_duck = Bird(sound_behaviour=SilentSound())






Swap the behaviour by swapping the object. Nothing else changes.




Inheritance defines what you are. Composition defines what you have. Prefer what you have — it's easier to change.










L — Liskov Substitution Principle




A child class should be fully substitutable for its parent. Wherever you use the parent, the child must work correctly — no surprises, no broken contracts.







The Violation






CODE
class Bird(ABC):
@abstractmethod
def fly(self):
pass

@abstractmethod
def make_sound(self):
pass

class Eagle(Bird):
def fly(self):
print("Eagle soaring high!")

def make_sound(self):
print("Screech!")

class Penguin(Bird):
def fly(self):
raise NotImplementedError("Penguins can't fly!") # ← LSP violated

def make_sound(self):
print("Squawk!")

# This breaks at runtime
def make_bird_fly(bird: Bird):
bird.fly() # works for Eagle, crashes for Penguin






Penguin extends Bird but can't honour the fly() contract. It's like a button that does nothing when you click it — the interface promises behaviour, the implementation delivers nothing. Users and callers hate this.






The Fix






CODE
from abc import ABC, abstractmethod

class Bird(ABC):
@abstractmethod
def make_sound(self):
pass

class Flyable(ABC):
@abstractmethod
def fly(self):
pass

class Eagle(Bird, Flyable):
def make_sound(self):
print("Screech!")

def fly(self):
print("Eagle soaring high!")

class Penguin(Bird):
def make_sound(self):
print("Squawk!")
# no fly() — penguins don't fly, so they don't implement Flyable

class Flamingo(Bird, Flyable):
def make_sound(self):
print("Honk!")

def fly(self):
print("Flamingo taking off!")

# Clean — only birds that can fly implement Flyable
def make_bird_fly(bird: Flyable):
bird.fly()

make_bird_fly(Eagle()) # ✅
make_bird_fly(Flamingo()) # ✅
# make_bird_fly(Penguin()) — type checker catches this at compile time






Now the contract is honest. If a class says it can fly, it actually can.









I — Interface Segregation Principle




An interface should only contain methods that are genuinely related to each other.




Notice the fix for LSP above — we moved fly() into a separate Flyable interface. That's ISP in action.






The Violation






CODE
class BirdInterface(ABC):
@abstractmethod
def make_sound(self): pass

@abstractmethod
def fly(self): pass

@abstractmethod
def dance(self): pass # ← what does dancing have to do with flying?

@abstractmethod
def swim(self): pass






Flying, dancing, and swimming are unrelated behaviours. Any class implementing BirdInterface is forced to implement all of them — even if dancing makes no sense for an eagle.



The rule: if you look at a method in an interface and think "why is this even here?" — that's ISP telling you to split.






The Fix






CODE
from abc import ABC, abstractmethod

class Bird(ABC):
@abstractmethod
def make_sound(self): pass

class Flyable(ABC):
@abstractmethod
def fly(self): pass

class Swimmable(ABC):
@abstractmethod
def swim(self): pass

class Danceable(ABC):
@abstractmethod
def dance(self): pass

# Each bird implements only what makes sense
class Eagle(Bird, Flyable):
def make_sound(self): print("Screech!")
def fly(self): print("Eagle soaring!")

class Penguin(Bird, Swimmable):
def make_sound(self): print("Squawk!")
def swim(self): print("Penguin swimming!")

class Peacock(Bird, Danceable):
def make_sound(self): print("Screech!")
def dance(self): print("Peacock dancing!")






Focused, cohesive, justified. Each interface does exactly one thing.






LSP vs ISP — Same Smell, Different Diagnosis



Both surface as a class implementing something it has no business implementing:





  • Penguin forced to implement fly()LSP says fix the hierarchy


  • BirdInterface forced to include dance()ISP says split the interface



Two sides of the same coin. Knowing which applies is what separates a good diagnosis from a guess.









D — Dependency Inversion Principle




Classes should not depend directly on each other — they should both depend on an abstraction.







The Violation






CODE
class LowFly:
def low_fly(self):
print("Flying low...")

class HighFly:
def high_fly(self):
print("Flying high!")

class Pigeon:
def __init__(self):
self.flying = LowFly() # hardcoded dependency

def fly(self):
self.flying.low_fly()

pigeon = Pigeon()
pigeon.fly() # Flying low...






Pigeon is hardcoded to LowFly. The pigeon has a RedBull and decides to fly high like an eagle. Now you're deep in the codebase changing every place LowFly was hardcoded. One decision ripples everywhere.






The Fix






CODE
from abc import ABC, abstractmethod

class DoFlying(ABC):
@abstractmethod
def fly(self): pass

class LowFly(DoFlying):
def fly(self):
print("Flying low...")

class HighFly(DoFlying):
def fly(self):
print("Flying high!")

class Pigeon:
def __init__(self, flying: DoFlying):
self.flying = flying # injected, not hardcoded

def fly(self):
self.flying.fly()

# Flying low
pigeon = Pigeon(flying=LowFly())
pigeon.fly() # Flying low...

# Pigeon had a RedBull — swap the behaviour, zero code changes
pigeon = Pigeon(flying=HighFly())
pigeon.fly() # Flying high!






Pigeon depends on the DoFlying interface — not on LowFly or HighFly directly. Both concrete classes implement the same fly() method through DoFlying. Swap the behaviour by changing one line at the call site. The Pigeon class never changes.









How They Connect



This is the question that often comes up in interviews: "How do SOLID principles relate to each other?"



Here's the connection:



SRP gives you small, focused classes. When a class does one thing, it becomes naturally easy to extend without modification — which is exactly what OCP asks for.



OCP tells you to extend via abstractions. But once you have inheritance hierarchies, LSP steps in and says: make sure your subclasses honour the parent's contract.



LSP and ISP surface the same smell — a class implementing something it has no business implementing. LSP says fix your hierarchy. ISP says fix your interface. Two sides of the same coin.



DIP is the glue that ties everything together. SRP, OCP, LSP, and ISP all tell you to create abstractions. DIP says: now depend on those abstractions, not the concretions. This is what makes everything testable, swappable, and decoupled.




SRP creates focused classes → OCP makes them extendable → LSP keeps hierarchies honest → ISP keeps interfaces clean → DIP wires it all together.










The Tradeoffs — What SOLID Costs You



SOLID is a compass, not a religion. Over-applying it leads to premature abstraction — which is its own anti-pattern.






































Principle Benefit Cost
SRP Focused, easy to change in isolation More classes, more files, more navigation
OCP Add features without breaking existing code More abstractions upfront — overkill if variants never appear
LSP Subclasses are truly interchangeable Sometimes forces flat hierarchies or abandoning inheritance
ISP Classes only know what they need Interface explosion — dozens of tiny interfaces
DIP Testable, swappable, decoupled Wiring complexity — need a composition root


Signs you've over-engineered:




  • You need to open 5 files to understand one feature

  • Interfaces all have exactly one implementation

  • New engineers can't find where the actual work happens



The rule of three: Once is a one-off. Twice is a coincidence. Three times — abstract it.






Understanding SOLID isn't about reciting five definitions. It's about knowing where each principle applies, how they connect to each other, and honestly explaining what each one costs. That's what makes the difference.

Vollständiger Original-Bericht
Ausführliche Details, Code-Beispiele & Hersteller-Stellungnahme auf dev.to.
↗ Original-Artikel auf dev.to lesen
Wie bewertest du diesen Beitrag?
1 Klick Feedback
Teilen mit Netzwerk & Team:

Community-Analysen & Experten-Meinungen 0

Verfasse deine eigene Analyse, teile Workarounds oder diskutiere diesen Vorfall im Blog.
Noch keine Community-Analyse verfasst. Markiere einen Textabschnitt oder klicke oben auf Eigene Analyse verfassen“!
Community Pulse: Relevanz-Einschätzung
1 Klick Experten-Votum
🔴 Akute Relevanz 0%
🟡 In Evaluierung 0%
🟢 Keine Auswirkung 0%
Spannende Innovation 0%
Verwandte Story-Cluster & Quellen (Vektor-KI)
Port 8095 Engine
3 Quellen
GPT-6 Astra Release Today? OpenAI’s Next Major AI Model Is Almost Here
1 Quelle
Apple accuses OpenAI of destroying evidence as trade-secrets fight intensifies
1 Quelle
Major AI platforms go down in unprecedented simultaneous outage
Ähnliche Beiträge
🔍 Verwandte News

Auch interessante Nachrichten SOLID Design Principles: Stop Writing Code That Breaks When You Touch It

Thematisch verwandte Begriffe: SOLID, Design, Principles, Stop · 6 Treffer

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...