⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ch18.htm

📁 一本好的VC学习书,本人就是使用这本书开始学习的vc,希望能对大家有帮助
💻 HTM
📖 第 1 页 / 共 5 页
字号:
<H4 ALIGN="CENTER"><A NAME="Heading24"></A><FONT COLOR="#000077">Application ProgramInterface</FONT></H4><P>An Application Program Interface (API) is a set of documentation and routinesfor using a service. Many of the mail providers will give you an API so that PostMastermail will be able to take advantage of their more advanced features, such as richtext and embedding files. PostMaster will also want to publish its own API so thatother providers can plan for working with PostMaster in the future.</P><P>Your <TT>PostMasterMessage</TT> class will want to have a well-designed publicinterface, and the conversion functions will be a principal component of PostMaster'sAPI. Listing 18.2 illustrates what <TT>PostMasterMessage</TT>'s interface looks likeso far.</P><P><A NAME="Heading25"></A><FONT SIZE="4" COLOR="#000077"><B>Listing 18.2. PostMasterMessagesinterface</B></FONT></P><PRE><FONT COLOR="#0066FF">1:     class PostMasterMessage : public MailMessage2:     {3:     public:4:       PostMasterMessage();5:       PostMasterMessage(6:           pAddress Sender,7:           pAddress Recipient,8:           pString Subject,9:           pDate creationDate);10:11:      // other constructors here12:      // remember to include copy constructor13:      // as well as constructor from storage14:      // and constructor from wire format15:      // Also include constructors from other formats16:      ~PostMasterMessage();17:      pAddress&amp; GetSender() const;18:      void SetSender(pAddress&amp;);19:      // other member accessors20:21:      // operator methods here, including operator equals22:      // and conversion routines to turn PostMaster messages23:      // into messages of other formats.24:25:    private:26:       pAddress itsSender;27:       pAddress itsRecipient;28:       pString  itsSubject;29:       pDate itsCreationDate;30:       pDate itsLastModDate;31:       pDate itsReceiptDate;32:       pDate itsFirstReadDate;33:       pDate itsLastReadDate;<TT>34: };</TT></FONT></PRE><P><FONT COLOR="#000000"><B><BR>Output: </B></FONT>None. <BR><FONT COLOR="#000077"><B><BR>Analysis: </B></FONT>Class <TT>PostMasterMessage</TT> is declared to derive from<TT>MailMessage</TT>. A number of constructors will be provided, facilitating thecreation of <TT>PostMasterMessage</TT>s from other types of mail messages.</P><P>A number of accessor methods are anticipated for reading and setting the variousmember data, as well as operators for turning all or part of this message into othermessage formats. You anticipate storing these messages to disk and reading them fromthe wire, so accessor methods are needed for those purposes as well.<H4 ALIGN="CENTER"><A NAME="Heading27"></A><FONT COLOR="#000077">Programming in LargeGroups</FONT></H4><P>Even this preliminary architecture is enough to indicate how the various developmentgroups ought to proceed. The communications group can go ahead and start work onthe communications back end, negotiating a narrow interface with the message formatgroup.</P><P>The message format group will probably lay out the general interface to the <TT>Message</TT>classes, as was begun above, and then will turn its attention to the question ofhow to write data to the disk and read it back. Once this disk interface is wellunderstood, they will be in a good position to negotiate the interface to the communicationslayer.</P><P>The message editors will be tempted to create editors with an intimate knowledgeof the internals of the <TT>Message</TT> class, but this would be a bad design mistake.They too must negotiate a very narrow interface to the <TT>Message</TT> class; messageeditor objects should know very little about the internal structure of messages.<H4 ALIGN="CENTER"><A NAME="Heading28"></A><FONT COLOR="#000077">Ongoing Design Considerations</FONT></H4><P>As the project continues, you will repeatedly confront this basic design issue:In which class should you put a given set of functionality (or information)? Shouldthe <TT>Message</TT> class have this function, or should the <TT>Address</TT> class?Should the editor store this information, or should the message store it itself?</P><P>Your classes should operate on a &quot;need to know&quot; basis, much like secretagents. They shouldn't share any more knowledge than is absolutely necessary.<H3 ALIGN="CENTER"><A NAME="Heading29"></A><FONT COLOR="#000077">Design Decisions</FONT></H3><P>As you progress with your program, you will face hundreds of design issues. Theywill range from the more global questions, &quot;What do we want this to do?&quot;to the more specific, &quot;How do we make this work?&quot;</P><P>While the details of your implementation won't be finalized until you ship thecode, and some of the interfaces will continue to shift and change as you work, youmust ensure that your design is well understood early in the process. It is imperativethat you know what you are trying to build before you write the code. The singlemost frequent cause of software dying on the vine must be that there was not sufficientagreement early enough in the process about what was being built.<H4 ALIGN="CENTER"><A NAME="Heading30"></A><FONT COLOR="#000077">Decisions, Decisions</FONT></H4><P>To get a feel for what the design process is like, examine this question, &quot;Whatwill be on the menu?&quot; For PostMaster, the first choice is probably &quot;newmail message,&quot; and this immediately raises another design issue: When the userpresses <TT>New Message</TT>, what happens? Does an editor get created, which inturn creates a mail message, or does a new mail message get created, which then createsthe editor?</P><P>The command you are working with is &quot;new mail message,&quot; so creatinga new mail message seems like the obvious thing to do. But what happens if the userhits Cancel after starting to write the message? Perhaps it would be cleaner to firstcreate the editor and have it create (and own) the new message.</P><P>The problem with this approach is that the editor will need to act differentlyif it is creating a message than if it is editing the message, whereas if the messageis created first and then handed to the editor, only one set of code need exist:Everything is an edit of an existing message.</P><P>If a message is created first, who creates it? Is it created by the menu commandcode? If so, does the menu also tell the message to edit itself, or is this partof the constructor method of the message?</P><P>It makes sense for the constructor to do this at first glance; after all, everytime you create a message you'll probably want to edit it. Nonetheless, this is nota good design idea. First, it is very possible that the premise is wrong: You maywell create &quot;canned&quot; messages (that is, error messages mailed to the systemoperator) that are not put into an editor. Second, and more important, a constructor'sjob is to create an object; it should do no more and no less than that. Once a mailmessage is created, the constructor's job is done; adding a call to the edit methodjust confuses the role of the constructor and makes the mail message vulnerable tofailures in the editor.</P><P>What is worse, the edit method will call another class, the editor, causing itsconstructor to be called. Yet the editor is not a base class of the message, noris it contained within the message; it would be unfortunate if the construction ofthe message depended on successful construction of the editor.</P><P>Finally, you won't want to call the editor at all if the message can't be successfullycreated; yet successful creation would, in this scenario, depend on calling the editor!Clearly you want to fully return from the message's constructor before calling <TT>Message::Edit()</TT>.<BLOCKQUOTE>	<P><HR><B>DO </B>look for objects that arise naturally out of your design.<B> DO</B> redesign	as your understanding of the problem space improves.<B> DON'T</B> share more information	among the classes than is absolutely necessary. <B>DO</B> look for opportunities	to take advantage of C++'s polymorphism. <HR></BLOCKQUOTE><H3 ALIGN="CENTER"><A NAME="Heading31"></A><FONT COLOR="#000077">Working with DriverPrograms</FONT></H3><P>One approach to surfacing design issues is to create a driver program early inthe process. For example, the driver program for PostMaster might offer a very simplemenu, which will create <TT>PostMasterMessage</TT> objects, manipulate them, andotherwise exercise some of the design.</P><DL>	<DD><HR><FONT COLOR="#000077"><B>New Term:</B></FONT><B> </B>A <I>driver program</I> is a	function that exists only to demonstrate or test other functions. <HR></DL><P>Listing 18.3 illustrates a somewhat more robust definition of the <TT>PostMasterMessage</TT>class and a simple driver program.</P><P><A NAME="Heading32"></A><FONT SIZE="4" COLOR="#000077"><B>Listing 18.3. A driverprogram for PostMasterMessage.</B></FONT></P><PRE><FONT COLOR="#0066FF">1:     #include &lt;iostream.h&gt;2:     #include &lt;string.h&gt;3:4:     typedef unsigned long pDate;5:     enum SERVICE 6:       { PostMaster, Interchange, CompuServe, Prodigy, AOL, Internet };7:     class String8:     {9:        public:10:          // constructors11:          String();12:           String(const char *const);13:           String(const String &amp;);14:          ~String();15:16:          // overloaded operators17:          char &amp; operator[](int offset);18:          char operator[](int offset) const;19:          String operator+(const String&amp;);20:          void operator+=(const String&amp;);21:          String &amp; operator= (const String &amp;);22:          friend ostream&amp; operator&lt;&lt;23:             ( ostream&amp; theStream,String&amp; theString);24:          // General accessors25:          int GetLen()const { return itsLen; }26:          const char * GetString() const { return itsString; }27:          // static int ConstructorCount;28:       private:29:          String (int);         // private constructor30:          char * itsString;31:          unsigned short itsLen;32:33:    };34:35:    // default constructor creates string of 0 bytes36:    String::String()37:    {38:       itsString = new char[1];39:       itsString[0] = `\0';40:       itsLen=0;41:       // cout &lt;&lt; &quot;\tDefault string constructor\n&quot;;42:       // ConstructorCount++;43:    }44:45:    // private (helper) constructor, used only by46:    // class methods for creating a new string of47:    // required size.  Null filled.48:    String::String(int len)49:    {50:       itsString = new char[len+1];51:       for (int i = 0; i&lt;=len; i++)52:          itsString[1] = `\0';53:       itsLen=len;54:       // cout &lt;&lt; &quot;\tString(int) constructor\n&quot;;55:       // ConstructorCount++;56:    }57:58:    // Converts a character array to a String59:    String::String(const char * const cString)60:    {61:       itsLen = strlen(cString);62:       itsString = new char[itsLen+1];63:       for (int i = 0; i&lt;itsLen; i++)64:          itsString[i] = cString[i];65:       itsString[itsLen]='\0';66:       // cout &lt;&lt; &quot;\tString(char*) constructor\n&quot;;67:       // ConstructorCount++;68:    }69:70:    // copy constructor71:    String::String (const String &amp; rhs)72:    {73:       itsLen=rhs.GetLen();74:       itsString = new char[itsLen+1];75:       for (int i = 0; i&lt;itsLen;i++)76:          itsString[i] = rhs[i];77:       itsString[itsLen] = `\0';78:       // cout &lt;&lt; &quot;\tString(String&amp;) constructor\n&quot;;79:       // ConstructorCount++;80:    }81:82:    // destructor, frees allocated memory83:    String::~String ()84:    {85:       delete [] itsString;86:       itsLen = 0;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -