/* The practice of abstraction is central to the creation of software. The single most important abstraction mechanism in C++ is the class. A class captures the common properties of the objects instantiated from it; a class characterizes the common behaviour of all objects that are its instances. Identifying appropriate abstractions is a critical part of programming in C++. To find good abstractions, the programmer must understand the underlying properties of the objects manipulated by the program. To study the class as an abstraction mechanism, we examine a sample program and evaluate its strength and weaknesses, particulary with respect to the choice of classes. ALternative ways of writing the program with different classes and different class relationships appear. General rules of programming style, which will improve other programs, then emerge from rethinking the design and rewriting the code of the sample program. */ // // C++ style // example 1 // /* A hardware store The program determines the price of various configurations of a computer. Two selections must be made when configuring a computer: one for an expansion card and an other for monitor. The slot for an expansion card must contain one of the three options: - CDROM drive - Tape drive - Netword card The monitor must be either: - Monochrom - Color Questions: - Are the classes providing the right abstractions? - Are there ways to eliminate complexity from the program by changing its abstractions? In reading the program, think about how it may be simplified. Write your own version, compile, and run it. What you gain and what you loose with the new version? */ #include <iostream> using namespace std; enum CARD {CDROM, TAPE, NETWORK }; enum MONITOR { MONO, COLOR }; class Card { public: virtual int price() = 0; virtual char *name() = 0; virtual int rebate(); }; class Network : public Card { public: int price(); char *name(); }; class Tape : public Card { public: int price(); char *name(); }; class CDRom : public Card { public: int price(); char *name(); int rebate(); }; class Monitor { public: virtual int price() = 0; virtual char *name() = 0; }; class Color : public Monitor { public: int price(); char *name(); }; class Monochrome : public Monitor { public: int price(); char *name(); }; int Card::rebate() { return 45; } int Network::price() { return 600; } char *Network::name() { return "Network"; } int CDRom::price() { return 1500; } char *CDRom::name() { return "CDRom"; } int CDRom::rebate() { return 135; } int Tape::price() { return 1000; } char *Tape::name() { return "Tape"; } int Color::price() { return 1500; } char *Color::name() { return "Color"; } int Monochrome::price() { return 500; } char *Monochrome::name() { return "Mono"; } class Computer { public: Computer( CARD, MONITOR ); ~Computer(); int netPrice(); void print(); private: Card *card; Monitor *mon; }; Computer::Computer( CARD c, MONITOR m ) { switch( c ) { case NETWORK: card = new Network; break; case CDROM: card = new CDRom; break; case TAPE: card = new Tape; break; } switch( m ) { case MONO: mon = new Monochrome; break; case COLOR: mon = new Color; break; } } Computer::~Computer() { delete card; delete mon; } int Computer::netPrice() { return mon->price() + card->price() - card->rebate(); } void Computer::print() { cout << "Configuration = " << card->name() << ", " << mon->name() << ", net price = " << netPrice() << endl; } int main() { Computer nm( NETWORK, MONO ); Computer cm( CDROM, MONO ); Computer tm( TAPE, MONO ); Computer nc( NETWORK, COLOR ); Computer cc( CDROM, COLOR ); Computer tc( TAPE, COLOR ); nm.print(); cm.print(); tm.print(); nc.print(); cc.print(); tc.print(); return 0; }