Selected C++ Example #4
// Example #4
// This C++ example illustrates the better method for implementing
// a fragment of the home heating system example described in
// Booch's OOA/D book. This better solution pushes higher-level
// functionality onto the Room class, making the heat flow
// regulator less god-like.
// This example illustrates several examples of containment. If
// you are unfamiliar with the concept of containment, please read
// Chapter 4 before working through this example.
#include <iostream.h>
#include <stdlib.h>
#include <string.h>
// Constants used in this example.
const int name_len = 50;
const int large_strlen = 128;
const int room_len = 20;
// These sensor classes are identical to those in the previous
// example. See the comments on the classes in that example for
// further information.
class DesiredTempActuator {
public:
int get_temp();
};
// Returns a random number from 50 to 90
int
DesiredTempActuator::get_temp()
{
return(random(41) + 50);
}
class ActualTempSensor {
public:
int get_temp();
};
int
ActualTempSensor::get_temp()
{
return(random(41) + 50);
}
class OccupancySensor {
public:
int anyone_in_room();
};
// Returns a random value (0 or 1)
int
OccupancySensor::anyone_in_room()
{
return(random(2) % 2);
}
// The Room class contains a desired temperature input device, a
// temperature sensor, and an occupancy sensor (all by value). It
// has a name attribute for descriptive information.
// Note that the accessor methods have been eliminated in favor of
// a ''do_you_need_heat()'' method.
class Room {
char name[name_len];
DesiredTempActuator dtemp;
ActualTempSensor atemp;
OccupancySensor occ;
public:
Room(char*);
int do_you_need_heat();
};
Room::Room(char* n)
{
strncpy(name, n, name_len);
}
// The Room object determines if it needs heat by calculating its
// working temperature (desired - actual) and checking if anyone
// is in the room. The room needs heat if the actual temperature
// is less than the desired temperature and someone is in the room,
// OR if no one is in the room and the actual temperature is more than
// five degrees less than the desired temperature.
// The method returns one if heat is needed and zero if not.
int
Room::do_you_need_heat()
{
int working_temp, occupied;
working_temp = dtemp.get_temp() - atemp.get_temp();
occupied = occ.anyone_in_room();
cout << ''The'' << name << '' has a working temp of '' <<
working_temp;
cout << '' and '' << (occupied ? ''someone in the room.\n'' :
''no one in the room.\n'');
if (working_temp > 5 || working_temp > 0 && occupied) {
return(1);
}
return(0);
}
// Our furnace does little in this implementation of a design
// fragment because it is relatively uninteresting to illustrate
// the problem of poorly related data and behavior.
class Furnace {
public:
void provide_heat();
void turnoff();
};
void
Furnace::provide_heat()
{
cout << ''Furnace Running\n'';
}
void
Furnace::turnoff()
{
cout << ''Furnace Turned Off\n'';
}
// The heat flow regulator does not contain a list of rooms and a
// furnace. It is associated with them. There is a very large
// difference between stating that a class contains an object by
// reference, or a class is associated with an object. See
// Chapter 7 for an indepth discussion on this subject.
class HeatFlowRegulator {
Room *house[room_len];
Furnace *heater;
int room_num;
public:
HeatFlowRegulator(Furnace*, int, Room**);
int loop();
};
// This constructor is identical to the one of the previous
// example.
HeatFlowRegulator::HeatFlowRegulator(Furnace* f, int num, Room
**rooms)
{
int i;
heater = f;
room_num = num;
for (i=0; i < room_num; i++) {
house[i] = rooms[i];
}
}
// The looping of the heat flow regulator is to check each room to see
// if it needs heat. In order to do this, the regulator simply asks
// the room if it needs heat. The work of figuring out if heat is
// needed has been pushed onto the Room class, which contains the
// necessary information.
int
HeatFlowRegulator::loop()
{
int anyone_need_heat=0, i;
for (i=0; i < room_num; i++) {
anyone_need_heat += house[i]->do_you_need_heat();
}
if (anyone_need_heat)
heater->provide_heat();
else
heater->turnoff();
return(anyone_need_heat);
}
void
main()
{
int room_num, i, retval;
Furnace our_furnace;
Room *rooms[room_len];
char buffer[large_strlen];
cout << ''How many rooms in your house? '';
cin >> room_num;
cin.get();
if (room_num > room_len)
room_num = room_len;
for (i=0; i < room_num; i++){
cout << ''What is the name of room['' << (i+1) << '']? '';
cin.getline(buffer, large_strlen, '\n');
rooms[i] = new Room(buffer);
}
HeatFlowRegulator h(&our_furnace, room_num, rooms);
do{
retval = h.loop();
cout << retval << '' rooms required heat!\n'';
cout << ''Continue? '';
cin.getline(buffer, large_strlen, '\n');
} while (buffer[0] == 'y');
}
|