Presentation is loading. Please wait.

Presentation is loading. Please wait.

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

Similar presentations


Presentation on theme: "אביב תשס"ה JCTתיכון תוכנה: ד"ר ראובן גלנט1 פרק 8 נקודות חשובות בתרגילים 7-9."— Presentation transcript:

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

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

3 אביב תשס"ה JCTתיכון תוכנה: ד"ר ראובן גלנט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 אביב תשס"ה JCTתיכון תוכנה: ד"ר ראובן גלנט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 אביב תשס"ה JCTתיכון תוכנה: ד"ר ראובן גלנט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 אביב תשס"ה JCTתיכון תוכנה: ד"ר ראובן גלנט6 Motor Class Create a constructor that creates instances of both types of Sensor: setItsTemperatureSensor(new TemperatureSensor( “ T1 ” )); setItsPressureSensor(new PressureSensor( “ P1 ” ));

7 אביב תשס"ה JCTתיכון תוכנה: ד"ר ראובן גלנט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 אביב תשס"ה JCTתיכון תוכנה: ד"ר ראובן גלנט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 אביב תשס"ה JCTתיכון תוכנה: ד"ר ראובן גלנט9 Derived Classes: TemperatureSensor.cpp //file TemperatureSensor.cpp #include “TemperatureSensor.h” TemperatureSensor::TemperatureSensor(OMString aName): Sensor(aName) { }

10 אביב תשס"ה JCTתיכון תוכנה: ד"ר ראובן גלנט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 אביב תשס"ה JCTתיכון תוכנה: ד"ר ראובן גלנט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 אביב תשס"ה JCTתיכון תוכנה: ד"ר ראובן גלנט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 אביב תשס"ה JCTתיכון תוכנה: ד"ר ראובן גלנט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 אביב תשס"ה JCTתיכון תוכנה: ד"ר ראובן גלנט14 2. Container Classes (OMCollection) and Iterators (OMIterator)

15 אביב תשס"ה JCTתיכון תוכנה: ד"ר ראובן גלנט15 Using OMIterator Rhapsody 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 first while ( *iSensor != NULL ) { (*iSensor)->print();// print ++iSensor;// point to next }

16 אביב תשס"ה JCTתיכון תוכנה: ד"ר ראובן גלנט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 אביב תשס"ה JCTתיכון תוכנה: ד"ר ראובן גלנט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 itsSensor; Note also that there is an operation addItsSensor(Sensor* p_Sensor);

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

19 אביב תשס"ה JCTתיכון תוכנה: ד"ר ראובן גלנט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 אביב תשס"ה JCTתיכון תוכנה: ד"ר ראובן גלנט20 2.a Dependencies

21 אביב תשס"ה JCTתיכון תוכנה: ד"ר ראובן גלנט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 אביב תשס"ה JCTתיכון תוכנה: ד"ר ראובן גלנט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 אביב תשס"ה JCTתיכון תוכנה: ד"ר ראובן גלנט23 Multiple Relation Save / Generate / Make / Run Show that the Motor has a collection of three Sensors.

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

25 אביב תשס"ה JCTתיכון תוכנה: ד"ר ראובן גלנט25 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 << "---------------------" << endl;

26 אביב תשס"ה JCTתיכון תוכנה: ד"ר ראובן גלנט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 אביב תשס"ה JCTתיכון תוכנה: ד"ר ראובן גלנט27 3. Threads, Active Classes, Statechart Inheritance

28 אביב תשס"ה JCTתיכון תוכנה: ד"ר ראובן גלנט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 אביב תשס"ה JCTתיכון תוכנה: ד"ר ראובן גלנט29 Active Classes With the browser, change the concurrency of the Sensor class from sequential to active.

30 אביב תשס"ה JCTתיכון תוכנה: ד"ר ראובן גלנט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 אביב תשס"ה JCTתיכון תוכנה: ד"ר ראובן גלנט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 אביב תשס"ה JCTתיכון תוכנה: ד"ר ראובן גלנט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 אביב תשס"ה JCTתיכון תוכנה: ד"ר ראובן גלנט33 Suspending Threads Note that a thread can be suspended.

34 אביב תשס"ה JCTתיכון תוכנה: ד"ר ראובן גלנט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 אביב תשס"ה JCTתיכון תוכנה: ד"ר ראובן גלנט35 4. Singleton, Abstract Factory

36 אביב תשס"ה JCTתיכון תוכנה: ד"ר ראובן גלנט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 אביב תשס"ה JCTתיכון תוכנה: ד"ר ראובן גלנט37 The Improved Design

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

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

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


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

Similar presentations


Ads by Google