neiron94 / Smart-Home-Simulation

Repo for OMO semestral project
MIT License
1 stars 1 forks source link

Design Patterns #4

Open ArtLmkn opened 9 months ago

ArtLmkn commented 9 months ago

DESIGN PATTERNS

Implemented

neiron94 commented 9 months ago

VISITOR

https://refactoring.guru/design-patterns/visitor


Element - consumer.Consumer accept() = consumer.Consumer.accept()

Element A - consumer.ElectricityConsumer Element B - consumer.WaterConsumer Element C - consumer.GasConsumer

Visitor (interface) - consumer.Visitor visit() = consume.Visitor.visit() - controls Element type

ConcreteVisitor A - consumer.AddVisitor visit(Element A) = consume.AddVisitor.visit(ElectricityConsumer) visit(Element B) = consume.AddVisitor.visit(WaterConsumer) visit(Element C) = consume.AddVisitor.visit(GasConsumer) Visitor feature - add consumer device to all places (Simulation + proper SupplySystem)

ConcreteVisitor B - consumer.DeleteVisitor visit(Element A) = consume.DeleteVisitor.visit(ElectricityConsumer) visit(Element B) = consume.DeleteVisitor.visit(WaterConsumer) visit(Element C) = consume.DeleteVisitor.visit(GasConsumer) Visitor feature - delete consumer device from all places (Simulation + proper SupplySystem)

ConcreteVisitor C - consumer.ConsumeVisitor visit(Element A) = consume.ConsumeVisitor.visit(ElectricityConsumer) visit(Element B) = consume.ConsumeVisitor.visit(WaterConsumer) visit(Element C) = consume.ConsumeVisitor.visit(GasConsumer) Visitor feature - make device consumption and write it to proper SupplySystem

ConcreteVisitor D - consumer.EventVisitor visit(Element A) = consume.EventVisitor.visit(ElectricityConsumer) visit(Element B) = consume.EventVisitor.visit(WaterConsumer) visit(Element C) = consume.EventVisitor.visit(GasConsumer) Visitor feature - creates disaster events (fire/flood/leak) for proper consumer


neiron94 commented 9 months ago

MEMENTO

https://www.baeldung.com/java-memento-design-pattern


Memento - place.RoomConfiguration

Originator - place.ControlPanel save() = saveConfiguration() restore() = loadConfiguration()

Caretaker - creature.person.Person hitSave() = room.getControlPanel.saveConfiguration() hitUndo() = room.getControlPanel.loadConfiguration()

state - prefered temperature, humidity, brightness and light color (fields in the ControlPanel). State is saved in static field in ControlPanel.


ArtLmkn commented 9 months ago

PROTOTYPE

https://refactoring.guru/design-patterns/prototype


Prototype (interface) - utils.Prototype

ConcretePrototype - place.RoomConfiguration clone() = place.RoomConfiguration.copy()


Prototype (interface) - utils.Prototype

ConcretePrototype - consumer.device.Device (+ all inheritors) clone() = consumer.device.Device.clone() (+ all inheritors)


ArtLmkn commented 9 months ago

BUILDER

https://refactoring.guru/design-patterns/builder


Client - smarthome.Simulation

Concrete Builder - place.HomeBuilder reset() = place.HomeBuilder.reset() getResult() = place.HomeBuilder.getHome() buildStepA() = place.HomeBuilder.buildHome() buildStepB() = place.HomeBuilder.buildFloor() buildStepC() = place.HomeBuilder.buildRoom()

There is no need in program in Builder interface as long as there is only one type of Home creating. We don't also need a Director class because this role is played by home draft readed from configuration file.


ArtLmkn commented 9 months ago

ABSTRACT FACTORY

https://refactoring.guru/design-patterns/abstract-factory


AbstractFactory - report.factoty.ReportFactory createProduc() = report.factoty.ReportFactory.createReport()

ConcreteFactory1 - report.factory.ConfigurationReportFactory createProduct() = report.factory.ConfigurationReportFactory.createReport()

ConcreteFactory2 - report.factory.ConsumptionReportFactory createProduct() = report.factory.ConsumptionReportFactory.createReport()

ConcreteFactory3 - report.factory.ActivityReportFactory createProduct() = report.factory.ActivityReportFactory.createReport()

ConcreteFactory4 - report.factory.EventReportFactory createProduct() = report.factory.EventReportFactory.createReport()

AbstractProduct - report.Report ConcreteProduct1 - report.ConfigurationReport ConcreteProduct2 - report.ConsumptionReport ConcreteProduct3 - report.ActivityReport ConcreteProduct4 - report.EventReport

Client - report.ReportCreator someOperationA() = report.ReportCreator.createConfigurationReport() someOperationB() = report.ReportCreator.createConsumptionReports() someOperationC() = report.ReportCreator.createActivityReports() someOperationD() = report.ReportCreator.createEventReports()


ArtLmkn commented 9 months ago

SINGLETON

https://refactoring.guru/design-patterns/singleton


Singleton - smarthome.Simulation

Client - smarthome.SmartHome and so on


Singleton - place.Street

Client - smarthome.Simulation and so on


ArtLmkn commented 9 months ago

FACADE

https://refactoring.guru/design-patterns/facade


Client A - smarthome.Simulation Client B - place.HomeBuilder Client C - place.ControlPanel, Client D - consumer.device.common.entertainment.EntertainmentService Client E - place.Street

Facade - utils.ConfigurationReader utils.ConfigurationReader.readSimulationConfig() - (A) utils.ConfigurationReader.readHomeConfig() - (B) utils.ConfigurationReader.readDeviceConfig() - (A) utils.ConfigurationReader.readCreatureConfig() - (A) utils.ConfigurationReader.readRoomConfigurationConfig() - (C) utils.ConfigurationReader.readContentConfig() - (D) utils.ConfigurationReader.readWeatherConfig() - (E)

Facade provides working with JSON files. Inside it reads, parse them and creates objects depending on configuration info or sets different parameters.


Client - smarthome.Simulation

Facade - report.ReportCreator report.ReportCreator.createReports() report.ReportCreator.createConfigurationReport()

Facade provides reports creation. Inside it collects all necessary information, creates reports and writes it into files.


ArtLmkn commented 9 months ago

SIMPLE FACTORY

https://dragonprogrammer.com/design-patterns-java-simple-factory/


Client - utils.ConfigurationReader

Factory - creature.CreatureFactory creature.CreatureFactory.createPerson() creature.CreatureFactory.createPet()

Factory provides Creature creations. Hidden complexity is control of validity of given parameters.


Client - utils.ConfigurationReader

Factory - consumer.device.DeviceFactory consumer.device.DeviceFactory.createDevice()

Factory provides Device creations. Hidden complexity is control of validity of given parameters.


Client - utils.ConfigurationReader

Factory - consumer.device.common.entertainment.EntertainmentFactory consumer.device.common.entertainment.EntertainmentFactory.createSong() consumer.device.common.entertainment.EntertainmentFactorycreateVideo() consumer.device.common.entertainment.EntertainmentFactory.createGame()

Factory provides Song, Video, Game creations. Hidden complexity is control of validity of given parameters.


ArtLmkn commented 9 months ago

STRATEGY

https://refactoring.guru/design-patterns/strategy


Strategy (interface) - event.throwStrategy.EventThrowStrategy ConcreteStrategy A - event.throwStrategy.HomeThrowStrategy ConcreteStrategy B - event.throwStrategy.FloorThrowStrategy ConcreteStrategy C - event.throwStrategy.RoomThrowStrategy execute() = event.throwStrategy.EventThrowStrategy.throwEvent()

Client - consumer.device.Device

Context - event.Event doSomething() = event.Event.throwEvent() setStrategy() is missing because it sets in constructor


Strategy (interface) - creature.strategy.Strategy ConcreteStrategy A - creature.strategy.ManStrategy ConcreteStrategy B - creature.strategy.WomanStrategy ConcreteStrategy C - creature.strategy.ChildStrategy ConcreteStrategy D - creature.strategy.DogStrategy ConcreteStrategy E - creature.strategy.CatStrategy ConcreteStrategy F - creature.strategy.SomePetStrategy execute() = creature.strategy.Strategy.react()

Client A - creature.person.Person Client B - creature.pet.Pet

Context - creature.Creature doSomething() is used in Creature routine function setStrategy() is missing because strategies sets in creatures' constructors


ArtLmkn commented 9 months ago

TEMPLATE METHOD

https://refactoring.guru/design-patterns/template-method


AbstractClass - creature.Creature templateMethod() = creature.Creature.routine() step1() (abstract) = creature.Creature.decreaseFullness() step2() (abstract) = creature.Creature.decreaseHunger() step3() (abstract) = creature.Creature.chooseActivity() step4() (abstract) = creature.Creature.reactMaxFullness() step5() = creature.Creature.reactMaxHunger()

ConcreteClass1 - creature.person.Person step1() = creature.person.Person.decreaseFullness() step2() = creature.person.Person.decreaseHunger() step3() = creature.person.Person.chooseActivity() step4() = creature.person.Person.reactMaxFullness()

ConcreteClass2 - creature.pet.Pet step1() = creature.pet.Pet.decreaseFullness() step2() = creature.pet.Pet.decreaseHunger() step3() = creature.pet.Pet.chooseActivity() step4() = creature.pet.Pet.reactMaxFullness()


ArtLmkn commented 9 months ago

OBSERVER

https://refactoring.guru/design-patterns/observer


Publisher - consumer.SupplySystem subscribers = consumer.SupplySystem.consumedMap subscribe() = consumer.SupplySystem.addConsumer() unsubscribe() = consumer.SupplySystem.deleteConsumer() notifySubscribers() = consumer.SupplySystem.switchRoom() Subscribers are keys (Devices) in map with consumed resource value. Notification calls different subscriber functions depends on notify function parameter.

Subscriber A - consumer.ElectricityConsumer Subscriber B - consumer.WaterConsumer Subscriber C - consumer.GasConsumer ConcreteSubscriber - consumer.device.Device update() = consumer.device.Device.turnOn() update() = consumer.device.Device.turnOff() Concrete subscribers are all devices (depends on what resource they consume).


ArtLmkn commented 8 months ago

STATE

https://refactoring.guru/design-patterns/state

State - place.weather.Weather ConcreteState A - place.weather.NormalWeather ConcreteState B - place.weather.SunnyWeather ConcreteState C - place.weather.CloudyWeather ConcreteState D - place.weather.RainyWeather ConcreteState E - place.weather.WindyWeather doThis() = place.weather.Weather.applyWeather() There is no need in setContext() because context is Singleton.

Context - place.Street changeState() = place.Street.setWeather() There is no need in explicit doThis() - context uses applyWeather() and changeWeather() of its state. InitialState is random Weather.

ArtLmkn commented 8 months ago

ADAPTER

https://refactoring.guru/design-patterns/adapter

Client - java.util.TreeSet

Service - java.util.Deque

Adapter - utils.RankedQueue

In the program Creature is need to work with its sequences of future actions (called memory). Those sequences have different priorities (what should be done next). Also implementation requires to have ability in iteration by action sequences. For this reason TreeSet is used (is easily iterable + can add elements respecting priorities). Every element of memory should be specific action sequence. That's why adapter was implemented to store those action sequences and its priority to let TreeSet work with it later.