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.

Закон Деметры / Demetra's law

12 views

Published on

Presentation about why it is dangerous to violate the Demetra's law in software development.

This is the third talk I gave at 2GIS internal meetup.

Published in: Technology
  • Be the first to comment

  • Be the first to like this

Закон Деметры / Demetra's law

  1. 1. Закон Деметры Лекция 3
  2. 2. GRASP General Responsibility Assignment Software Patterns ● Polymorphism ● Low Coupling ● High Cohesion ● … ● Information Expert ● Creator ● Controller ● Pure Fabrication ● ...
  3. 3. Polymorphism ILamp DaylightLamp constructor(supported_colors:[color]) +get_supported_colors(): [color] +set_intensity(int) +get_intensity(): int +set_color(string) +get_color(): string ColoredLamp white white, blue, green, red ~ supported_colors_: [color]
  4. 4. Polymorphism ILamp DaylightLamp +get_supported_colors(): [color] +set_intensity(int) +get_intensity(): int +set_color(string) +get_color(): string ILamp DaylightLamp constructor(supported_colors:[color]) +get_supported_colors(): [color] +set_intensity(int) +get_intensity(): int +set_color(string) +get_color(): string ColoredLamp white white, blue, green, red +get_supported_colors(): return [white] ~ supported_colors_: [color] DaylightLamp +get_supported_colors(): return [white, red, blue, green]
  5. 5. Low coupling, high cohesion High coupling, low cohesion Low coupling, high cohesion
  6. 6. Law of Demeter My vassal's vassal is not my vassal (Вассал моего вассала - не мой вассал)
  7. 7. Law of Demeter My vassal's vassal is not my vassal (Вассал моего вассала - не мой вассал)
  8. 8. IRoom constructor(max_lamps: dict) +calculate_payment(): float +add_lamp(lamp_type=daylight) +get_lamps(): dict +is_lamp_allowed(lamp_type): bool ~ max_lamps_: dict(lamp_type, int) ~ lamps_: dict(lamp_type, ILamp) IFloor constructor(rooms: [IRoom]) +get_rooms(): [IRoom] ~ rooms_: [IRoom] ILamp constructor(supported_colors:[color]) +get_supported_colors(): [color] +set_intensity(int) +get_intensity(): int +set_color(string) +get_color(): string ~ supported_colors_: [color] IFloorLampPolicy +evaluate(is_day: bool) +switch_all(color: color, intensity: int) +get_floor(): IFloor +set_floor(floor: IFloor) ~ floor_: IFloor Law of Demeter
  9. 9. Law of Demeter IFloorLampPolicy +evaluate(is_day: bool) +get_floor(): IFloor +set_floor(floor: IFloor) ~ floor_: IFloor class IFloorLampPolicy: def evaluate(self, is_day: bool): pass class CurfewPolicy(IFloorLampPolicy): def evaluate(self, is_day: bool): if is_day: return # Turn all light off in the floor for room in self.get_floor().get_rooms(): for _, lamps in room.get_lamps().items(): for lamp in lamps: lamp.set_color(white) lamp.set_intensity(0) CurfewPolicy
  10. 10. Law of Demeter IFloorLampPolicy +evaluate(is_day: bool) +get_floor(): IFloor +set_floor(floor: IFloor) ~ floor_: IFloor class IFloorLampPolicy: def evaluate(self, is_day: bool): pass class CurfewPolicy(IFloorLampPolicy): def evaluate(self, is_day: bool): if is_day: return # Turn all light off in the floor for room in self.get_floor().get_rooms(): for _, lamps in room.get_lamps().items(): for lamp in lamps: lamp.set_color(white) lamp.set_intensity(0) CurfewPolicy Law of Demeter violation (High Coupling): get_floor() -> get_rooms() -> get_lamps()
  11. 11. Law of Demeter violation IFloorLampPolicy +get_floor(): IFloor ~ floor_: IFloor IRoom +get_lamps(): dict ~ lamps_: dict(lamp_type, ILamp) IFloor +get_rooms(): [IRoom] ~ rooms_: [IRoom] ILamp
  12. 12. Law of Demeter violation problems IFloor constructor(rooms: [IRoom]) +get_rooms(): [IRoom] ~ rooms_: [IRoom] IFloor constructor(rooms: [IRoom], corridor: IRoom) +get_rooms(): [IRoom] +get_corridor(): IToom ~ rooms_: [IRoom] ~ corridor_: IRoom class IFloorLampPolicy: def evaluate(self, is_day: bool): pass class CurfewPolicy(IFloorLampPolicy): def evaluate(self, is_day: bool): if is_day: return # Turn all light off in the floor for room in self.get_floor().get_rooms(): for _, lamps in room.get_lamps().items(): for lamp in lamps: lamp.set_color(white) lamp.set_intensity(0)
  13. 13. Law of Demeter violation problems IFloor constructor(rooms: [IRoom]) +get_rooms(): [IRoom] ~ rooms_: [IRoom] IFloor constructor(rooms: [IRoom], corridor: IRoom) +get_rooms(): [IRoom] +get_corridor(): IToom ~ rooms_: [IRoom] ~ corridor_: IRoom class IFloorLampPolicy: def evaluate(self, is_day: bool): pass class CurfewPolicy(IFloorLampPolicy): def evaluate(self, is_day: bool): if is_day: return # Turn all light off in the floor for room in self.get_floor().get_rooms(): for _, lamps in room.get_lamps().items(): for lamp in lamps: lamp.set_color(white) lamp.set_intensity(0)
  14. 14. Avoiding Law of Demeter violation IRoom +get_lamps(): dict +apply_action(action: LampAction) ~ lamps_: dict(lamp_type, ILamp) IFloor +get_rooms(): [IRoom] +apply_action(action: LampAction) ~ rooms_: [IRoom] ILamp IFloorLampPolicy +get_floor(): IFloor ~ floor_: IFloor ILampAction +evaluate(lamp: ILamp) LampOff
  15. 15. Avoiding Law of Demeter violation class IRoom: def apply_action(self, action: ILampAction): for lamp_type, lamps in self.lamps_.items(): for lamp in lamps: action.evaluate(lamp) class IFloor: def apply_action(self, action: ILampAction): for room in self.rooms_: room.apply_action(action) self.corridor_.apply_action(action) class CurfewPolicy(IFloorLampPolicy): def evaluate(self, is_day: bool): if is_day: return floor = self.get_floor() floor.apply_action(LampOff()) class ILampAction: def evaluate(self, lamp: ILamp): pass class LampOff(ILampAction): def evaluate(self, lamp: ILamp): lamp.set_color(white) lamp.set_intensity(0) class LampOn(ILampAction): def evaluate(self, lamp: ILamp): lamp.set_intensity(100) class RedLampOff(ILampAction): def evaluate(self, lamp: ILamp): if lamp.get_color() == red: lamp.set_intensity(0)
  16. 16. Avoiding Law of Demeter violation IRoom +get_lamps(): dict +apply_action(action: ILampAction) ~ lamps_: dict(lamp_type, ILamp) IFloor +get_rooms(): [IRoom] +apply_action(action: IRoomAction) ~ rooms_: [IRoom] ILampILampAction +evaluate(lamp: ILamp) IRoomAction +evaluate(room: IRoom) IFloorLampPolicy +get_floor(): IFloor ~ floor_: IFloor
  17. 17. The end

×