Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

Принципы и практики разработки ПО 2 / Principles and practices of software development 2

15 views

Published on

In this lecture I'm talking about Liskov Substitution Principle.

Published in: Technology
  • Be the first to comment

  • Be the first to like this

Принципы и практики разработки ПО 2 / Principles and practices of software development 2

  1. 1. Принципы и практики разработки ПО Лекция 2
  2. 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. 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
  4. 4. def turn_all_on(lamps): for lamp in lamps: lamp.switch(True) l1 = DaylightLamp() l2 = DaylightLamp() l3 = TableLamp() l4 = TableLamp() Liskov Substitution Principle (LSP) TableLampDaylightLamp ILampSwitcher +switch(on_off: bool) +is_on(): bool
  5. 5. 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) TableLampDaylightLamp ILampSwitcher +switch(on_off: bool) +is_on(): bool
  6. 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. 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. 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. 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. 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()
  11. 11. class IMultiLampSwitcher: def switch(self, idx, on_off: bool): pass def switch_all(self, on_off: bool): pass Contracts, interface consistency and LSP
  12. 12. class IMultiLampSwitcher: def switch(self, idx, on_off: bool): pass def switch_all(self, on_off: bool): pass class MultiLamp(IMultiLampSwitcher): def __init__(self, lamps_count): self.lamps_count = lamps_count self.lamps = [False] * lamps_count def switch(self, idx, on_off: bool): self.lamps[idx] = on_off def switch_all(self, on_off: bool): for idx in range(self.lamps_count): self.lamps[idx] = on_off Contracts, interface consistency and LSP
  13. 13. class IMultiLampSwitcher: def switch(self, idx, on_off: bool): pass def switch_all(self, on_off: bool): pass class MultiLamp(IMultiLampSwitcher): def __init__(self, lamps_count): self.lamps_count = lamps_count self.lamps = [False] * lamps_count def switch(self, idx, on_off: bool): self.lamps[idx] = on_off def switch_all(self, on_off: bool): for idx in range(self.lamps_count): self.lamps[idx] = on_off Contracts, interface consistency and LSP class SmartOfficeLamp(MultiLamp): def __init__(self): super(SmartOfficeLamp, self).__init__(3) self.switching_times = [0] * 3 def switch(self, idx, on_off: bool): super(SmartOfficeLamp, self).switch(idx, on_off) def switch_all(self, on_off: bool): super(SmartOfficeLamp, self).switch_all(on_off)
  14. 14. Contracts, interface consistency and LSP IMultiLampSwitcher MultiLamp +switch(idx:int, on_off: bool) +switch_all(on_off:bool) SmartOfficeLamp +switch(idx:int, on_off: bool) +switch_all(on_off:bool) +switch(idx:int, on_off: bool) +switch_all(on_off:bool)
  15. 15. class MultiLamp(IMultiLampSwitcher): def switch(self, idx, on_off: bool): self.lamps[idx] = on_off def switch_all(self, on_off: bool): for idx in range(self.lamps_count): self.lamps[idx] = on_off Contracts, interface consistency and LSP class SmartOfficeLamp(MultiLamp): def switch(self, idx, on_off: bool): super(SmartOfficeLamp, self).switch(idx, on_off) def switch_all(self, on_off: bool): super(SmartOfficeLamp, self).switch_all(on_off)
  16. 16. class MultiLamp(IMultiLampSwitcher): def switch(self, idx, on_off: bool): self.lamps[idx] = on_off def switch_all(self, on_off: bool): for idx in range(self.lamps_count): self.lamps[idx] = on_off Contracts, interface consistency and LSP class SmartOfficeLamp(MultiLamp): def switch(self, idx, on_off: bool): if on_off != self.lamps[idx]: self.switching_times[idx] += 1 super(SmartOfficeLamp, self).switch(idx, on_off) def switch_all(self, on_off: bool): for idx in range(self.lamps_count): if on_off != self.lamps[idx]: self.switching_times[idx] += 1 super(SmartOfficeLamp, self).switch_all(on_off)
  17. 17. class MultiLamp(IMultiLampSwitcher): def switch(self, idx, on_off: bool): self.lamps[idx] = on_off def switch_all(self, on_off: bool): for idx in range(self.lamps_count): self.lamps[idx] = on_off l = SmartOfficeLamp() print(l.lamps) # [False, False, False] print(l.switching_times) # [0, 0, 0] l.switch_all(True) print(l.lamps) # [True, True, True] print(l.switching_times) # [1, 1, 1] Contracts, interface consistency and LSP class SmartOfficeLamp(MultiLamp): def switch(self, idx, on_off: bool): if on_off != self.lamps[idx]: self.switching_times[idx] += 1 super(SmartOfficeLamp, self).switch(idx, on_off) def switch_all(self, on_off: bool): for idx in range(self.lamps_count): if on_off != self.lamps[idx]: self.switching_times[idx] += 1 super(SmartOfficeLamp, self).switch_all(on_off)
  18. 18. class MultiLamp(IMultiLampSwitcher): def switch(self, idx, on_off: bool): self.lamps[idx] = on_off def switch_all(self, on_off: bool): for idx in range(self.lamps_count): # self.lamps[idx] = on_off self.switch(idx, on_off) l = SmartOfficeLamp() print(l.lamps) # [False, False, False] print(l.switching_times) # [0, 0, 0] l.switch_all(True) print(l.lamps) print(l.switching_times) Contracts, interface consistency and LSP class SmartOfficeLamp(MultiLamp): def switch(self, idx, on_off: bool): if on_off != self.lamps[idx]: self.switching_times[idx] += 1 super(SmartOfficeLamp, self).switch(idx, on_off) def switch_all(self, on_off: bool): for idx in range(self.lamps_count): if on_off != self.lamps[idx]: self.switching_times[idx] += 1 super(SmartOfficeLamp, self).switch_all(on_off)
  19. 19. class MultiLamp(IMultiLampSwitcher): def switch(self, idx, on_off: bool): self.lamps[idx] = on_off def switch_all(self, on_off: bool): for idx in range(self.lamps_count): # self.lamps[idx] = on_off self.switch(idx, on_off) l = SmartOfficeLamp() print(l.lamps) # [False, False, False] print(l.switching_times) # [0, 0, 0] l.switch_all(True) print(l.lamps) # [True, True, True] print(l.switching_times) # [2, 2, 2] Contracts, interface consistency and LSP class SmartOfficeLamp(MultiLamp): def switch(self, idx, on_off: bool): if on_off != self.lamps[idx]: self.switching_times[idx] += 1 super(SmartOfficeLamp, self).switch(idx, on_off) def switch_all(self, on_off: bool): for idx in range(self.lamps_count): if on_off != self.lamps[idx]: self.switching_times[idx] += 1 super(SmartOfficeLamp, self).switch_all(on_off)
  20. 20. class IMultiLampSwitcher: def switch(self, idx, on_off: bool): pass def switchers_count(self): pass @staticmethod def switch_all(multi_lamp_switcher, on_off): cnt = multi_lamp_switcher.switchers_count() for idx in range(cnt): multi_lamp_switcher.switch(idx, on_off) Contracts, interface consistency and LSP
  21. 21. class IMultiLampSwitcher: def switch(self, idx, on_off: bool): pass def switchers_count(self): pass @staticmethod def switch_all(multi_lamp_switcher, on_off): cnt = multi_lamp_switcher.switchers_count() for idx in range(cnt): multi_lamp_switcher.switch(idx, on_off) Contracts, interface consistency and LSP class MultiLamp(IMultiLampSwitcher): def switch(self, idx, on_off: bool): self.lamps[idx] = on_off def switchers_count(self): return self.lamps_count
  22. 22. class IMultiLampSwitcher: def switch(self, idx, on_off: bool): pass def switchers_count(self): pass @staticmethod def switch_all(multi_lamp_switcher, on_off): cnt = multi_lamp_switcher.switchers_count() for idx in range(cnt): multi_lamp_switcher.switch(idx, on_off) Contracts, interface consistency and LSP class MultiLamp(IMultiLampSwitcher): def switch(self, idx, on_off: bool): self.lamps[idx] = on_off def switchers_count(self): return self.lamps_count class SmartOfficeLamp(MultiLamp): def switch(self, idx, on_off: bool): if on_off != self.lamps[idx]: self.switching_times[idx] += 1 super(SmartOfficeLamp, self).switch(idx, on_off) l = SmartOfficeLamp() IMultiLampSwitcher.switch_all(l, True)
  23. 23. The end

×