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

📄 index.html

📁 《Big C++ 》Third Edition电子书和代码全集-Part1
💻 HTML
📖 第 1 页 / 共 4 页
字号:

<ul>
	<li>To sort by ascending salary:
		<blockquote>
<pre>class SalaryComparator
{
public:
   bool operator()(const Employee&amp; a, const Employee&amp; b)
   {
      return a.get_salary() &lt; b.get_salary();
   }
};</pre>
		</blockquote>
	</li>
	<li>No state</li>
	<li>Its sole purpose is to execute a function</li>
</ul>

</font>

<hr><h2><font color="#009999">26.5.1 Function Objects (cont.)</font></h2>
<font size="+1">

<ul>
	<li>Client is ignorant of sort implementation</li>
	<li>Sort compares using:
		<blockquote>
<pre>if (!comp(x, y))
	 <i>rearrange x and y</i>;</pre>
		</blockquote>
	</li>
	<li><tt>comp</tt> is the object we passed in</li>
	<li><tt>comp(x, y)</tt> invokes <tt>SalaryComparator::operator()</tt></li>
	<li>Any sense of comparison is now possible</li>
</ul>

</font>

<hr><h2><font color="#009999">26.5.1 Function Objects (cont.)</font></h2>
<font size="+1">

<ul>
	<li>Add attributes to extend functionality:
		<blockquote>
<pre>class SalaryComparator
{
public:
   SalaryComparator(bool a) : ascending(a) {}

   bool operator()(const Employee&amp; a, const Employee&amp; b)
   {
      if (ascending)
         return a.get_salary() &lt; b.get_salary();
      else
         return a.get_salary() &gt; b.get_salary();
   }

private:
   bool ascending;
}</pre>
		</blockquote>
	</li>
</ul>

</font>

<hr><h2><font color="#009999">26.5.1 Function Objects (cont.)</font></h2>
<font size="+1">

<ul>
	<li>Use
		<blockquote><tt>
			SalaryComparator reverse_comp(false);
		</tt></blockquote>
		to sort by decreasing salary
	</li>
	<li>When creating an unnamed object:
		<blockquote><tt>
			sort(staff.begin(), staff.end(), SalaryComparator() ):
		</tt></blockquote>
	</li>
	<li>Note the parenthesis after <tt>SalaryComparator</tt></li>
	<li>Creates an object using default c'tor</li>
	<li>Must pass in an object, not a type</li>
</ul>

<hr><h2><font color="#009999">26.5.2 The STRATEGY Pattern</font></h2>
<font size="+1">

<ul>
	<li>Comparator object provides a great deal of flexibility</li>
	<li>This is an example of the STRATEGY pattern</li>
	<li>Applies whenever you want to allow a client to supply an algorithm</li>
	<li>Pattern places the essential steps in a strategy i/f</li>
	<li>Vary algorithm by supplying different classes</li>
</ul>

</font>

<hr><h2><font color="#009999">Pattern STRATEGY</font></h2>
<font size="+1">
<hr color="#00ffff" size="6">

<h3><font color="#009999">Context</font></h3>

<ol>
	<li>A class (the <i>context</i> class) can benefit from variants on an
		algorithm</li>
	<li>Clients of the context class can supply custom versions of the
		algorithm</li>
</ol>

</font>

<hr><h2><font color="#009999">Pattern STRATEGY</font></h2>
<font size="+1">
<hr color="#00ffff" size="6">

<h3><font color="#009999">Solution</font></h3>

<table cellpadding='5'>
	<tr>
		<td valign='top'><font size='+1'>
			<ol>
				<li>Define the <i>strategy i/f</i>, an abstraction for the
					algorithm</li>
				<li>Concrete strategy classes implement the strategy i/f;
					each class defines a version of the algorithm</li>
				<li>Client supplies a concrete strategy object to the context class</li>
				<li>The context class calls the appropriate functions of the strategy
					object</li>
			</ol>
		</font>
		</td>
		<td>
			<script><!--
				image( "un06.png" )
			//--></script>
		</td>
	</tr>
</table>

</font>

<hr><h2><font color='#009999'>26.5.2 The STRATEGY Pattern</font></h2>
<font size="+1">

<ul>
	<table border='1' cellpadding='4'>
		<tr bgcolor='#00ffff'>
			<th width='50%'>Name in Design Pattern</th>
			<th width='50%'>Actual Name (String Streams)</th>
		</tr>
		<tr>
			<td align='center'><tt>Context</tt></td>
			<td align='center'><tt>sort</tt> function</td>
		</tr>
		<tr>
			<td align='center'><tt>Strategy</tt></td>
			<td align='center'>The i/f that <tt>sort</tt> expects <tt>comparator</tt>
				to have, i.e., <tt>operator()</tt></td>
		</tr>
		<tr>
			<td align='center'><tt>ConcreteStrategy</tt></td>
			<td align='center'>The <tt>comparator</tt> class</td>
		</tr>
		<tr>
			<td align='center'><tt>do_work()</tt></td>
			<td align='center'>The <tt>operator()</tt></td>
		</tr>
	</table>
</ul>

</font>

<hr><h2><font color='#009999'>26.6 The COMPOSITE Pattern</font></h2>
<font size='+1'>

<ul>
	<li>Consider the invoice program (chptr 13)</li>
	<li>Lists an item, quantity, and unit price</li>
	<li>We'd like to add <i>bundles</i> of items</li>
	<li>Sol'n:  inherit <tt>Bundle</tt> from <tt>Item</tt>
		<blockquote>
<pre>class Bundle : public Item
{
   . . .
private:
   vector&lt;Item*&gt; items;
};</pre>
		</blockquote>
	</li>
</ul>

</font>

<hr><h2><font color='#009999'>26.6 The COMPOSITE Pattern (cont.)</font></h2>
<font size='+1'>

<ul>
	<li>Example of the COMPOSITE pattern</li>
	<li>Pimitive objects can be grouped into composite objects</li>
	<li>Composites are primitives</li>
	<li>E.g., in an HTML editor, elements can be grouped in a table, and the
		table is an element</li>
</ul>

</font>

<hr><h2><font color='#009999'>26.6 The COMPOSITE Pattern (cont.)</font></h2>
<font size='+1'>

<ul>
	<li>Functions of the composite class must be applied to all primitives, then
		combine the results</li>
	<li>E.g., compute the price of a bundle:
		<blockquote>
<pre>double Bundle::get_unit_price() const
{
   double price = 0;
   for (int i = 0; i &lt; items.size(); i++)
   {
      price = price +
         ( items[i]-&gt;get_unit_price()
            * items[i]-&gt;get_quantity() );
   }
   return price;
}</pre>
		</blockquote>
	</li>
</ul>

</font>

<hr><h2><font color="#009999">Pattern COMPOSITE</font></h2>
<font size="+1">
<hr color="#00ffff" size="6">

<h3><font color="#009999">Context</font></h3>

<ol>
	<li>Primitive objects can be combined into composite objects</li>
	<li>Clients treat a composite as a primitive</li>
</ol>

</font>

<hr><h2><font color="#009999">Pattern COMPOSITE</font></h2>
<font size="+1">
<hr color="#00ffff" size="6">

<h3><font color="#009999">Solution</font></h3>

<ol>
	<li>Define a class that is an abstraction for the primitive objects</li>
	<li>Both primitive and composite classes inherit from that class</li>
	<li>A composite object contains a collection of primitives</li>
	<li>An operation on a composite class is applied to its primitives,
		results are combined</li>
</ol>

</font>

<hr><h2><font color="#009999">Pattern COMPOSITE</font></h2>
<font size="+1">
<hr color="#00ffff" size="6">

<h3><font color="#009999">Solution (cont.)</font></h3>

<script><!--
	image( "un07.png" )
//--></script>

</font>

<hr><h2><font color='#009999'>26.6 The COMPOSITE Pattern (cont.)</font></h2>
<font size='+1'>

<ul>
	<table border='1' cellpadding='4'>
		<tr bgcolor='#00ffff'>
			<th width='50%'>Name in Design Pattern</th>
			<th width='50%'>Actual Name (String Streams)</th>
		</tr>
		<tr>
			<td align='center'><tt>Primitive</tt></td>
			<td align='center'><tt>Item</tt></td>
		</tr>
		<tr>
			<td align='center'><tt>Composite</tt></td>
			<td align='center'><tt>Bundle</tt></td>
		</tr>
		<tr>
			<td align='center'><tt>op()</tt></td>
			<td align='center'><tt>get_unit_price</tt></td>
		</tr>
	</table>
</ul>

</font>

<hr><h2><font color="#009999">26.7 Case Study:  Putting Patterns to Work
	</font></h2>
<font size="+1">

<ul>
	<li>Refine the invoice printing program of Chptr 13</li>
	<li>Include <tt>Bundle</tt>, from above</li>
	<li>Make changes to employ several other patterns</li>
</ul>

</font>

<hr><h2><font color="#009999">26.7 Case Study:  Putting Patterns to Work (cont.)
	</font></h2>
<font size="+1">

<ul>
	<li>General <tt>Item</tt> abstract base class:
		<blockquote>
<pre>class Item
{
public:
   virtual double get_unit_price() const = 0;
   virtual int get_quantity() const = 0;
   virtual string get_description() const = 0;
   double get_total_price() const;
   . . .
};</pre>
		</blockquote>
	</li>
</ul>

</font>

<hr><h2><font color="#009999">26.7 Case Study:  Putting Patterns to Work (cont.)
	</font></h2>
<font size="+1">

<ul>
	<li>Derived classes implement the virtual functions</li>
	<li><tt>get_total_price</tt> is defined in the <tt>Item</tt> class:
		<blockquote>
<pre>double Item::get_total_price() const
{
   return get_quantity() * get_unit_price();
}</pre>
		</blockquote>
	</li>
	<li>A generic item can't compute quantity or unit price, but it knows that
		the total price is their product - TEMPLATE METHOD pattern</li>
</ul>

</font>

<hr><h2><font color="#009999">26.7 Case Study:  Putting Patterns to Work (cont.)
	</font></h2>
<font size="+1">

<ul>
	<li>We want to add simple products to an invoice</li>
	<li>Invoice stores <tt>Item</tt>s, not <tt>Product</tt>s</li>
	<li>Use ADAPTER pattern, define <tt>ProductItem</tt> that wraps a
		<tt>Product</tt> in an <tt>Item</tt> i/f:
		<script><!--
			image( "fig04.png" )
		//--></script>
	</li>
</ul>

</font>

<hr><h2><font color="#009999">26.7 Case Study:  Putting Patterns to Work (cont.)
	</font></h2>
<font size="+1">

<ul>
	<blockquote>
<pre>class ProductItem : public Item
{
public:
   ProductItem(Product p);
   virtual double get_unit_price() const;
   virtual string get_description() const;
private:
   Product prod;
};</pre>
	</blockquote>
</ul>

</font>

<hr><h2><font color="#009999">26.7 Case Study:  Putting Patterns to Work (cont.)
	</font></h2>
<font size="+1">

<ul>
	<li>Adapter methods call appropriate <tt>Product</tt> methods:
		<blockquote>
<pre>double ProductItem::get_unit_price() const
{
   return prod.get_price();
}</pre>
		</blockquote>
	</li>
</ul>

</font>

<hr><h2><font color="#009999">26.7 Case Study:  Putting Patterns to Work (cont.)
	</font></h2>
<font size="+1">

<ul>
	<li><tt>Invoice</tt> holds a collection of items:
		<blockquote>
<pre>class Invoice
{
public:
   void add(Item* item)
   {
      items.push_back(item);
   }
   . . .
private:
   vector&lt;Item*&gt; items;
};</pre>
		</blockquote>
	</li>
</ul>

</font>

<hr><h2><font color="#009999">26.7 Case Study:  Putting Patterns to Work (cont.)
	</font></h2>
<font size="+1">

<ul>
	<li><tt>Invoice</tt> clients my want to inspect the items</li>
	<li><tt>Invoice</tt> doesn't want to reveal its details - they may change</li>
	<li>Sol'n - follow the ITERATOR pattern</li>
	<li>Design an iterator class:</li>
</ul>

</font>

<hr><h2><font color="#009999">26.7 Case Study:  Putting Patterns to Work (cont.)
	</font></h2>
<font size="+1">

<ul>
	<blockquote>
<pre>class ItemIterator
{
public:
   . . .
   bool is_done() const;
   void next();
   Item* get() const;
private:
   vector&lt;Item*&gt;&amp; items;
   int pos;
};</pre>
	</blockquote>
</ul>

</font>

<hr><h2><font color="#009999">26.7 Case Study:  Putting Patterns to Work (cont.)
	</font></h2>
<font size="+1">

<ul>
	<li>These functions access a reference to the original vector:
		<blockquote>
<pre>Item* ItemIterator::get() const
{
   if (pos &lt; items.size())
      return items[pos];
   else
      return NULL;
}</pre>
	</blockquote>
</ul>

</font>

<hr><h2><font color="#009999">26.7 Case Study:  Putting Patterns to Work (cont.)
	</font></h2>
<font size="+1">

⌨️ 快捷键说明

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