Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
SlideShare a Scribd company logo
Закон Деметры
Лекция 3
GRASP
General Responsibility Assignment Software Patterns
● Polymorphism
● Low Coupling
● High Cohesion
● …
● Information Expert
● Creator
● Controller
● Pure Fabrication
● ...
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]
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]
Low coupling, high cohesion
High coupling, low cohesion Low coupling, high cohesion
Law of Demeter
My vassal's vassal is not my vassal
(Вассал моего вассала - не мой вассал)
Law of Demeter
My vassal's vassal is not my vassal
(Вассал моего вассала - не мой вассал)
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
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
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()
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
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)
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)
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
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)
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
The end

More Related Content

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

  • 2. GRASP General Responsibility Assignment Software Patterns ● Polymorphism ● Low Coupling ● High Cohesion ● … ● Information Expert ● Creator ● Controller ● Pure Fabrication ● ...
  • 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. Low coupling, high cohesion High coupling, low cohesion Low coupling, high cohesion
  • 6. Law of Demeter My vassal's vassal is not my vassal (Вассал моего вассала - не мой вассал)
  • 7. Law of Demeter My vassal's vassal is not my vassal (Вассал моего вассала - не мой вассал)
  • 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. 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. 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. 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. 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. 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. 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. 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. 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