# House of Things Project Documentation ### Authors: ``` Ana Catarina Gomes Diogo Melo Rogério Carminé Shivathanu Gopirajan Chitra ``` # Table of Contents - [Context](#context) - [Product Goals](#product-goals) - [1st Delivery](#1st-delivery) - [2nd Delivery](#2nd-delivery) - [Problems or Issues](#problems-or-issues) - [Elements of the Architecture](#elements-of-the-architecture) - [Sensor](#sensor) - [Actuator](#actuator) - [Control Unit](#control-unit) - [Rules](#rules) - [Condition](#condition) - [Action](#action) - [Event](#event) - [Commands](#commands) - [Class Diagram](#class-diagram) - [Reusable Design Patterns Chosen for the Project](#reusable-design-patterns-chosen-for-the-project) - [Bridge](#different-actuators) - [Command ](#support-the-execution-of-different-actuators) - [Mediator](#communication-between-classes-may-become-more-complex) - [Observer](#coupling-between-dependent-objects-is-not-flexible) - [Composite](#actions-that-trigger-more-than-one-actuator) - [Adapter](#integrate-incompatible-interfaces-to-work-together) - [Template](#different-events-detected-by-sensors) - [Null Object](#events-that-trigger-no-action) - [Strategy and Factory](#conditions-have-to-deal-with-different-events-and-check-if-they-meet-the-conditions-criteria) - [State](#the-actuators-should-remember-their-state) - [Issues regarding the development of User Interface Elements](#issues-regarding-the-development-of-user-interface-elements) - [Model View Controller](#separation-of-the-implementation-and-the-user-interface) - [Template](#various-controller-classes-need-to-interact-with-the-user-using-the-same-operations) - [Command](#call-all-different-controllers-in-the-same-way) - [Composite](#if-system-can-have-more-than-one-control-unit-how-would-the-controller-handle-it) - [Strategy and Factory](#controllers-dealing-with-different-events-and-commands) - [Conclusion](#conclusion) - [Problems Solved](#problems-solved) - [System Evolution](#system-evolution) - [Intimacy with design patterns](#intimacy-with-design-patterns) - [Appendix-I](#appendix-i) ## Context We researched about home automation systems and we based our reasoning on information about Alexa's smart home functionality, Amazon's personal assistant. The system has three main actors: * The *Sensors*, whose function is to gather information about the environment. * The *Actuators*, whose function is to interact with the environment. * The *Control Unit*, which is the system where the *Sensors* and *Actuators* are connected. The true value of an automated system resides on the fact that changes on the environment, read by the *Sensors*, can trigger *Actuators* to interact with that environment. For that, we created *Rules*, that allow the mapping of certain event conditions to trigger a certain Actuator or Actuators. ## Product Goals The requirements we are aiming to fulfill in this project are as follows: * Support different kind of Sensor readings (boolean, incremental, spacial aware). * Support interaction with different kinds of *Actuators* (on/off, channel switching, incremental, spacial aware). * Be compatible with different types of devices, by using common interfaces (on/off, channel switching, incremental, spacial aware). * Add actions to the system (if X reading happens in a sensor, then trigger Y *Actuator(s)*). * Work in simulator mode: sensor readings manually input into the system and virtual *Actuators* displaying messages. * Easily connect new devices to the existing interfaces. * Use well known messaging systems as input and output of the system. * Have a GUI or Command line interface. ## 1st Delivery * In the first delivery we focus on the main function of the HOT system: the implementation of the *Actions*, that translates into how to make *Sensor* events trigger *Actuator* commands. * In order to do that, we used the *Mediator* pattern to mediate the interaction between *Sensors* and *Actuators*, using *Rules*, *Actions* and *Conditions*. * The *Observer* pattern is also used to allow the *Sensor* events to be handled by the *Mediator/Observer* object, that maps those *Events* to *Conditions* in order to trigger (or not) the *Action*. * The *Command* pattern is also used to allow the *Action* to execute the functions of the *Actuator*. * The *Bridge* pattern is used to represent the various types of *Actuators*. * A test class is present to show how the system will work, with only one test case comprising two rules. ## 2nd Delivery * In this second delivery we focused on refining and expanding on the functionalities previously implemented. * There are now different kinds of events supported, by using the *Template* pattern. * The *Condition* deals distinctly with the different kinds of events detected by the *Sensors* and handled by the *Control Unit*, by using the *Strategy and Factory* patterns. * Events that satisfy no condition no longer break the system, thanks to the *Null Object* pattern. * An *Action* can now trigger more than one *Actuator*, by using the *Composite* pattern. * Support to non-compatible *Actuators* is taken into account by the system, using the *Adapter* pattern. * Some extra test classes have been added, as well as a main class that was intended to morph into a command line tool but could not be finished. * Although not present in the pros of all patterns used, in this delivery we noticed a common advantage of all the patterns implemented: team work is easier. * Since the different functionalities and components are so encapsulated in each class and pattern, by improving a functionality there are few compatibility problems to solve in other parts of the system. For instance: Implementing the *Composite* pattern didn't require any change in the *Event* and *Condition* that trigger the *Action*, or, reversely, improving the *Events* and *Conditions* didn't have any implications on the implementation of the *Actions* they trigger. ## Problems or Issues **Issue 1:** Integration between sub-systems (*Sensors* and *Actuators*) might become a problem. For Example, Temperature sensors not responding? **Issue 2:** Synchronizing the control steps between the remote control system and the central *Control Unit* is a bit hard. For Example: Control steps given from remote control should be known to central *Control Unit*, in order for the intelligent system to operate the device. **Issue 3:** Compatibility of sub systems is important, because if one device is not compatible for integration with another device. For example: An automated blinds supplier provides a window blind that could operate only with a dedicated remote control. That meant the home owner couldn't use their central control system to control their blinds and that they had (another) remote control. ## Elements of the Architecture ### Sensor *Sensors* collect data from the world Examples: light, motion, door, contact, temperature, smoke detection, CO2 levels, IR receiver. ### Actuator *Actuators* interact with the world, moving and controlling a mechanism or system. Examples: smart lock, power outlet, lamp, fan, vacuum cleaner, window blinds ### Control Unit The central component that connects sensors and actuators. It coordinates the *Rules* that allow events from the *Sensors* to trigger commands in the *Actuators*. ### Rules In order to do actions when some event occurs, the rule concept was defined. The *Rule* is based on a condition and an action. If the condition happens, so the action will be executed. This is a feature available in some IoT product, such as Amazon Alexa, for example. Example: Rule #1\ Description: Turn on the lights when there is no light in the room.\ Condition: No light in the room.\ Action: Turn on the lights. ### Condition *Condition* is an element that represents a situation that could happen in an environment that is captured by the *Sensor* and it will be delivered to the *Control Unit*, in order to handle an action based on this condition. The *Condition* is defined in the *Rule* element and it is related to *actions*. Example:\ No light in the room.\ Temperature is greater than 26°C in the room.\ Smoke is detected in the room. ### Action *Action* is the element that represents an activity performed by the *Actuators* when a condition occurs. The *action* is also defined inside the *rule* and it is triggered when a *condition* occurs. Examples:\ Smart Lamp: Turn on the lights.\ Smart AC System: Turn on the air conditioner.\ Smart Heater: Turn off the heater. ### Event *Event* is the element that represents what happened in the environment based on situation that is captured by a *Sensor*. The *Event* keep the information regarding the condition, the moment and the sensor that captured the situation. Example: Event #1\ Description: No light in the room.\ Moment: 05/11/2019 - 03:05pm.\ Sensor: Smart Lamp. ### Commands The *Command* element represents the operations in the low level of implementation that will be executed by the actuators. ## Class Diagram On the following sections, it is shown the specific part of the class diagram with focus on some elements in order to make easy the explanation of each topic. The full version of the diagram is available on [*Appendix I*](#appendix-i). ## Reusable Design Patterns Chosen for the Project ### Different actuators #### Problem in context The *Actuators* can have different ways of being activated, and although some of them are shared between various *Actuators* (on/off, channel switch, incremental), the implementation of each *Actuator* differs despite having the same function. Inheritance doesn't solve this problem. #### Bridge Pattern It allows us to decouple an abstraction from its implementation, so they can vary independently. We can have various implementations of *On/Off Actuators*, knowing that all support the *turnOn* and *turnOff* functions but each can implement it in its way, independently. The same reasoning could be extended to *Sensors* in the future. #### Implementation The interface *OnOffOperations* represents the actuators that only have these two operations (*Turn On* and *Turn Off*). There is another interface that represents the actuators that have more operations related to the channel settings, such as: a TV or Radio System, in this case, the interface *ChannelOperations* inherits from the interface *OnOffOperations* to receive the responsibility of specifying the methods *turnOn* and *turnOff*. On Figure 1, it is ilustrated the package of interfaces related to the *bridge* pattern. That was extracted from the class diagram which is available on Appendix I. From this section, in order to focus on the specific elements to explain, the excerpts of the original class diagram is provided according to each related topic. ![Fig 01 - bridge operation](https://i.imgur.com/TMTMln0.png) **Figure 1** - Package *operation* that represents the interface of *Bridge* pattern. &nbsp; On Figure 2, the classes *SimpleActuator* and *ActuatorOnOffGroup* implements the interfaces of the bridge pattern. The class *ActuatorOnOffGroup* also implements other design pattern that is going to be explained in the following sections. ![](https://i.imgur.com/cWm9pkv.png) **Figure 2** - Package *actuator* that contains the classes that implements the interfaces of the *Bridge* pattern. &nbsp; These interfaces are implemented by the classes that represents that actuators. An example of the source code is shown below on Spec 1. ```java public interface OnOffOperations { void turnOn(); void turnOff(); } ``` **Spec 1** - Interface to represent devices that perform *turn on* and *turn off* operations. Other example that is shown on Spec 2 is the interface *ChannelOperations* which has the methods *channelUp* and *channelDown* and also the methods *turnOn* and *turnOff* which received by inheritance from the interface *OnOffOperations* to represent the devices capable of performing channel operations, such as a TV, for instance. ```java public interface ChannelOperations extends OnOffOperations { void channelUp(); //Increase; void channelDown(); //Decrease; } ``` **Spec 2** - Interface to represent devices that perform *channel up* and *channel down* operations. &nbsp; The class *SimpleActuator* implements the interface *OnOffOperations* and has the concrete methods *turnOn()* and *turnOff()*. The class *TurnOnCommand*, for instance, can interact with *SimpleActuator* through the interface *OnOffOperations*. If it is necessary to create another kind of actuator that need to interact with *TurnOnCommand*, that new class has to implement only the interface *OnOffOperations* and it is not necessary to change the code of the class *TurnOnCommand*. Thus, decoupling the abstraction from its implementation so that the two can vary independently. The source code on Spec 3 shows the class *SimpleActuator*. ```java public class SimpleActuator extends Actuator implements OnOffOperations { // source code omitted... public void turnOn() { System.out.println("Turn On:"+getName()); } public void turnOff() { System.out.println("Turn Off:"+getName()); } ``` **Spec 3** - Class *SimpleActuator* that represents a simple actuator which is capable of doing the actions: *turn on* and *turn off*. &nbsp; #### Pros * With the *Bridge* pattern we can avoid permanent binding between abstraction and implementation: various *On/Off Actuators* that can implement the *turnOn* and *turnOff* function differently. * It also allows the *Control Unit* to ignore the implementation of the *Actuators*, only needing to know their interface and not needing to know how it is implemented by each *Actuator*. #### Cons * The client doesn't know the implementation thus it may make maintenance and future extension more complex. ### Support the execution of different actuators #### Problem in context The *Actions* should support the execution of all types of *Actuators*, but the *Action* doesn't need to be concerned with the implementation of all *Actuators* and their different behaviors. The *Action* should only execute the *Actuator* without knowing what it does or how it is implemented. A remote control button can be used to send commands for turning on / off the lights. The same control can be re-configured to issue commands to close the window blind. #### Command Pattern The *Command* pattern allows the system to use a common interface to execute all *Actuators* without the need to know what the *Actuator* actually does, separating the execution from the implementation. It allows the *Action* to execute the *Actuator* and delegates the implementation of that execution to each *Actuator*, allowing more flexibility to the system in the configuration of distinct *Actions* with very distinct outcomes. The *Composite* pattern could also be used to allow *Actions* to group various *Actuators* and execute them at the same time. #### Implementation ![](https://i.imgur.com/5LC0GBR.png) **Figure 3** - Package *command* that contains some of the classes that related to the *command* pattern. &nbsp; The interface *Command* represents the commands that will be launched by the actuators. There are two classes that implements that interface: *TurnOffCommand* and *TurnOnCommand* as it is shown on Figure 3. ```java public interface Command { public void execute(); } ``` **Spec 4** - The interface *Command* that the *Command Concrete Classes* has to implement. &nbsp; ```java public class TurnOnCommand implements Command{ private OnOffOperations actuator; public TurnOnCommand(OnOffOperations actuator){ this.actuator=actuator; } public void execute(){ actuator.turnOn(); } } ``` **Spec 5** - The class *TurnOnCommand* that implements the interface *Command*. &nbsp; On Spec 5, It is shown the class *TurnOnCommand* that has the implementation of the method *execute* which represents the execution of the command. ```java public class TurnOffCommand implements Command{ private OnOffOperations actuator; public TurnOffCommand(OnOffOperations actuator){ this.actuator=actuator; } public void execute(){ actuator.turnOff(); } } ``` **Spec 6** - The class *TurnOffCommand* that implements the interface *Command*. &nbsp; On Spec 6, It is shown the class *TurnOffCommand* that is similar to the class *TurnOnCommand* and implements the method *execute* which represents the execution of the command with the specific action inside. ![](https://i.imgur.com/WDi61Xr.png) **Figure 4** - Package *controlUnit* that represents classes of the *Control Unit* concept. &nbsp; On Figure 4, it is shown the package *controlUnit* which contains other classes that represents the *Command* Pattern. The class *Action* represents the invoker that will invoke the command. The class *Control Unit* represents the Client that will call the invoker *Action* when it is necessary. The *Control Unit* has a map of rules that do the binding between the condition of events occurs and the action that should be executed. The *Actuator*, which is the Receiver of command, will be called by the command through the interface *OnOffOperations*, which is implemented by the *SimpleActuator*. The *Command* pattern allows the requests to be encapsulated as objects, and send to the Receiver that will execute them. ```java public class Action extends AbstractAction { private String name; private Command command; private Actuator actuator; public Action(String name, Actuator actuator, Command command) { this.command = command; this.actuator = actuator; this.name = name; } @Override public Command getCommand() { return command; } @Override public Actuator getActuator() { return actuator; } } ``` **Spec 7** - The class *Action* that represents the Invoker of the *command* pattern. &nbsp; On Spec 7, it is shown the class *Action* that has an inheritance relationship with the class *AbstractionAction* which makes the creation of new types of compatible actions possible without have to update the class *Action*. #### Pros * The use of the *Command* pattern makes it possible to configure various *Actions* with a variety of *Actuators*, making their execution independent from each *Actuator's* implementation. More flexibility and independence between execution and implementation are the biggest advantages, as well as the possibility of using the *Composite* pattern in the future to easily execute two or more *Actuators* in the same *Action*. #### Cons * Using *command* pattern may require more effort on implementation, since each command requires a *concrete command* class, which will increase the number of classes significantly. ### Communication between classes may become more complex #### Problem in context The system should be capable of performing *Actions*, that are triggered by the *Sensors* and must be executed by the *Actuators*. This *Actions* are triggered when the sensor readings reach a certain threshold (e.g. temperature) or some predefined event happens (e.g. the sun sets). Although part of the same system, the operation and implementation of *Actuators* and *Sensors* should be independent of one another. #### Mediator Pattern Uses the *Control Unit* as a mediator between the *Sensor* and the *Actuator*, encapsulating how they would interact to trigger and execute *Actions*. It promotes loose coupling, by keeping *Sensor* and *Actuator* from referring to each other, and allows us to vary their interaction independently. #### Implementation On Figure 4, it is shown the package *controlUnit*, which contains the elements of the *Mediator* patterns to solve the issue on communication between the classes *Sensor* and *Actuator*. The *Mediator* solves to problem to relate the *Sensor* to the *Actuator* through the *Control Unit*. The class *Control Unit* has an object called *rules* which is a map that connects *Condition* to the *Action*. The class *Condition* represents a condition that has to happen to execute an action. A *Control Unit* can contain many rules based on sensors and actuators, for example: when the sun sets, turn on the lights. The sensor will release an event that will trigger an action in the class *Control Unit*. The class *Action*, thereby, will call a command and involves the receiver, which is the actuator. ```java public class ControlUnit extends Device{ private AbstractAction lastAction; private List<Rule> rules = new ArrayList<Rule>(); public ControlUnit() { super(); } public ControlUnit(long id, String name) { super(id,name); } public void addRule(Condition condition, Action action){ Rule rule = new Rule(condition, action); rules.add(rule); } public void handle(Event event){ System.out.println(this.getName() + " detected event: " + event); AbstractAction action = new ActionNull(); for (Rule rule : rules) { if (rule.getCondition().isTriggeredBy(event)) { action = (Action) rule.getAction(); lastAction=action; break; } } // Here it is to see the action related to the condition. System.out.println(action); // Executing the command related to the action. action.getCommand().execute(); // Setting the last action performed to check on Junit test. this.lastAction = action; } public AbstractAction getLastAction() { return lastAction; } } ``` **Spec 8** - The class *ControlUnit* that represents the mediator object between the *Sensors* and the *Actuators*. &nbsp; On Spec 8, the class *ControlUnit* represents the mediator object of the pattern. In order to have the relationship between the *Sensors* and *Actuator*, based on a condition that happens to the sensor, when it does the reading of the environment, an action is triggered that was defined in the rules settings. The method *addRule* receives two parameter objects: *Condition* and *Action*. *Condition* is related to the *Sensor* and *Action* is related to the *Actuator*. The method *handle* manages the condition and action based on a given event. So if a event happens, a rule is searched that is related to the event in order to do the specific comparison. Hereby, if the received event satifisfies the comparison criteria, the action is fired and it represents the actuator will execute the defined command. ```java public class Rule { private Condition condition; private AbstractAction action; public Rule(Condition condition, AbstractAction action) { this.condition = condition; this.action = action; } public Condition getCondition() { return this.condition; } public AbstractAction getAction() { return this.action; } } ``` **Spec 9** - The *Rule* class that represents the pair: *Condition* and *Action*. &nbsp; On Spec 9, the *Rule* object represents a pair of *Condition* and *Action*. As it was already mentioned, the condition is related to the sensor readings that triggers an action that is executed by the actuators. ```java public class Condition { private String condition; private Sensor sensor; private Event event; private ComparingStrategy comparingStrategy; public Condition(String condition, Sensor sensor, Event event, char comparator) { this.condition = condition; this.sensor = sensor; this.event = event; this.comparingStrategy = ComparingStrategyFactory.getComparingStrategy(comparator); } //Other methods were omitted. public boolean isTriggeredBy(Event event) { EventConditionStrategy strategy = EventConditionStrategyFactory.getStrategy(event, this); return sensor.equals(event.getSensor()) && strategy.eventMeetsCriteria(this, event, comparingStrategy); } } ``` **Spec 10** - The class *Condition* that represents a condition of a rule. &nbsp; On Spec 10, the class *Condition* contains an association with *Sensor* and *Event*, this last element contains the reading of the sensor. This reading is used to do the comparison to the predefined condition, based on a comparing *Strategy*. The comparing strategy is defined by a related character, e.g., the character "=" defines the comparing strategy *EqualsComparingStrategy* that allows to verify if a value is equal to other value. There is a class called *ComparingStrategyFactory* that helps to create an object of the specific comparator. This topic will be explained further in following sections of this document. The *Mediator* was one of the most important design patterns that allow us to connect the sensor to the actuator, because it defines an object that encapsulates how a set of objects can interact and it promotes loose coupling in the relationship between them. #### Pros * Avoid having lots of interconnections between classes. Since *Actuator* and *Sensor* don't need to interact directly with one another. * Easier to maintain the system and evolve each component and its behavior without unnecessary dependencies. #### Cons * The *Mediator* often needs to be very intimate with all the different classes, and it makes it really complex. * Can make it difficult to maintain. #### Coupling between dependent objects is not flexible #### Problem in context The *Control Unit* has to be informed about the events received by the Sensor, so it can receive the critical data needed to trigger the Actions. The *Control Unit* is dependent on the data from the *Sensor* to its operation, but should not be tightly connected with the *Sensor*, it just has to be notified about the data when the *Sensor* reads it without constantly monitoring the Sensor's activity. #### Observer Pattern The *Observer* pattern, implemented with the *mediator* pattern, allows the *Control Unit*, as the *observer/mediator* object, to be notified about the events detected by the Sensor. The *Sensor*, as the subject, sends all its events to the *observer/mediator* and the *mediator* decides how to handle them. By using this pattern, the data dependency stays present but the subject and observer keep their implementations independent. #### Implementation ![](https://i.imgur.com/Cn8TBhK.png) **Figure 5** - The class *Sensor* that represents the source of event on the *Observer* Pattern. &nbsp; In order to receive information about the environment, the class *Sensor*, as shown on Figure 5, represents the Subject or the source of the event and the class *Control Unit*, as shown on Figure 4, represents the *Observer*. The Sensor has an instance of *Control Unit*, and when a situation occurs, the Sensor create an *Event* object and sends to the *Control Unit*. The *Control Unit* represents a class for the *mediator* object, and it will trigger the action based on the mapped predefined condition. The *Control Unit* will handle the event in order to execute the specific command in the class *Actuator* that represents the Receiver. On Figure 6, it is shown the package *event* that contains the class of the specific events in the system. The class *Event* is the superclass and there are other class to represent the types: *BooleanEvent* and *ScaleEvent*. *BooleanEvent* detects the presence of something in the environment, the value can be detected (true) or not detected (false). On the other hand, *ScaleEvent* represents events based on scale, e.g., the light intensity in a room can be measured in lux unit, so if the scale is higher, there is more light in the room. ![](https://i.imgur.com/vI07eK6.png) **Figure 6** - The package *event* contains the classes that represent the event types available in the system. &nbsp; On Spec 7, the method *isTriggeredBy* handles the correct strategy to verify if an event meets the condition criteria. ```java public class Condition { private String condition; private Sensor sensor; private Event event; private ComparingStrategy comparingStrategy; //code omitted. public boolean isTriggeredBy(Event event) { EventConditionStrategy strategy = EventConditionStrategyFactory.getStrategy(event, this); return sensor.equals(event.getSensor()) && strategy.eventMeetsCriteria(this, event, comparingStrategy); } } ``` **Spec 7** - Source code of the class *Condition* with focus on method *isTriggeredBy*. &nbsp; *Events* can have different types of *strategy* based on their types, in order to verify if they meet the condition criteria defined in the rules. For instance, the event based on two values (on and off) which is represented by the class *BooleanEvent* has to be verified by a compatible strategy that is represented in this case by the class *BooleanEventConditionStrategy*. The event type *Scale* would be verified using the strategy related to the scale events, in this case, the class *ScaleEventConditionStrategy*. On Figure 7, it is shown the package *eventStrategy* that contains the classes that represent the compatible strategies for event types available in the system. ![](https://i.imgur.com/CvSqHSe.png) **Figure 7** - The package *eventStrategy* contains the compatible classes strategies with the event types. &nbsp; The usage of *Observer* pattern is important for the architecture to solve the issue of communication between sensors and actuators. In this case, it was necessary to use the *Mediator* pattern as well to involve the *Control Unit* as an object to handle the communication between them. #### Pros * The *Control Unit*, as the observer/mediator, doesn't have to know the specificities of the Sensor's implementation, allowing independent coupling. * It allows for more flexibility in defining different kinds of *Sensors* without having to adapt the *Control Unit* to the specificities of those different sensors or the way it is notified about their events. * Provides a loosely coupled design between objects that interact. #### Cons * If not correctly implemented, the *Observer* can add complexity and lead to inadvertent performance issues. ### Integrate incompatible interfaces to work together #### Problem in context The system would like to use a legacy device without modifying it. However, the desired usage requires conformance to different target interface (to be used by the client class). In this context, I should not change the class to implements the required interface as it is not possible to change existing classes because they are implemented by a different classes and are used in other projects which don’t contain the required interface. Defining an *Adapter* class resolves this problem. #### Adapter pattern An *Adapter* allows two incompatible interfaces to work together. Interfaces may be incompatible, but the inner functionality should suit the need. The adapter design pattern allows otherwise incompatible classes to work together by converting the interface of one class into an interface expected by the clients. #### Implementation ![](https://i.imgur.com/TwfRsFU.png) **Figure 8** - The package *adapter* contains some of the class related to the Adapter Pattern. &nbsp; On Figure 8, the class *OldDevice* represents an incompatible actuator that needs to be connected to the system to turn on and turn off the lights. The methods for that purpose are *lightOn* and *lightOff*, respectively, which are different from the methods of the interface *OnOffOperations* that has the methods *turnOn* and *turnOff*. The issue is how to connect the class *OldDevice* to the system if it is different from what the system expects. In order to solve this problem, the class *ActuatorAdapter* was created which does the adaptive connection between the System and the *OldDevice* class. On Spec 8, the *ActuatorAdapter* class is an implementation of the *OnOffOperations* interface and extends the functionality of an *Actuator abstract class*. The class *OldDevice* represents an incompatible device and its operations. Once an instance of the *ActuatorAdapter* has executed its methods, actually, it is delegated to the *OldDevice* methods. ```java public class ActuatorAdapter extends Actuator implements OnOffOperations { private OldDevice oldDevice; public ActuatorAdapter(OldDevice oldDevice) { this.oldDevice=oldDevice; } public void turnOn() { oldDevice.lightOn(); } public void turnOff() { oldDevice.lightOff(); } } ``` **Spec 8** - Source code of the class *ActuatorAdapter*. &nbsp; #### Pros * Introduce new types of adapters into the program without breaking the existing client code. * It increases reusability and flexibility. The interface of the adapter is defined and agreed upon. So as long as the agreement is maintained we can change the implementation within the adapter #### Cons * The overall complexity of the code increases because you need to introduce a set of new interfaces and classes. ### Actions that trigger more than one Actuator #### Problem in context To implement a smart and flexible house automation system we should consider Actions that deal with more than one Actuator or with a group of Actuators. For instance, we can have individual light actuators in a room and turn all those lights on or off at the same time, or we can deal with combinatory Actions: if the sun sets -> close blinds and turn on the light. The *Action* object doesn't need to encapsulate the complexity of turning multiple devices at the same time, since it already knows how to deal with different Actuators while ignoring their implementation (thanks to the *Command* pattern). #### Composite pattern The *Composite* pattern is meant to allow treating individual objects and compositions of objects in the same way. By treating a group of Commands as a *Composite command*, implementing the same component interface, this pattern helps us to run multiple commands as one, without the Action being aware if it is triggering a single instance or a composition of command. With this pattern, we can compose objects and work with them as if it was a singular object. #### Implementation ![](https://i.imgur.com/q0cEl34.png) **Figure 9** - The package *actuator* and the class *ActuatorOnOffGroup* that implements the *composite* pattern. &nbsp; On Figure 9, the package *actuator* contains the available actuators in the system. The class *ActuatorOnOffGroup* represents a group of actuator that implements the *composite* pattern. The *ActuatorOnOffGroup* class implements the *OnOffOperations* interface and has a list of *OnOffOperations*. By implementing the required *turnOn* and *turnOff* methods of that interface, and invoking the respective *TurnOn* or *TurnOff* method in each individual actuator that are in the list. It provides the same interface to the outside (the *Action*) while dealing with compositions of operators. On Spec 9, it is shown the class *ActuatorOnOffGroup* that has the *turnOn* and *turnOff* methods implemented considering to call the methods of each actuator presents in the list. ```java public class ActuatorOnOffGroup extends Actuator implements OnOffOperations { private List<OnOffOperations> actuators; public ActuatorOnOffGroup(List<OnOffOperations> actuators){ this.actuators=actuators; } //code omitted public void turnOn() { for(OnOffOperations actuator:actuators){ actuator.turnOn(); } } public void turnOff() { for(OnOffOperations actuator:actuators){ actuator.turnOff(); } } } ``` **Spec 9** - The class *ActuatorOnOffGroup* which implements the *composite* pattern. &nbsp; #### Pros: * The *Action* can trigger several Actuators without knowing their implementation nor how many Actuators it is executing. * The *Actions* gained flexibility to trigger more than one Actuator without implementing any more code. #### Cons: * More complex *Actuators* can require different parameters and this design pattern may be too simplistic to deal with that eventual complexity. ### Different Events detected by Sensors #### Problem in Context *Sensors* maybe physically different, but to the system what distinguish one *Sensor* from the other is the *Event* they detect. There is different data that can be represented by an *Event*. Some represent measures of temperature or light, others represent the occurrence or non occurrence of certain events (movement, smoke) and even others can represent spacial information. Although different, these *Events* have some common elements that don't need to be dispersed and repeated in different classes. A common interface is needed, but with flexibility to allow each Event to represent its own data. #### Template method Pattern The *Template* method defines the base structure of the *Event* and the common methods between all Events, delegating the specific methods and divergent data to be implemented by each specific *Event* that extends the *AbstractEvent* class. It provides a basic structure for all the system to interact with without knowing the specificities of each Event type. #### Implementation On Figure 6, the *Abstract Class Event* implements all methods common to all events, namely the time of its occurrence, a description and the Sensor that sensed it. On Spec 10, the *template* method is the *toString* method in this case, that delegates the display of the specific Event's data to the abstract *displayData* method, that must be implemented by all *Concrete Events*. ```java public abstract class Event { private LocalDateTime moment; private String situation; //Sensor is the source of the event; private Sensor sensor; public Event(String situation, Sensor sensor) { moment = LocalDateTime.now(); this.situation=situation; this.sensor=sensor; } //Code omitted @Override public final String toString() { return "Event{" + "moment=" + moment + ", situation='" + situation + '\'' + ", sensor=" + sensor + DisplayData(); } public abstract String DisplayData(); } ``` **Spec 10** - The *Abstract Class Event* which has template method. &nbsp; There are two types of events available in the system: * *ScaleEvents*: that sense values in a certain unit scale (e.g. temperature, brightness, CO2 levels). * *BooleanEvents*: that sense if something occurs or not (alarm, smoke detector). #### Pros * Non repeated code between all different Events, by keeping it centralized on the *Abstract Class Event*. If some change has to be made to all events or some new common behavior has to be implemented, there is only one class to edit. * The *Control Unit* does not need to know which *concrete Event* it is handling upon detection of an *Event* by the *Sensor*, it processes all *Events* the same way and their specificities are taken into account only when needed (in the *Condition*). #### Cons * The system has to deal with different types of events, therefore becoming more complex. ### Events that trigger no Action #### Problem in Context Not all Events detected by the *Sensors* will trigger *Actions*. The *Sensors* will send readings that will lead to no action by the *Actuators*. The system should not expect every Event to meet a *Condition*, and checking if an object is null before each operation leads to an inelegant implementation. #### Null Object Pattern By using an object that represents the absence of an action, the implementation doesn't need to check if the *Action* is null before executing it, it will execute a non-Action with a default execute nothing behavior that will have no consequence in the system. #### Implementation ![](https://i.imgur.com/NBHZwkg.png) **Figure 10** - The class *ActionNull* that implements the *Null Object* Pattern. &nbsp; On Figure 10, the *AbstractAction* class defines the interface of an Action. The Action class, now extending the *AbstractAction*, implements the functionalities it implemented before, representing an *Action* that will do something.The *ActionNull* class also extends the *AbstractAction* class but representing the absence of an Action, by providing a do-nothing behavior to the system. The source code of the class *ActionNull* is shown on Spec 11 The *ControlUnit*, while handling an *Event*, knows that if no *Condition* is met an *ActionNull* will be executed and no behavior will come from it, instead of making prevention to null pointer exceptions in every step of the implementation. ```java public class ActionNull extends AbstractAction { private static final String NO_ACTION = "no action set"; private static final SimpleActuator NO_ACTUATOR = new SimpleActuator(NO_ACTION); private static final TurnOffCommand NO_COMMAND = new TurnOffCommand(NO_ACTUATOR); public ActionNull() { // empty constructor } @Override public String getName() { return NO_ACTION; } @Override public Command getCommand() { return NO_COMMAND; } @Override public Actuator getActuator() { return NO_ACTUATOR; } @Override public String toString() { return NO_ACTION; } } ``` **Spec 11** - The source code of the class *ActionNull* that implements the *Null Object* Pattern &nbsp; #### Pros * With the *Null Object* pattern the need of checking for nulls is reduced, by assuming a *ActionNull* object while searching for *Conditions* that are triggered by an *Event*. * The execution of a *ActionNull* will have no real consequence in the system, since it doesn't use any *Actuator*. #### Cons * More complexity introduced with the need of creating one more abstract class (*AbstractAction*) without benefiting the original Action class. * The *Null Object* pattern is mor a refactoring technique than a real design pattern, although it can be viewed as an implementation of the *State* pattern that defines a do-nothing state. ### Conditions have to deal with different events and check if they meet the Condition's criteria #### Problem in Context The *Sensors* can detect different kinds of *Events* (e.g. *ScaleEvent* - value + unit; *BooleanEvent* - situation + occurrence (true/false)). The user should be able to define *Rules* whose *Condition* can represent any type of *Event* supported in the system. Upon detecting an *Event*, the *Condition* should be able to evaluate if the *Event* meets the criteria set by the user. #### Strategy and factory pattern combination By using the *Strategy* pattern, it is possible to define different algorithms to check if an *Event* meets a criteria set in a *Condition*, based on the type of *Event* defined in the *Condition*. The *Condition* class doesn't need to know what algorithm is used in the comparison, it delegates that responsibility to the strategy. This pattern is used in conjunction with the *Factory* pattern. A *factory* class receives the *Events* it needs to decide what is the strategy needed in that case and returns the correct strategy. The *Condition* doesn't need to know what strategy it is using or why, just asks the factory to provide the correct strategy and calls the methods all strategies implement. #### Implementation An *EventConditionStrategy* interface defines the methods needed to compare *Events* detected and the *Event* set in a *Condition*. The concrete strategies, *ScaleEventConditionStrategy* and *BooleanEventConditionStrategy*, implement the algorithms that compare each *Event* and its specific data. An *EventConditionStrategyFactory* decides, based on the detected *Event* and the *Event* set in a *Condition*, what *EventConditionStrategy* should be used to see if an *Event* meets the criteria set in the *Condition*. This factory can return a *BooleanEventConditionStrategy* (to compare *BooleanEvents*), *ScaleEventConditionStrategy* (to compare *ScaleEvents*) or *InvalidStrategy*, returning false and forbidding the comparison of concrete Events of different types. ![](https://i.imgur.com/hAaevfO.png) **Figure 11** - The package *eventStrategy* that contains the classes that represents different types of strategy for dealing with types of event. &nbsp; The *Strategy* pattern is used in two instances, as shown on Figure 11: Firstly to know the algorithm needed to compare a detected Event with the defined Conditions (*EventConditionStrategy*). This interface defines the method that will compare an *Event* and a *Condition*, leaving to the concrete strategies its implementation. Secondly to know how to compare a *ScaleEvent* with the comparing strategy that was defined in the Condition class , for >, < = or != operations. ```java public interface EventConditionStrategy { public boolean eventMeetsCriteria(Condition condition, Event detectedEvent, ComparingStrategy comparingStrategy); } ``` **Spec 12** - The interface *EventConditionStrategy*. &nbsp; ```java public class BooleanEventConditionStrategy implements EventConditionStrategy { public boolean eventMeetsCriteria(Condition condition, Event detectedEvent, ComparingStrategy comparingStrategy) { final BooleanEvent detectedBooleanEvent = (BooleanEvent) detectedEvent; final BooleanEvent triggerBooleanEvent = (BooleanEvent) condition.getEvent(); return triggerBooleanEvent.isDetected() == detectedBooleanEvent.isDetected(); } } ``` **Spec 13** - The concrete class *BooleanEventConditionStrategy*. &nbsp; ```java public class ScaleEventConditionStrategy implements EventConditionStrategy { public boolean eventMeetsCriteria(Condition condition, Event detectedEvent, ComparingStrategy comparingStrategy) { final ScaleEvent detectedScaleEvent = (ScaleEvent) detectedEvent; final ScaleEvent triggerScaleEvent = (ScaleEvent) condition.getEvent(); return triggerScaleEvent.getUnit().equals(detectedScaleEvent.getUnit()) && comparingStrategy.compare(triggerScaleEvent.getScale(), detectedScaleEvent.getScale()); } } ``` **Spec 14** - The concrete class *ScaleEventConditionStrategy*. &nbsp; ```java public class EventConditionStrategyFactory { public static EventConditionStrategy getStrategy(Event event, Condition condition) { EventConditionStrategy strategy = new InvalidStrategy(); if (event.getClass() == condition.getEvent().getClass()) { if (event.getClass() == ScaleEvent.class) { strategy = new ScaleEventConditionStrategy(); } if (event.getClass() == BooleanEvent.class) { strategy = new BooleanEventConditionStrategy(); } } return strategy; } } ``` **Spec 15** - The class *EventConditionStrategyFactory*. &nbsp; ```java public class InvalidStrategy implements EventConditionStrategy { public boolean eventMeetsCriteria(Condition condition, Event detectedEvent, ComparingStrategy comparingStrategy) { return false; } } ``` **Spec 16** - The class *InvalidStrategy* that implements *EventConditionStrategy*. &nbsp; On Spec 15, An *EventConditionStrategyFactory* decides, based on the detected Event and the Event set in a Condition, what *EventConditionStrategy* should be used to see if an Event meets the criteria set in the Condition. This factory can return a *BooleanEventConditionStrategy* (Spec 13), to compare *BooleanEvents*, *ScaleEventConditionStrategy* (Spec 14),to compare *ScaleEvents*, or *InvalidStrategy* (Spec 16), forbidding the comparison of concrete Events of different types. A comparing *StrategyFactory* decides, based on a character, the mathematical comparison needed to compare the *ScaleEvents* (>, <, =, !=). The diagram on Figure 11 ilustrates the classes and relations among them. #### Pros * The *Condition* class needs no knowledge about the *Event* it is detecting to decide what algorithm to use, delegating its implementation to the *EventConditionStrategy* and the selection to the *EventConditionStrategyFactory*. * The Condition uses the *EventConditionFactory* to chose the best Strategy to analyze each Event it has to analyze, providing flexibility at runtime; * The code is much more cleaner and hides all the complexity from the main classes. #### Cons * Multiplication of classes and interfaces to define basic operations. This problem is felt with only two *Event* types, it can be exponentially increased with the implementation of new *Event* types in the future. ### Unfeasibility of using exact values in Conditions #### Problem in Context It isn't realistic to define a precise condition to an *Action*. Consider for instance the need to turn on the heating system: it shouldn't be triggered when the temperature reaches exactly 0 degrees, if it gets to -1, -2 or -10 the heating should be turned on as well. It is unfeasible and will make the system useless if the user has to manually define a different *Condition* to each value below 0 to be able to turn on the heating system when it is cold. The user should define a comparator in each *Condition* and the *Condition* should know how to interpret the *Events* detected and decide if they meet the *Event* that triggers the *Condition*. However, this situation is not applicable to *BooleanEvents* (which don't comprise any numerical value), so the logic should be hidden from the Condition class. #### Strategy and factory pattern combination By using the *Strategy* pattern, different comparing strategies can be defined to see if an *Event* meets the range of a *Condition*. The *Condition* delegates the comparing algorithms to the *ComparingStrategy* and only has to pass them to the *EventConditionStrategy* in each comparison. This pattern is used in conjunction with the *Factory* pattern. A factory class receives the attributes it needs to decide what is the strategy needed in a certain case and returns that strategy. The class that uses the *Strategy* doesn't need to know what strategy it is using or why, just asks the factory to provide the correct strategy and executes it. #### Implementation ![](https://i.imgur.com/QkoDOPK.png) **Figure 12** - The package *comparator* that contains classes used for the comparing strategies. &nbsp; The *Strategy* pattern is used to know how to compare a *ScaleEvent* with the defined *Condition*. The *ComparingStrategy* interface (Spec 17) declares a boolean compare method that receives to numeric values and a String method sign that returns the comparing mathematical sign of the operation (used for display purposes). The concrete strategies: *EqualsComparingStrategy* (Spec 19), *NotEqualsComparingStrategy* (Spec 22), *MoreThanComparingStrategy* (Spec 21) and *LessThanComparingStrategy* (Spec 20) implement the comparing algorithms and provide the logic to the *ScaleEventConditionStrategy*. A comparing *StrategyFactory* (Spec 18) decides, based on a character (=, >, < and !=), the mathematical comparison needed to compare the *ScaleEvents*. On Figure 18, it is shown the class diagram regarding the comparing strategies. ```java public interface ComparingStrategy { public boolean compare(int definition, int candidate); } ``` **Spec 17** - The interface *ComparingStrategy* &nbsp; ```java public class ComparingStrategyFactory { public static ComparingStrategy getComparingStrategy(char comparator) { ComparingStrategy strategy = new NotEqualsComparingStrategy(); switch (comparator) { case '=': strategy = new EqualsComparingStrategy(); break; case '>': strategy = new MoreThanComparingStrategy(); break; case '<': strategy = new LessThanComparingStrategy(); break; } return strategy; } } ``` **Spec 18** - The class *ComparingStrategyFactory* &nbsp; ```java public class EqualsComparingStrategy implements ComparingStrategy { @Override public boolean compare(int definition, int candidate) { return definition == candidate; } } ``` **Spec 19** - The class *EqualsComparingStrategy* &nbsp; ```java public class LessThanComparingStrategy implements ComparingStrategy { @Override public boolean compare(int definition, int candidate) { return candidate < definition; } } ``` **Spec 20** - The class *LessThanComparingStrategy* &nbsp; ```java public class MoreThanComparingStrategy implements ComparingStrategy { @Override public boolean compare(int definition, int candidate) { return candidate > definition; } } ``` **Spec 21** - The class *MoreThanComparingStrategy* &nbsp; ```java public class NotEqualsComparingStrategy implements ComparingStrategy { @Override public boolean compare(int definition, int candidate) { return definition != candidate; } } ``` **Spec 22** - The class *NotEqualsComparingStrategy* &nbsp; #### Pros * The *Condition* class needs no knowledge about the implementation of the comparing algorithms needed to compare *ScaleEvents*. * The *ComparingStrategy*, being immutable in each *Condition*, can be defined upon the definition of the *Condition*. * The code is much more cleaner and hides all the complexity from the *Condition* and *EventConditionStrategy* classes. * Expandability - if a new type of Event is implemented whose *Condition* requires mathematical operations (e.g. spacial awareness: X < value, Y = value, Y > value), the implementation of the comparing operations is already done and available to the new *EventConditionStrategy* class that will deal with those Events. #### Cons * The *ComparingStrategy* appears in cases in which it is not relevant, like in Conditions concerning *BooleanEvents*. The alternative would be to have more than one type of *Condition*, but it would also multiply the Strategies needed to each Condition and this compromise looked like the more acceptable and less troublesome to deal with. * Multiplication of classes and interfaces to define basic operations. ### The Actuators should remember their state #### Problem in Context The *Actuators* can do a variety of commands and they should remember in which state they are so the user can see what each actuator is doing at the moment. If we turn on the lights, the lights shall turn on and keep turned on until turned off in the future. Moreover, when we try to turn on a light that is already on we should expect a different behavior than when we switched it from off to on. Some behaviors are more complex, like remembering the temperature and intensity set in an air conditioner or the program set in an intelligent washing machine, but others will be common between different actuators, like turn on and off, and we should avoid repeating code while implementing the actuator state. #### State pattern The *State* pattern allows us to delegate the management of the actuator's state to the state object, allowing the actuators to call the methods in the state without having to implement its functionality and manage how the states interact with each other. This allows code recycling, because various actuator types can encapsulate the same state and its functionality without having to reimplement it or repeat its code. #### Implementation ![](https://i.imgur.com/9LOsODw.png) **Figure 13** - The package *state* that contains classes used for managing the states of actuator. &nbsp; On Figure 13, there is the *ActuatorState* interface (Spec 24) that has the *getState* method, that returns a *String* with the device's state. The Actuator class has an *ActuatorState*, and since all Actuators extend this class, all should have an *ActuatorState*. The *ActivationState* (Spec 23) is another interface that extends *ActivatorState*. It has the *turnOn, turnOff and switch* methods and is present in the *SimpleActuator* (that implements *OnOffOperations* - turnOn and turnOff). The *TurnedOnActivationState* class (Spec 26) and *TurnedOffActivationState* (Spec 25) implement the *ActivationState* interface, allowing common operations and state transitions to all Actuators that need to use this state. ```java public interface ActivationState extends ActuatorState { public ActivationState turnOn(); public ActivationState turnOff(); public ActivationState switchState(); } ``` **Spec 23** - The interface *ActivationState* that extends *ActuatorState*. &nbsp; ```java public interface ActuatorState { public String getState(); } ``` **Spec 24** - The interface *ActuatorState* &nbsp; ```java public class TurnedOffActivationState implements ActivationState { private final static String OFF_STATE = "Turned Off"; private final static String TURN_ON = "Turn On: "; private final static String ALREADY_OFF = "Already turned off: "; public String getState() { return OFF_STATE; } public ActivationState turnOn() { return switchState(); } public ActivationState turnOff() { System.out.print(ALREADY_OFF); return this; } public ActivationState switchState() { System.out.print(TURN_ON); return new TurnedOnActivationState(); } } ``` **Spec 25** - The class *TurnedOffActivationState* that implements *ActivationState* &nbsp; ```java public class TurnedOnActivationState implements ActivationState { private final static String ON_STATE = "Turned On"; private final static String TURN_OFF = "Turn Off: "; private final static String ALREADY_ON = "Already turned on: "; public String getState() { return ON_STATE; } public ActivationState turnOn() { System.out.print(ALREADY_ON); return this; } public ActivationState turnOff() { return switchState(); } public ActivationState switchState() { System.out.print(TURN_OFF); return new TurnedOffActivationState(); } } ``` **Spec 26** - The class *TurnedOnActivationState* that implements *ActivationState* &nbsp; More *ActuatorStates* could be implemented in the future to extend more sophisticated behaviors (e.g. *ChannelState* - for actuators that can switch channels of operation, location state - for actuators that receive spacial coordinates in their operation).. Using a *Decorator* pattern to allow for various *ActuatorStates* combinations would also be a good architectural solution to allow various states to coexist in the same object without manually combining them for covering all combinatory possibilities. #### Pros * The *Actuators* keep information about their state without implementing the specific behavior of each state, only encapsulating the desired state and calling its methods too switch states. * The user can see the state of an Actuator any time. * In the future the states can be combined and expanded without the existent *Actuators* needed to be changed. #### Cons * More classes needed to manage relatively simple operations. * Combination of *State, Bridge and Command* pattern in Actuators leads to more consideration and analysis before making changes and improving the functionality of the system. ## Issues regarding the development of User Interface elements ### Separation of the implementation and the user interface #### Problem in Context The implementation of a user interface adds complexity and more code to be implemented and managed. The behavior of the system and the way it is displayed should be separated and managed independently. Moreover, in the long run more user interfaces can be added in the system and they should be independent from one another and, specially, from the implementation of the business logic. #### Model View Controller pattern With the *Model View Controller* pattern (MVC) the business logic and the interface are separated and managed independently: * The *Model* deals with the business logic and all the operations needed to fulfill the functional requirements of the system. * The *View* displays the data to the user and receives the user's input and interactions. * The *Controller* processes the user input sent from the *view* and interacts with the model, providing communication between the two components and deciding what functions of the logic to invoke based on the information that the view received from the user. #### Implementation ![](https://i.imgur.com/Uf2tQw2.png) **Figure 14** - The package *controller* for UI that contains classes used for managing the UI actions. &nbsp; The implementation of this pattern involves using three different packages with their responsibilities well defined: * the *model package* - the one mentioned in almost every pattern in this report (all patterns in the 1st and 2nd deliveries) - is responsible for the business logic of the system. No matter how many different user interfaces the system could have, the model will remain the same throughout them and all eventual Controllers shall interact with the same model. * The *controller package* (Figure 14), responsible to implement all logic to provide the right information to the user interface and to process it to the appropriate methods and classes of the model. It manages how the view is generated and how the data that the user inputs in the view is processed. More details about problems, patterns and implementation of the *Controller* will be explained in the following sections. * the *view package* displays the user interface, by calling the *CommandLineController* class in a static main method and generating it with demo-data provided by the *ControllerDataInitializer*. The view is displayed on the command line and the user interacts with it. #### Pros * The model is separated from the view, making the code cleaner and allowing each package its own responsibility. * The code is more well organized and easy to maintain. #### Cons * More classes to deal with and more complexity in joining the different components. * A good understanding of the control flow is needed to edit and maintain the code. ### Various Controller classes need to interact with the user using the same operations #### Problem in Context The *Controller* classes will specialize in different parts of the interface (input readings into sensors, creating *sensors* and *actuators*, creating *rules*, activating actuators) and each class should have its own responsibility instead of having a giant class comprising the whole *Controller* logic. However, all these *Controller* classes will use similar methods to ask the user for input and to process it, and repeated code is not a good solution. #### Template pattern Using the *template* pattern, we can implement an *abstract class* comprising all the functionality needed in all controllers and delegating the implementation of specific logic to each controller that extends the abstract class. By doing so, the common logic of asking the user for input and processing the input is located on the *abstract class* and accessible for all classes that extend it. The implementation also uses the *command* pattern, as explained in the next section. #### Implementation ![](https://i.imgur.com/w6kLKVl.png) **Figure 15** - The class *AbstractController* and the interface *DisplayCommand*. &nbsp; The *AbstractController* class (Spec 27) implements the methods *printInterface* - that print some text and ask the user for an input in the command line. The basic *printInterface* method only receives one String, prints it and asks the user for an input, where the other *printInterface* method receives an array of Strings, prints them one by one and stores in an array the inputs that the user inserts for each displayed String, returning it. This allows processing of more complex menus with less implementation effort. On Figure 15, the selected elements of the class diagram ilustrates the classes, interfaces, and their relationships. The *AbstractController* class also has a method to print tables, used to present the Dashboard in the main menu. This method calls various private methods that, despite relevant for the operation, are not relevant to be visible for each *Controller* class that extends *AbstractController*. ```java public abstract class AbstractController implements DisplayCommand { protected int commandIndex; protected static final String SELECTION_MESSAGE = "- Select one: "; private static final String INVALID_MESSAGE = "Invalid data, please try again\n"; //code omitted protected static String printInterface(String display) { //code ommited } protected static List<String> printInterface(List<String> display) //code omitted } protected void printTable(String[] headers, String[][] values) { //code omitted } private void printLine(String[] line, int[] dimensions) { //code omitted } private void printCell(int size, String string) { //code omitted } private String fillWithSpaces(int times) { //code omitted } private static int[] calculateTableDimensions(String[] headers, String[][] values) { //code omitted } protected static String invalidData() { //code omitted } public String commandLineDisplay() { //code omitted } public int commandIndex() { //code omitted } } ``` **Spec 27** - The class *AbstractController* used for the *UI controller* classes. &nbsp; The *AbstractController* doesn't present explicitly any abstract method that the classes that extend it should implement, however it implicitly defines some methods that each sub-class should implement by implementing the *DisplayCommand* interface, implementing some of its methods that all subclasses will use in the same way, namely the *commandIndex*. More detail will be provided in the next section. #### Pros * Centralizing the implementation of all common methods that all Controllers need and allowing each one to implement its specific behavior. * Avoid repeated code and making maintaining and changing the common methods easier. * Cleaner code and well defined responsabilities among the Controller classes. #### Cons * Some common methods are reduced to the lowest common denominator (primitive types) and require some work-arounds to be used by the subclasses, namely converting Arrays into Lists in the *printInterface* method that receives multiple user inputs or converting all variables into Strings and put them in a matrix in the *printTable* method. * Trade offs between higher reuse of code and more specific methods to suit each Controller's responsibilities and classes used (e.g. specific method to print *Actuators* and *Sensors* vs generalizing to use Strings). ### Call all different controllers in the same way #### Problem in Context The *CommandLineController* decides what menu it will display in the user interface. It has to be able to call all different controllers by the clearest way possible, without if-elses to see which controller is being invoked and what operation to call in each case. A *Strategy* pattern could be used to call different methods, but we decided that there was a cleaner approach. #### Command pattern By forcing every controller to implement the *DisplayCommand* interface (that is partially implemented by the abstract class *AbstractController* that all Controllers extend), the *CommandLineController* can call every Controller in the same way, without needing to know which menu was selected by the user and, consequently, which *Controller* should be active and displayed. #### Implementation The *DisplayCommand* interface (Spec 28) declares: * the *displayCommand* void method (that displays each Controller's menu); * the *commandName* String method, that defines the name of the menu; * The *commandIndex* int method, that defines what number will represent the menu and has been implemented by the *AbstractController* class; * the *commandLineDisplay* String method, that defines what number and name will represent the Controller in the main menu (and has been implemented by the *AbstractController* class. This interface is shown on Figure 15. Each *Controller* just defines its *displayCommand* method to print the menu and its *commandName* method to choose its own name and the *CommandLineController* can call each Controller's functionality indiscriminately, just asking the user to select one and calling the *commandName* and the *displayCommand* method of the actual selection. ```java public interface DisplayCommand { public void displayCommand(ControlUnit controlUnit); public String commandLineDisplay(); public String commandName(); public int commandIndex(); } ``` **Spec 28** - The interface *DisplayCommand* &nbsp; #### Pros * Clean way to call different functionalities of different *Controllers* without discriminating which one is selected * Easy to maintain the code and to add more *Controllers*; * Using with the *template* pattern allow the delegation of common operations to the *AbstractController* method; * Even more flexibility and expandability to future functionalities by using the *composite* pattern (in the next section). #### Cons * If different *Controllers* required different operations or parameters in their operation this wouldn't be the best pattern to solve the problem, *Strategy* would be more efficient. ### If system can have more than one control unit, how would the Controller handle it? #### Problem in Context We were considering just one *Control Unit* in the whole system, but what if we could have one per house division? How would the menu be presented? How could the current implementation be easily expanded to allow a more complex menu? #### Composite pattern By implementing the same *DisplayCommand* interface, the *CommandLineController* can be used in the same way that the Controllers are, so a class that calls different *CommandLineInterfaces*, each with its different *ControlUnit*, could be implemented as easily as the *CommandLineController* is. #### Implementation The *CommandLineController* (shown on Figure 15) implements the menu display related methods (*commandLineDisplay, commandName and commandIndex*) so it can appear in a menu and called in the same way as the *Controllers*. Details of implementation is shown on Spec 29. It contains a list of *CommandDisplay* elements, so it is a composition of objects that implement the same interface as the class in which they are contained. By implementing the *displayCommand* method, its menu is invoked the same way as each Controller menu is, allowing another class to call it as a normal *CommandDisplay* implementation. ```java public class CommandLineController implements DisplayCommand { private SensorController sensorController; private EventController eventController; private ActuatorController actuatorController; private ActionController actionController; private RuleDisplayController ruleDisplayController; private RuleController ruleController; private int indexation = 0; private static List<DisplayCommand> commandsToDisplay = new ArrayList<DisplayCommand>(); private final String output = "\nH.O.T. DASHBOARD\n"; private String menu = "MAIN MENU"; private final String ASK_SELECTION = "Select an option:"; private final String SEPARATOR_LINE = "\n------------------------------------------------------------------------------------------------------------------\n"; private final String DASHBOARD_SEPARATOR_LINE = "\n##################################################################################################################\n"; public CommandLineController() { eventController = new EventController(attributeIndex()); commandsToDisplay.add(eventController); sensorController = new SensorController(attributeIndex()); commandsToDisplay.add(sensorController); actionController = new ActionController(attributeIndex()); commandsToDisplay.add(actionController); actuatorController = new ActuatorController(attributeIndex()); commandsToDisplay.add(actuatorController); ruleDisplayController = new RuleDisplayController(attributeIndex()); commandsToDisplay.add(ruleDisplayController); ruleController = new RuleController(attributeIndex()); commandsToDisplay.add(ruleController); defineMenu(); } public void displayCommand(ControlUnit controlUnit) { //code omitted } private void showDevices(ControlUnit controlUnit) { //code omitted } private void defineMenu() { //code omitted } private int attributeIndex() { //code omitted } public String commandLineDisplay() { //code omitted } public String commandName() { //code omitted } public int commandIndex() { //code omitted } } ``` **Spec 29** - The class *CommandLineController* implements the interface *DisplayCommand*. &nbsp; #### Pros * Expandability of functionality without requiring a different approach in calling menus. * Easy to implement based on the initial implementation of each Controller. #### Cons * The *Composite* pattern usually calls all its components at the same time. The current implementation disrespects that fact. ### Controllers dealing with different events and commands #### Problem in Context When a *Controller* is creating inputs (readings/events) and outputs (actions/commands) in the system, multiple events and commands can be created (e.g. *ScaleEvent, BooleanEvent or TurnOn, TurnOff and channel operation commands*). An if-else approach in different parts of the code would be a solution that will be hard to evolve with more types of events and commands, requiring constant effort and manual expansion of types in different places of the code. #### Strategy and factory patterns By using different *strategies* for each situation, the system can manage the complexity of each event or command in their respective strategy and, by using a factory, generate the correct strategy for each situation and invoke all methods needed in each strategy without repeating if-elses at each decision stage. #### Implementation The *EventControllerEventCreationStrategy* interface (Figure 16) defines the methods that each strategy of event creation should implement. The source code of this interface is shown on Spec 30. The *EventControllerEventCreationStrategyFactory* (Spec 31) receives the input of the user and decides based on it which strategy it shall return. After the strategy is returned to the *EventController*, no more if-elses are needed and all specific operations that each strategy provides are accessible by the *createEvent* method without needing to know with which event it is dealing with at each time. ![](https://i.imgur.com/5Ly7qbD.png) **Figure 16** - The package *strategy* that contains strategies for dealing of UI elements related to the types of events that are available in the system. &nbsp; ```java public interface EventControllerEventCreationStrategy { public String[] specificEventInfo(); public Event createEvent(List<String> values, Sensor sensor); } ``` **Spec 30** - The class *EventControllerEventCreationStrategy* &nbsp; ```java public class EventControllerEventCreationStrategyFactory { public static EventControllerEventCreationStrategy getStrategy(String input) { EventControllerEventCreationStrategy strategy = null; switch (input.charAt(0)) { case '1': strategy = new EventControllerScaleEventCreationStrategy(); break; case '2': strategy = new EventControllerBooleanEventCreationStrategy(); break; } return strategy; } } ``` **Spec 31** - The class *EventControllerEventCreationStrategyFactory* &nbsp; By the same reasoning, the *RuleControllerCommandStrategy* (Spec 32) interface defines the methods that each strategy of command creation should implement. The *RuleControllerCommandStrategyFactory* (Spec 33) receives the input of the user and decides based on it which strategy it shall return. After the strategy is returned to the *RuleController*, no more if-elses are needed and all specific operations that each strategy provides are accessible by the *createAction* method without needing to know with which Command it is dealing with at each time. ```java public interface RuleControllerCommandStrategy { public Command createCommand(SimpleActuator actuator); } ``` **Spec 32** - The interface *RuleControllerCommandStrategy* &nbsp; ```java public class RuleControllerCommandStrategyFactory { private static final String ON_STRING = "on"; private static final String OFF_STRING = "off"; public static final RuleControllerCommandStrategy getStrategy(String input) { RuleControllerCommandStrategy strategy = null; if (ON_STRING.equalsIgnoreCase(input.trim())) { strategy = new RuleControllerTurnOnCommandStrategy(); } else if (OFF_STRING.equalsIgnoreCase(input.trim())) { strategy = new RuleControllerTurnOffCommandStrategy(); } return strategy; } } ``` **Spec 33** - The class *RuleControllerCommandStrategyFactory* &nbsp; #### Pros * Delegation of algorithm implementation to each strategy; * Delegation of algorithm selection to the factory; * Cleaner code with less if-elses; * Easy to expand existing functionality by creating more strategies and adding their selection criteria to the factory; #### Cons * More classes needed and more packages required to a decent organization. # Conclusion Throughout this project, we tackled various problems using design patterns, we figured out how the use of design patterns would help to evolve the system and we became more familiar and fluent in using them and incorporating them in our thinking. ## Problems Solved Since the start of this project, various problems emerged from interpreting the requirements and trying to translate them into a real system. We believe that the biggest and most structural problem we solved, and the one we are prouder of the solution, now and in its future implications, was how to allow the system to make *Sensors* and *Actuators* collaborate without the need of knowing each other's operation, in order to make an *Action* be triggered by a certain input from a *Sensor*. The *Mediator* pattern became a central figure in our system, by using the *Control Unit, Rule, Condition and Action* to delegate the interaction with the *Sensors* and their *Events* and the *Actuators* and their *Commands*. It really allow the flexibility to evolve the system components independently without breaking the other part's functionality in the process. Its relevance was felt in all components of the system, in retrospective it really feels like a standard we defined early on to define that each component should have its own limited concern and responsibility and that different parts must not be mixed and too dependent on other parts. To avoid an unmanageable dependence between the *Control Unit* and *Sensor*, we used the *Observer* pattern (allied to the *Mediator*) to allow the *Events* detected by the *Sensors* to be communicated to and handled by the *Control Unit* and keeping each class independent. To deal with different types of *Event* readings from Sensors we used the *Template* pattern, providing common functionality to all *Events* but allowing each to implement its specificities. To tackle the existence of different *Actuators* that could do the same function in different ways we used the *Bridge* pattern, allowing us to decouple their abstraction from the implementation. To allow an *Action* to execute a command regardless of the *Actuator* type we used the *Command* pattern. It also allowed us to group various *Commands* and *Actuators* into the same Action to trigger multiple commands at once as if they were a single command, by using the *Composite* pattern. The *State* pattern was used to remember the state of an *Actuator* and provide different behavior in each operation in consonance with the Actuator's state. The *Adapter* pattern also has solved the problem of supporting *Actuators* that don't implement the same interface, by providing a middle class that translates the incompatible commands into the supported ones. The *Strategy and Factory* patterns were very useful to allow the *Condition* to compare any detected Event with the *Events* defined in the *Rules*, by delegating the selection of the correct *Strategy* to the *Factory* and delegating the implementation of each detected event comparison to the *Strategy* without cluttering the *Condition* class. The same patterns were also responsible for allowing a feasible implementation of mathematical operations in *Conditions*, by checking values >, <, = and != to a predefined one, delegating the comparing algorithm to each *Strategy* and the selection to the *Factory*. To deal with the fact that some *Events* would not meet any *Condition*, therefore not triggering any Action, the *Null Object* pattern was also very useful to avoid cluttering the *Control Unit* class with null checks, by defining an inconsequent Action that would do nothing when executed. In the implementation of the user interface, some problems also appeared and were solved with familiar patterns: * The *MVC* pattern allowed the business logic (model) to be separated from the interface that the user interacts with (View) and the logic that defines what information the user will see and what the system would do with the user inputs (Controller). In eventual future interfaces, only new *Controller* and *View* have to be developed, since the *Model* will remain the same. * To avoid code repetition and to centralize all methods needed to the *Controllers* while keeping each Controller's responsibility isolated, the Template method has been used. * The *Command* pattern also allowed us to treat every *Controller* the same way, making the code easy to develop, maintain and evolve. It allowed us also to group various *Controllers* into another with the same functionality by using the *Composite* pattern, allowing more complex expandability in the future. * The challenge of making the *Controllers* deal with various *Event* types and *Commands* was tackled by using another *Strategy and Factory* combination, with the *Controller* delegating the selection of the *Strategy* to the *Factory* and the concrete algorithm implementation to the *Strategy*. ## System evolution Besides the immediate benefits of using patterns, we believe that it has also greater long term advantages: * Extending the functionality of the current implementation only requires adding more specific classes in each pattern and will require minimum changes in the current implementation. Due to being time constrained, we could only implement a limited number of concrete *Events* and *Actuator* types. However, the expansion of the system's feature set in the future would require no changes in its core code. For instance: if we want to implement a new *Event* type that senses spacial movement (x, y, z), we just have to extend the Event class and add the x, y and z variables and implement the displayData method. * To be able to use this new event type on a *Condition* we just need to implement an *EventConditionStrategy* to handle this new concrete *Event* and to add a code line in the *EventConditionStrategyFactory* class to return that *EventConditionStrategy*. The *comparingStrategies* could be also re-used. Creating new *Actuator* functionality would require a new interface in the *Bridge* pattern and an *Actuator* subclass that extends that functionality. To invoke this new *Actuator* in an *Action*, we just need to create a *Command* that invokes the desired *Actuator's* method and executes it. Notice that the *ControlUnit, Condition, Action and Rule* class, the most important classes in our implementation of a smart home automation system, do not require any addition or change to implement these hypothetical new concrete *Event* and *Actuator* type. * To implement the real mode asked in the requirements, that we overlooked in our implementation, we just needed to add a String attribute *httpAddress* to the device, class extended by the *Sensor, Actuator and Control Unit*, and to define in each specific *Actuator* methods the termination of the API that should be called to execute each command. * As a very rough example, while creating a *simpleActuator* we would require to add an http address of the Actuator (e.g. "http://hot/lamp/"), the termination to turn it on (e.g. "/on") and to turn it off (e.g. "/off"). The implementation of the *turnOn* and *turnOff* methods will add a line sending a http request to the concatenation of the *httpAddress* and the *turnOn* and *turnOff* api terminations, respectively. * To integrate popular messaging services into our system, we could use a similar approach, which will probably lead to one more use of the strategy pattern. A *SendCommunicationStrategy* interface that would implement the *sendMessage* method and would have another method to receive all the parameters needed to send the message. Each communication service would have its implementation of this *Strategy*. A command to send a message would be created and the user could choose that command while configuring a *Rule*. * An Event related to messaging systems could also be created, a *ReceiveCommunicationStrategy* interface could encapsulate the logic needed to receive a message and a *MessageEventConditionStrategy* would be used to set a *Condition* that would be triggered via message. * Probably, to avoid code repetition, the *Template* pattern could also be used to encapsulate each communication platform's specific logic (e.g. WhatsApp, Slack, Skype), in various *Abstract [platformName] Communication* classes and each concrete implementation also implementing the *SendCommunicationStrategy* or *ReceiveCommunicationStrategy* to send or receive that platform's messages, respectively. * To implement a fully featured Graphical User Interface, another MVC approach would also be used. The business logic is already implemented in the *Model* and, as stated in the previous paragraphs, can be easily evolved. We would only need to develop a new *Controller* and a new *View* for the system, since the *Model* would be completely reusable from the existent implementation. ## Intimacy with design patterns During this project, we have noticed a drastic increase of our familiarity with design patterns. In the first delivery we face patterns as a requirement of the project and we were trying to find situations in which we could use them and trying to justify their usage. In the second delivery, as noted in the delivery notes, we noticed some real advantages of using patterns in the team work, each member could be doing his/her part and rarely two members would be editing the same class, since each class had its own purpose and responsibility well defined. In this last delivery we figured that no longer we needed to focus on patterns and in how to use them, they simply started pop up in our head when a problem appeared in the implementation. When we thought about how to make the *Controllers* common operations available to all *Controllers*, the *template* pattern came immediately to mind, when we thought about how to handle creating different types of *Events* the *Strategy* and *Strategy Factory* came instinctively as a solution and to allow each specific Controller to be called and its information displayed in the same way regardless of which *Controller* was active, the *Command* pattern came as a logical approach. We end this work by acknowledging how it changed our views about design patterns, and how our relationship with them evolved from viewing them as a strange agent that was forced into our thinking to being a helpful partner that allows us to structure our reasoning and communication, improve our problem solving skills and make our implementations more robust, team work friendly and easy to evolve in the future. # Appendix I ## Full Class Diagram of the Main HoT System. ![](https://i.imgur.com/AnUSmNo.png) ## Full Class Diagram of the GUI of the HoT System. ![](https://i.imgur.com/ixqH4L0.png)