40
הההה ההה"הJCT ההההה ההההה: ה"ה ההההה הה הה1 ההה8 הההההה הההההה הההההההה7-9

פרק 8 נקודות חשובות בתרגילים 7-9

  • Upload
    base

  • View
    48

  • Download
    0

Embed Size (px)

DESCRIPTION

פרק 8 נקודות חשובות בתרגילים 7-9. 1. Initializer. Inheritance. Make the PressureSensor and TemperatureSensor inherit from the base class Sensor. Add directed associations from the Motor to the PressureSensor and to the TemperatureSensor. Set the multiplicity to 1. - PowerPoint PPT Presentation

Citation preview

  • 8 7-9

    : "

  • 1. Initializer

    : "

  • InheritanceMake the PressureSensor and TemperatureSensor inherit from the base class Sensor.Add directed associations from the Motor to the PressureSensor and to the TemperatureSensor.Set the multiplicity to 1.

    : "

  • Base Class SensorAdd attribute name of type OMStringAdd a constructor that receives an argument aName of type OMString Initialize the attribute in the initializer name(aName)Create an operation print with implementation std::cout
  • Base Class Sensor-Sensor.cpp//file Sensor.cpp#include Sensor.h

    Sensor::Sensor(OMString aName): name(aName) { }

    void Sensor::print() {std::cout

  • Motor ClassCreate a constructor that creates instances of both types of Sensor:setItsTemperatureSensor(new TemperatureSensor(T1));setItsPressureSensor(new PressureSensor(P1));

    : "

  • Class Motor- Motor.cpp//file Motor.cpp#include Motor.cpp#include Sensor.h Motor::Motor() { setItsTemperatureSensor(new TemperatureSensor(T1)); setItsPressureSensor(new PressureSensor(P1));}

    : "

  • Derived Sensor ClassesFor both derived Sensor classes:Create a constructor that has an argument aName of type OMStringSet the Initializer to Sensor(aName) Sensor(aName) invokes the Sensor constructor so as to initialize the name field of the base class.

    : "

  • Derived Classes: TemperatureSensor.cpp//file TemperatureSensor.cpp#include TemperatureSensor.h

    TemperatureSensor::TemperatureSensor(OMString aName): Sensor(aName) { }

    : "

  • AnimatingCreate a Test component and a Debug configuration that creates an initial instance of the Motor classSave / Generate / Make / Run With the browser, note that there are two instances of Sensor. Each Sensor has a name that has been initialized.

    : "

  • User TypesUsing the browser, right-click on the Default package and select Add New Type add a type tTempUnits declared asenum tTempUnits { CELSIUS, FAHRENHEIT };An alternative declaration is :enum %s { CELSIUS, FAHRENHEIT }.

    : "

  • Attribute UnitAdd an attribute unit of type tTempUnits for the TemperatureSensor.Add an argument to the TemperatureSensor constructor called aUnit of the same type In the initializer add ,unit(aUnit)

    : "

  • TemperatureSensorChange the read operation to :std::cout
  • 2. Container Classes (OMCollection)andIterators(OMIterator)

    : "

  • Using OMIteratorRhapsody provides an OMIterator class that can be used as follows to iterate through a container:OMCollection itsSensor; // a container

    OMIterator iSensor(itsSensor);iSensor.reset(); // point to firstwhile ( *iSensor != NULL ) { (*iSensor)->print();// print ++iSensor;// point to next}

    : "

  • Collection of SensorsLoad the Virtual project and save as CollectionDelete from Model the relations between the Motor and the Sensors. Check in the Browser that these relations have been deleted from the model not just the view.Add a directed aggregation itsSensor from the Motor to the Sensor. Set Multiplicity to * (many).

    : "

  • OMCollectionDelete implementation of Motor constructorSave / Generate / Examine code for MotorNote that the relation has been implemented as a collection of Sensors: OMCollection itsSensor;Note also that there is an operation addItsSensor(Sensor* p_Sensor);

    : "

  • OMCollection: Motor.h#ifndef Motor_H #define Motor_H #include "PressureSensor.h"#include "TemperatureSensor.h"class Sensor;public : //defined by user void addSensor(); void deleteSensor(); void pollSensors();

    public: //defined by Rhapsody OMIterator getItsSensor() const; void addItsSensor(Sensor* p_Sensor); void removeItsSensor(Sensor* p_Sensor); void clearItsSensor();

    protected : OMCollection itsSensor;};#endif

    : "

  • Adding to OMCollectionIn the motor constructor add Sensors:addItsSensor(new TemperatureSensor(Sensor1,CELSIUS));addItsSensor(new TemperatureSensor(Sensor2,FAHRENHEIT));addItsSensor(new PressureSensor(Sensor3) );

    : "

  • 2.a Dependencies

    : "

  • DependenciesIn order to compile, the Motor needs to include the Pressure and Temperature Sensors header files. To do this we will add dependencies from the Motor to those classes:Double-click on each dependency and select the stereotype Usage.

    : "

  • Implementation IncludesAlternatively instead of drawing dependencies, we can just modify the properties for the Motor class and for CPP_CG->Class->ImpIncludes add TemperatureSensor.h,PressureSensor.hCPP_CG means C++ Code Generation.

    : "

  • Multiple RelationSave / Generate / Make / RunShow that the Motor has a collection of three Sensors.

    : "

  • StatechartCreate a simple Statechart for the Motor class that calls a pollSensors() routine every two seconds.

    : "

  • pollSensors()Create the pollSensors() operation that will poll all the Sensors in the collection:Note that if any more Sensors of any other type are added, the operation still functions!OMIterator iSensor(itsSensor);for ( iSensor.reset(); *iSensor; ++iSensor ) { (*iSensor)->print(); (*iSensor)->read();} cout
  • Extended ExerciseFor the Sensor class, add a static attribute numberOfSensors of type int with initial value 0.In the Sensor Constructor add numberOfSensors++;For the Sensor class, add a virtual Destructor with implementation : numberOfSensors--;Add the following to pollSensors() cout
  • 3. Threads, Active Classes, Statechart Inheritance

    : "

  • ConcurrencyWe want each Sensor to run on its own thread (active class). To do so, we need each Sensor to be Reactive (class that waits for events). So we will create a Statechart for the base Sensor class as follows:

    : "

  • Active ClassesWith the browser, change the concurrency of the Sensor class from sequential to active.

    : "

  • Inheriting BehaviorOpen the Statecharts for the PressureSensor and TemperatureSensor. Note that they have inherited the base class Statechart.Specialize the behavior of the TemperatureSensor as below:Grayed out indicatinginherited behavior

    : "

  • Starting the BehaviorAdd a call to startBehavior() from the TemperatureSensor and PressureSensor constructors to initialize the statecharts.If we had used a composite class, Rhapsody would have done this for us, but that would have been too easy !

    : "

  • Multi-threadsSave / Generate / Make / RunCheck that there are four active threads.Setting the focus to a particular thread displays the call stack and event queue for that thread. There will always be one thread called mainThread.

    : "

  • Suspending ThreadsNote that a thread can be suspended.

    : "

  • Problems with the DesignWith the current design there are a few potential problems:The Motor class needs to know about all the different types of Sensor.If another class wants access to the Sensors, it too will need to depend upon all the different types of Sensor.Starting the behavior of a Sensor, in the constructor is not very elegant.Adding a new type of Sensor means finding and modifying all classes that use Sensor.

    : "

  • 4. Singleton, Abstract Factory

    : "

  • Improving the DesignUsing the factory method design pattern will solve all these concerns.A SensorFactory class can be introduced that is used by all classes ( ex: Motor ) that need to get a Sensor. This decouples the Motor class from the actual Sensors and can also start the behavior of the Sensors.The SensorFactory will be implemented using the Singleton design pattern (to ensure that there is only one instance of SensorFactory). See the SensorFactory example.

    : "

  • The Improved Design

    : "

  • The Singleton Design Pattern IProtectedconstructorStatic attribute

    : "

  • The Singleton Design Pattern IIStatic factoryoperationCalling thecreateRandomSensoroperation

    : "

  • SensorFactory::createRandomSensor()Sensor * SensorFactory::createRandomSensor(){ Sensor* aSensor; OMString aName; char index[10];

    //itoa(Sensor::getCount(), index, 10); strcpy ( index, "1" ); aName = "Sensor" + OMString(index);

    switch ( rand() % 4 ) { default: case 0: aSensor = new TemperatureSensor( aName, CELSIUS ); break; case 1: aSensor= new TemperatureSensor( aName, FAHRENHEIT ); break; case 2: aSensor = new PressureSensor( aName ); break; case 3: aSensor = new SpeedSensor( aName ); break; } aSensor->startBehavior(); return aSensor;}

    : "