1 / 40

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

פרק 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.

base
Download Presentation

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

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. פרק 8נקודות חשובות בתרגילים 7-9 תיכון תוכנה: ד"ר ראובן גלנט

  2. 1. Initializer תיכון תוכנה: ד"ר ראובן גלנט

  3. 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. תיכון תוכנה: ד"ר ראובן גלנט

  4. Base Class Sensor • Add attribute name of type OMString • Add 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 << name << “ “; תיכון תוכנה: ד"ר ראובן גלנט

  5. Base Class Sensor-Sensor.cpp //file Sensor.cpp #include “Sensor.h” Sensor::Sensor(OMString aName): name(aName) { } void Sensor::print() {std::cout << name << “ “;} תיכון תוכנה: ד"ר ראובן גלנט

  6. Motor Class • Create a constructor that creates instances of both types of Sensor: • setItsTemperatureSensor(new TemperatureSensor(“T1”)); • setItsPressureSensor(new PressureSensor(“P1”)); תיכון תוכנה: ד"ר ראובן גלנט

  7. Class Motor- Motor.cpp //file Motor.cpp #include “Motor.cpp #include “Sensor.h” Motor::Motor() { setItsTemperatureSensor(new TemperatureSensor(“T1”)); setItsPressureSensor(new PressureSensor(“P1”)); } תיכון תוכנה: ד"ר ראובן גלנט

  8. Derived Sensor Classes • For both derived Sensor classes: • Create a constructor that has an argument aName of type OMString • Set the Initializer to Sensor(aName) Sensor(aName) invokes the Sensor constructor so as to initialize the name field of the base class. תיכון תוכנה: ד"ר ראובן גלנט

  9. Derived Classes: TemperatureSensor.cpp //file TemperatureSensor.cpp #include “TemperatureSensor.h” TemperatureSensor::TemperatureSensor(OMString aName): Sensor(aName) { } תיכון תוכנה: ד"ר ראובן גלנט

  10. Animating • Create a Test component and a Debug configuration that creates an initial instance of the Motor class • Save / Generate / Make / Run • With the browser, note that there are two instances of Sensor. Each Sensor has a name that has been initialized. תיכון תוכנה: ד"ר ראובן גלנט

  11. User Types • Using the browser, right-click on the Default package and select “Add New Type” • add a type tTempUnits declared as • enum tTempUnits { CELSIUS, FAHRENHEIT }; An alternative declaration is : enum %s { CELSIUS, FAHRENHEIT}. תיכון תוכנה: ד"ר ראובן גלנט

  12. Attribute Unit • Add 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) תיכון תוכנה: ד"ר ראובן גלנט

  13. TemperatureSensor • Change the read operation to : std::cout << “Temperature = “ << rand() % 100 << “deg “; if ( unit == CELSIUS ) std::cout << “C” << std::endl; else std::cout << “F” << std::endl; • In the Motor constructor, add the argument “CELSIUS” as follows: setItsTemperatureSensor (new TemperatureSensor( “T1”, CELSIUS)); תיכון תוכנה: ד"ר ראובן גלנט

  14. 2. Container Classes (OMCollection)andIterators(OMIterator) תיכון תוכנה: ד"ר ראובן גלנט

  15. Using OMIterator • Rhapsody provides an OMIterator class that can be used as follows to iterate through a container: • OMCollection<Sensor*> itsSensor; // a container • OMIterator<Sensor*> iSensor(itsSensor); • iSensor.reset(); // point to first • while ( *iSensor != NULL ) { • (*iSensor)->print(); // print • ++iSensor; // point to next • } תיכון תוכנה: ד"ר ראובן גלנט

  16. Collection of Sensors • Load the “Virtual” project and save as “Collection” • Delete 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). תיכון תוכנה: ד"ר ראובן גלנט

  17. OMCollection • Delete implementation of Motor constructor • Save / Generate / Examine code for Motor • Note that the relation has been implemented as a collection of Sensors: OMCollection<Sensor*> itsSensor; • Note also that there is an operation addItsSensor(Sensor* p_Sensor); תיכון תוכנה: ד"ר ראובן גלנט

  18. 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<Sensor*> getItsSensor() const; void addItsSensor(Sensor* p_Sensor); void removeItsSensor(Sensor* p_Sensor); void clearItsSensor(); protected : OMCollection<Sensor*> itsSensor; }; #endif תיכון תוכנה: ד"ר ראובן גלנט

  19. Adding to OMCollection • In the motor constructor add Sensors: • addItsSensor(new TemperatureSensor(“Sensor1”,CELSIUS)); • addItsSensor(new TemperatureSensor(“Sensor2”,FAHRENHEIT)); • addItsSensor(new PressureSensor(“Sensor3”) ); תיכון תוכנה: ד"ר ראובן גלנט

  20. 2.a Dependencies תיכון תוכנה: ד"ר ראובן גלנט

  21. Dependencies • In 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. תיכון תוכנה: ד"ר ראובן גלנט

  22. Implementation Includes • Alternatively instead of drawing dependencies, we can just modify the properties for the Motor class and for CPP_CG->Class->ImpIncludes add TemperatureSensor.h,PressureSensor.h CPP_CG means C++ Code Generation. תיכון תוכנה: ד"ר ראובן גלנט

  23. Multiple Relation • Save / Generate / Make / Run • Show that the Motor has a collection of three Sensors. תיכון תוכנה: ד"ר ראובן גלנט

  24. Statechart • Create a simple Statechart for the Motor class that calls a pollSensors() routine every two seconds. תיכון תוכנה: ד"ר ראובן גלנט

  25. pollSensors() • Create the pollSensors() operation that will poll all the Sensors in the collection: • OMIterator<Sensor*> iSensor(itsSensor); • for ( iSensor.reset(); *iSensor; ++iSensor ) { • (*iSensor)->print(); • (*iSensor)->read(); • } • cout << "---------------------" << endl; Note that if any more Sensors of any other type are added, the operation still functions! תיכון תוכנה: ד"ר ראובן גלנט

  26. Extended Exercise • For 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 << “Number of sensors = “ << Sensor::getNumberOfSensors() << endl; • Generate code and execute to check that numberOfSensors = 3. תיכון תוכנה: ד"ר ראובן גלנט

  27. 3. Threads, Active Classes, Statechart Inheritance תיכון תוכנה: ד"ר ראובן גלנט

  28. Concurrency • We 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: תיכון תוכנה: ד"ר ראובן גלנט

  29. Active Classes • With the browser, change the concurrency of the Sensor class from sequential to active. תיכון תוכנה: ד"ר ראובן גלנט

  30. Inheriting Behavior • Open 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 indicating inherited behavior תיכון תוכנה: ד"ר ראובן גלנט

  31. Starting the Behavior • Add 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 ! תיכון תוכנה: ד"ר ראובן גלנט

  32. Multi-threads • Save / Generate / Make / Run • Check 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. תיכון תוכנה: ד"ר ראובן גלנט

  33. Suspending Threads • Note that a thread can be suspended. תיכון תוכנה: ד"ר ראובן גלנט

  34. Problems with the Design • With 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. תיכון תוכנה: ד"ר ראובן גלנט

  35. 4. Singleton, Abstract Factory תיכון תוכנה: ד"ר ראובן גלנט

  36. Improving the Design • Using 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. תיכון תוכנה: ד"ר ראובן גלנט

  37. The Improved Design תיכון תוכנה: ד"ר ראובן גלנט

  38. The Singleton Design Pattern I Static attribute Protected constructor תיכון תוכנה: ד"ר ראובן גלנט

  39. The Singleton Design Pattern II Static factory operation Calling the createRandomSensor operation תיכון תוכנה: ד"ר ראובן גלנט

  40. 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; } תיכון תוכנה: ד"ר ראובן גלנט

More Related