• VC++编程之道读书笔记(2)


    第三篇 技术细节

    第七章:细说开发人员必知必会的39个开发细节

    细节36:单例模式的应用

    在开发程序时,往往需要在整个工程中只需要一个类的实例。而这个实例一旦被创建就不能被其他的实例再创建了,通常我们称这个实现过程为单例模式。

    既然要保证类只有一个实例,那么就需要其他的类不能使用实例化该类。因此,需要将其构造方法设为私有的,即使用private关键字修饰。同时,类中提供一个静态方法,该方法的返回值是该类的一个实例。这样就只能使用该静态方法来获取类的实例了,从而保证了唯一性。

    下面通过具体代码来实现一个单例模式的应用,代码如下:

     1 #include <iostream>
     2 using namespace std;
     3 
     4 class Emperor
     5 {
     6 private:
     7     static Emperor *pEmperor; // declear a reference
     8     static int count; // contructor times
     9     Emperor() // contructor
    10     {
    11         count++;
    12     }
    13 public:
    14     static Emperor getInstance()
    15     {
    16         if(NULL == pEmperor)
    17         {
    18             pEmperor = new Emperor();
    19         }
    20         
    21         return *pEmperor;
    22     }
    23     void getName()
    24     {
    25         cout << "I am the " << count << "contructor" << endl; 
    26     }
    27 }
    28 int main(void)
    29 {
    30     cout << "The first time contructor" << endl;
    31     Emperor emperor1 = Emperor::getInstance();
    32     emperor1.getName();
    33     
    34     cout << "The second time contructor" << endl;
    35     Emperor emperor2 = Emperor::getInstance();
    36     emperor2.getName();
    37     
    38     cout << "The third time contructor" << endl;
    39     Emperor emperor3 = Emperor::getInstance();
    40     emperor3.getName();
    41     
    42     return 0;
    43 }

    要想实现单例模式,首先,需要将类的构造方法定义为类的私有成员方法。当然,如果不是实现单例模式,这样做是不对的,因为在类外是无法创建该类的实例的。既然无法创建类的实例,那么单例模式又是如何创建这个类的实例的呢?方法很简单,在类中定义一个公有的静态成员方法,在这个静态成员方法中创建类的实例就可以了。

    细节37:策略模式的简单应用

    当我们在解决问题时,这个问题的解决方案有很多种,处理起来非常不方便。例如,在使用图像处理软件处理图片后,需要选择一种格式保存。然而各种格式在底层实现的算法并不相同,这刚好适合策略模式。

    对于策略模式,需要定一个抽象类来标识各种策略的抽象。这样就可以使用多态来让虚拟机选择不同的实现类。然后让每一个中具体的策略来实现这个抽象,并为其中定义的方法提供具体的实现。由于在选择适当的策略上有些不方便,需要不断地判断需要的类型,因此用简单工厂方法类实现判断过程。

    下面通过代码来看一下策略模式的应用,代码如下:

     1 #include <iostream>
     2 
     3 using namespace std;
     4 
     5 const int GIF = 1;
     6 const int JPEG = 2;
     7 // 抽象类
     8 class ImageSaver
     9 {
    10 public:
    11     virtual void save() = 0; // 纯虚函数
    12 };
    13 
    14 class GIFSaver : public ImageSaver
    15 {
    16 public:
    17     virtual void save()
    18     {
    19         cout << "将图片保存成GIF格式" << endl;
    20     }
    21 };
    22 
    23 class JPEGSave : public ImageSaver
    24 {
    25 pbulic:
    26     virtual void save()
    27     {
    28         cout << "将图片保存成JPEG格式" << endl;
    29     }
    30 };
    31 
    32 class TypeChooser
    33 {
    34 public:
    35     static ImageSaver* getSaver(int type)
    36     {
    37         if(type == GIF)
    38         {
    39             return new GIGSaver();
    40         }
    41         else if(type == JPEG)
    42         {
    43             return new JPEGSaver();
    44         }
    45         else
    46         {
    47             return null;
    48         }
    49     }
    50 };
    51 
    52 int main(void)
    53 {
    54     cout << "用户选择了GIF格式:" << endl;
    55     ImageSaver *saver = TypeChooser::getSaver(GIF); // 获得保存图片为GIF类型的对象
    56     saver->save();
    57     cout << "用户选择了JPEG格式:" << endl;
    58     delete saver;
    59     saver = TypeChooser::getSaver(JPEG);
    60     saver->saver();
    61     
    62     return 0;
    63 }

    在上面的代码中定义了接口ImageSaver,在该接口中定义了Save方法。接下来编写类GIFSaver类和JPEGSaver类,这两个类实现了ImageSaver接口。在实现save()方法时将图片保存成GIF和JPEG格式。编写类TypeChooser,该类根据用户提供的图片类型来选择合适的图片存储方式。这样就实现了一个简单的策略模式的应用。同时也使用了简单工厂模式。

    细节38:适配器模式的使用

    对于刚从工厂中生产出来的产品,有些功能并不能完全满足用户的需要。因此用户通常会对其进行一定的改装工作。在不破坏原有产品的情况下为其添加新的功能,这时就需要使用适配器模式。

    适配器模式可以在符合OCP原则(开放封闭原则)的基础上,为类增加新的功能。该模式涉及的主要角色有以下几点。

    • 目标角色:就是期待得到的类,例如本实例的GPS抽象类。
    • 源角色:需要被增加功能的类,例如本实例的Car类。
    • 适配器角色:新创建的类,在源角色的基础上实现了目标角色,例如本实例的GPSCar类。

    关于各个类的继承关系,如图1-1所示:

    下面通过具体的实例来进一步了解适配器模式的应用,代码如下:

     1 #include <iostream>
     2 #include <string>
     3 
     4 using namespace std;
     5 
     6 typedef char String[30];
     7 struct Point
     8 {
     9     int x, y;
    10 };
    11 
    12 class Car
    13 {
    14 private:
    15     String name;
    16     double speed;
    17 public:
    18     double getSpeed()
    19     {
    20         return speed;
    21     }
    22     void setSpeed(double sp)
    23     {
    24         this->speed = sp;
    25     }
    26     char *getName()
    27     {
    28         return name;
    29     }
    30     void setName(String strName)
    31     {
    32         strcpy(this->name, strName);
    33     }
    34 public:
    35     virtual void toString()
    36     {
    37         cout << "车名:" << name << ", "
    38         << "速度:" << speed << "千米/小时" << endl;
    39     }
    40 };
    41 class GPS
    42 {
    43 public:
    44     virtual Point getLocation() = 0; // 纯虚函数
    45 };
    46 
    47 class GSPCar : public Car, GPS
    48 {
    49 public:
    50     Point getLocation()
    51     {
    52         Point point;
    53         point.x = getSpeed();
    54         point.y = getSpeed();
    55         
    56         return point;
    57     }
    58     void toString()
    59     {
    60         Car::toString();
    61         cout << "坐标:(" << getLocation().x << ", " << getLocation().y << "" << endl;
    62     }
    63 };
    64 
    65 int main(void)
    66 {
    67     cout << "自定义普通的汽车" << endl;
    68     Car car;
    69     car.setName("Audi");
    70     car.setSpeed(100);
    71     car.toString();
    72     
    73     cout << "自定义GPS汽车" << endl;
    74     GPSCar gpsCar;
    75     gpsCar.setName("BMW");
    76     gpsCar.setSpeed(120);
    77     gpsCar.toString();
    78     
    79     return 0;
    80 }

    在上面的代码中产品是有Car类所标识的小汽车,新增加的功能是有GPS类标识的GPS定位功能。然后有适配器类GPSCar将Car类和GPS类组合到一起形成一个新的产品,这一过程就是适配器模式的使用。

  • 相关阅读:
    编写PHP规则
    phpmyadmin修改mysql数据库密码
    响应式设计:流式布局
    响应式设计:媒体查询
    html5、css3及响应式设计入门
    HTML5学习笔记五:html5表单
    HTML5学习笔记四:html5结构
    HTML5学习笔记三:aside元素,time元素与微格式
    css基础知识1——css基础语法、css选择器、css继承和层叠
    HTML基础知识5——<div>和<span>标签
  • 原文地址:https://www.cnblogs.com/lit10050528/p/3724695.html
Copyright © 2020-2023  润新知