zoukankan      html  css  js  c++  java
  • 设计模式一(创建型模式)

    主要是看着http://www.mscenter.edu.cn/blog/k_eckel 学习,有代码并且23种设计模式总结的很好~

    我自己简单记点笔记。

    设计模式:用一个通用模式可以解决一类问题,一个框架

    一创建型模式:

    Factory, AbstractFactory,Singleton,Builder,Prototype

    这里面试测试岗位最常问到要求写的就是singleton单例设计模式,C++primer Plus中也有提到

    所谓单例设计模式,是想定义一个只能被实例化一次的类, 这个具体化后的对象相当于是面向对象编程中的一个全局变量(全局变量不符合面向对象编程的要求)。

    实现:将构造函数放在protected或private中,使得外部不能利用construct构造对象。唯一的途径是利用public static的成员函数调用保护的构造成员函数,但static成员函数保证了只能执行一次,生成一个唯一的类对象。

    code:

     1  1 #ifndef SINGLETON__H_INCLUDED
     2  2 #define SINGLETON__H_INCLUDED
     3  3 #include <iostream>
     4  4 
     5  5 /*Singleton 单例设计模式,构造函数放在private或protected中
     6  6 通过public的静态成员函数调用construct,static函数只在第一次调用时执行,所以单例模式
     7  7 只生成一个实例*/
     8  8 
     9  9 using namespace std;
    10 10 class Singleton
    11 11 {
    12 12 public:
    13 13     static Singleton* Instance();
    14 14 protected:
    15 15     Singleton();
    16 16 private:
    17 17     static Singleton *_instance;
    18 18 };
    19 19 
    20 20 #endif // SINGLETON__H_INCLUDED
    21 21 //------------------------------------------------------------------
    22 22 #include "Singleton.h"
    23 23 #include <iostream>
    24 24 
    25 25 using namespace std;
    26 26 
    27 27 Singleton * Singleton::_instance=0;  //
    28 28 
    29 29 Singleton::Singleton()
    30 30 {
    31 31     cout<<"Singleton"<<endl;
    32 32 }
    33 33 
    34 34 Singleton* Singleton::Instance()
    35 35 {
    36 36     if(_instance==0)
    37 37     {
    38 38         _instance=new Singleton();
    39 39     }
    40 40     return _instance;
    41 41 }
    42 42 //---------------------------------------------------------
    43 43 #include <iostream>
    44 44 #include "Singleton.h"
    45 45 using namespace std;
    46 46 
    47 47 int main()
    48 48 {
    49 49     Singleton* sgn=Singleton::Instance();// public
    50 50 
    51 51     return 0;
    52 52 }
    View Code

    Factory,AbstractFactory

    工厂模式就像它的名字一样,好比车床加工模具一样,一台车床可以加工出各式各样的模具,操作工人不需要知道代码怎么写的,甚至不关心加工出来的是个啥,只要负责站在流水线上就可以了(这个比方不知道恰当否)

    用面向系统设计的专业术语来讲,

    1)为了提高内聚(Cohesion)和松耦合(Coupling) ,我们经常会抽象出一些类的公共接口以形成抽象基类或借口。即一个基类factory指针可以指向多个派生类,具体生产哪个product由concreteFactory决定(Factory和AbstractFactory的区别就是:Factory模式只有一个concreteFactory生产同一类产品【A1,A2...】,而AbstractFactory模式有多个factory的子类,不同的子类生产一些相关但不同类的产品【A1,A2...】,【B1,B2,...】,...)。客户需要用的是已经封装好的factory接口就可以了,不能了解生产工艺。

    2)这里1)中为什么不直接factory中生产product呢,而是在下面又扩展了一层?我觉得应该是考虑到AbstractFactory要生产A大类,B大类多类product,就需要Factory_A,Factory_B,考虑到代码的重复利用和管理维护,用个基类Factory管理派生这些子类,无疑更方便。

    PS:高内聚(Cohesion)和松耦合(Coupling):

          耦合是指两个实体相互依赖于对方的一个量度;内聚(Cohesion)是一个模块内部各成分之间相关联程度的度量

      Q:什么叫高内聚 低耦合?
          A;系统的各个模块尽可能具有较大的独立性,换句话说,希望这样设计软件结构,使得每个模块完成一个相对独立的特定子功能,并且和其他模块之间的关系很简单,以便能方便地把不同场合下写成的程序模块组合成软件系统。衡量模块独立性的定性标准是内聚(一个模块内各个元素彼此结合的紧密程度)和耦合(一个软件结构内不同模块之间互连程度的度量)。高内聚、低耦合的模块是设计时追求的目标。尽量降低系统各个部分之间的耦合度,是应用服务层设计中需要重点考虑的问题。 

          简单来讲就是类似属性的东西隔一个模块里边,并且保证各个模块相对独立,即插即用~~

    code:

      1 // Product.h
      2 
      3 
      4 #ifndef _PRODUCT_H_
      5 #define _PRODUCT_H_
      6 
      7 class Product
      8 {
      9 public:
     10     virtual ~Product()=0; 
     11 protected:
     12     Product();       
     13 };
     14 
     15 class ConcreteProduct:public Product
     16 {
     17 public:
     18     ConcreteProduct();
     19     ~ConcreteProduct();
     20 };
     21 
     22 #endif
     23 //-----------------------------------------------------
     24 // Factory.h
     25 /*Factory两个重要功能:
     26 1,高内聚,松耦合,Factory类中提供一个接口,,并封装了product类的实例化。
     27 2,具体化的工作延迟至Factory子类中进行
     28    (Product可能有很多子类,Factory中不知道要实例化哪一个
     29    但是Factory的对应的子类知道需要创建哪一个产品)。
     30 
     31 */
     32 #ifndef _FACTORY_H_
     33 #define _FACTORY_H_
     34 
     35 class Product; //前向声明Product是一个类
     36 
     37 class Factory
     38 {
     39 public:
     40     virtual ~Factory()=0;
     41     virtual Product* GetProduct()=0;
     42 protected:
     43     Factory();  //把创建对象放在子类中实现
     44 };
     45 
     46 class ConcreteFactory:public Factory
     47 {
     48 public:
     49     ConcreteFactory(); 
     50     ~ConcreteFactory();
     51     Product* GetProduct();
     52 };
     53 
     54 #endif
     55 //----------------------------------------------------
     56 #include "Product.h"
     57 #include <iostream>
     58 
     59 using namespace std;
     60 
     61 Product::Product()
     62 {
     63     cout<<"Product.."<<endl;
     64 }
     65 Product::~Product()
     66 {
     67 }
     68 ConcreteProduct::ConcreteProduct()
     69 {
     70     cout<<"ConcreteProduct.."<<endl;
     71 }
     72 
     73 ConcreteProduct::~ConcreteProduct()
     74 {
     75     // ...
     76 }
     77 //--------------------------------------
     78 #include "Factory.h"
     79 #include "Product.h"
     80 #include <iostream>
     81 
     82 using namespace std;
     83 
     84 Factory::Factory()
     85 {
     86     cout<<"Factory.."<<endl;
     87 }
     88 Factory::~Factory()
     89 {
     90 }
     91 
     92 ConcreteFactory::ConcreteFactory()
     93 {
     94     cout<<"ConcreteFactory.."<<endl;
     95 }
     96 ConcreteFactory::~ConcreteFactory()
     97 {
     98 
     99 }
    100 Product* ConcreteFactory::GetProduct()
    101 {
    102     return new ConcreteProduct();
    103 }
    104 //--------------------------------------------------------
    105 # include "Factory.h"
    106 #include <iostream>
    107 
    108 using namespace std;
    109 
    110 int main()
    111 {
    112     Factory* spd=new ConcreteFactory();//父类Factory不知道要实例化Product的哪一个子类
    113     Product* p=spd->GetProduct();//
    114     return 0;
    115 }
    View Code

    Bulider建设者模式:

    如果说Factory只关心结果,Builder模式的话更关心过程,最后生成Product实例之前需要做一些别的工作(Factory直接返回Product或其子类的实例),这些工作A,B,C可能会影响到product实例的生成,就像一点意外就会导致人的一生戏剧性的转变,这个也是这样的道理。当然A,B,C这些类方法需要有一些Director提供的参数控制,使最后product生成的是director而不是actor什么的。

    Prototype模式:

    这个就是一个类拷贝的过程,自定义一个复制构造函数和重载赋值操作符。

  • 相关阅读:
    MongoDB结构划分
    iphone下scrollview图片浏览器小记
    图文详解linux/windows mysql忘记root密码解决方案
    【记】Javascript遍历对象属性的方法
    【jQuery】jQueryUI中的datepicker在overflow下的两点点小小的问题。
    第一个测试文章
    【记】Javascript的正则表达式RegExp
    【记】IE下input标签中的paddingleft和paddingright
    【CSS】关于IE、FireFox中table强制换行的总结
    【DOCTYPE】兼容模式和标准模式
  • 原文地址:https://www.cnblogs.com/fkissx/p/4733435.html
Copyright © 2011-2022 走看看