2. SOLID principles
S SRP
O OCP
L LSP
I ISP
D DIP
Single Responsibility Principle
Open-Close Principle
Liskov Substitution Principle
Interface Segregation Principle
Dependency Inversion Principle
3. class ILampSwitcher:
def switch(self, on_off):
pass
def is_on(self):
return self.light_on
class DaylightLamp(ILampSwitcher):
pass
class TableLamp(ILampSwitcher):
pass
Liskov Substitution Principle (LSP)
ILampSwitcher
TableLampDaylightLamp
+switch(on_off: bool)
+is_on(): bool
6. def turn_all_on(lamps):
for lamp in lamps:
lamp.switch(True)
l1 = DaylightLamp()
l2 = DaylightLamp()
l3 = TableLamp()
l4 = TableLamp()
turn_all_on([l1, l2]) # OK
turn_all_on([l3, l4]) # Exception
Liskov Substitution Principle (LSP)
class DaylightLamp(ILampSwitcher):
def switch(self, on_off):
self.light_on = on_off
7. def turn_all_on(lamps):
for lamp in lamps:
lamp.switch(True)
l1 = DaylightLamp()
l2 = DaylightLamp()
l3 = TableLamp()
l4 = TableLamp()
turn_all_on([l1, l2]) # OK
turn_all_on([l3, l4]) # Exception
Liskov Substitution Principle (LSP)
class DaylightLamp(ILampSwitcher):
def switch(self, on_off):
self.light_on = on_off
class TableLamp(ILampSwitcher):
def switch(self, on_off):
# debug
f = open("c:v_pupkintmp.txt", 'w')
f.write("Lamp state: " + str(self.is_on()))
self.light_on = on_off
8. l1 = DaylightLamp()
l2 = DaylightLamp()
l3 = TableLamp()
l4 = TableLamp()
turn_all_on([l1, l2]) # OK
turn_all_on([l1, l2]) # OK
turn_all_on([l3, l4]) # OK
turn_all_on([l3, l4]) # Exception
Liskov Substitution Principle (LSP)
class DaylightLamp(ILampSwitcher):
def switch(self, on_off):
...
class TableLamp(ILampSwitcher):
def switch(self, on_off):
...
9. l1 = DaylightLamp()
l2 = DaylightLamp()
l3 = TableLamp()
l4 = TableLamp()
turn_all_on([l1, l2]) # OK
turn_all_on([l1, l2]) # OK
turn_all_on([l3, l4]) # OK
turn_all_on([l3, l4]) # Exception
Liskov Substitution Principle (LSP)
class DaylightLamp(ILampSwitcher):
def switch(self, on_off):
self.light_on = on_off
class TableLamp(ILampSwitcher):
def switch(self, on_off):
if self.light_on and on_off:
raise Exception("Already on.")
if not self.light_on and not on_off:
raise Exception("Already off.")
self.light_on = on_off
10. class ILampSwitcher:
# Switches on or off.
# No throw of exceptions.
def switch(self, on_off):
pass
# Returns is lamp on.
# No throw of exceptions.
def is_on(self):
return self.light_on
# Blinks every interval (ms) if turned on.
# Throws NotSupportedException if lamp can't do this.
def blink(interval):
pass
Keeping contracts == obey LSP
class DaylightLamp(ILampSwitcher):
def switch(self, on_off):
self.light_on = on_off
def blink(interval):
raise NotSupportedException()