zoukankan      html  css  js  c++  java
  • C++ 与设计模式学习(其一)

           记得曾经一年前,听到同学再说设计模式,当时觉得不怎么重要,所以就没有去系统的学习,这一放,就是一年,直到前段时间,面试了一个阿里巴巴的职位,要我谈谈对于设计模式的看法。

           之后就好好了看了一些文章,好好的体会了一番! 现在将自己的心得好好的分享一下吧!(由于设计模式内容比较多,以及设计模式的六大原则,后续都会陆续的更新!)

     1. 单例模式(单件模式):单例模式确保某一个类只有一个实例,而且自行实例化并向整个系统提供这个实例单例模式。单例模式只应在有真正的“单一实例”的需求时才可使用。

      举个栗子:

     1 #include<iostream>
     2 
     3 class sigle_class {
     4 
     5 private :
     6 
     7     sigle_class() {};  //将构造函数私有化
     8     static sigle_class * sigle; 
     9 
    10 public:
    11     ~sigle_class();
    12     static sigle_class * init();
    13     void  show() {
    14         std::cout <<"这是一个单例模式"<<std::endl;
    15     }
    16 };
    17 
    18 //对于静态变量需要在内外进行必要的初始化!
    19 sigle_class * sigle_class::sigle = NULL;
    20 
    21 sigle_class::~sigle_class() {
    22 
    23     std::cout << "单例模式举例被析构了!" << std::endl;
    24 };   //析构函数
    25 
    26 sigle_class * sigle_class::init(){
    27 
    28     if (sigle == NULL) {
    29        sigle = new sigle_class();
    30     }
    31     return  sigle;
    32 };
    33 
    34 int  main(int argv ,char args []){
    35 
    36     sigle_class  *sigle= sigle_class::init();    //定义个sigle_class 实例
    37       sigle->show();
    38     sigle_class  * mode = sigle_class::init();   //顶一个mod的实例
    39       mode->show();
    40       if (sigle == mode) {
    41           std::cout << "sigle == mode" << std::endl;
    42       }
    43       else {
    44           std::cout << "sigle is not equal mode!" << std::endl;
    45       }
    46       getchar();
    47     return 0;
    48 }

      当然,我们在日常项目中,解愁到的单例模式,远比这个要复杂得多。这里只是打个比方而已!他会设计到单例模式中的两种模式: 赖汉模式,和饱汉模式。

    这里因为是对所有的模式,作总结,就不一一例举了!

    其实将《泡妞与设计模式》中的那句话改一下,可以这样形容这个模式:

       假如有一个王二小(不是为鬼子带路的王二小),他超爱玩游戏,所以在很多的游戏中都有自己的账号。这就是说,这些账号只有王二小可以使用(当然,这里我们就不说,王二小将账号给朋友去玩了哈!)。这就是一个单例模式。很多时候,单例模式和静态类有点类似,但是不尽相同。

    2.     工厂模式:

           工厂模式:客户类和工厂类分开。消费者任何时候需要某种产品,只需向工厂请求即可。消费者无须修改就可以接纳新产品。缺点是当产品修改时,工厂类也要做相应的修改。如:如何创建及如何向客户端提供。

       举个栗子:

         calc.h 头文件

     1 #pragma once
     2  #ifndef _CALC__H__
     3  #define _CALC__H__
     4 #include"Method.h"
     5 
     6 //这部分,用来处理得到的数据
     7 //继承
     8 template<typename Tre , typename in >
     9 class calc : private method<Tre>{
    10 
    11 public :    
    12     //构造函数
    13         calc() ;
    14         ~calc() {};
    15      void show(in ,Tre ,Tre);
    16     
    17 };
    18 
    19 //定义一个魔板构造函数
    20 template<typename Tre, typename in>
    21 calc<Tre, in >::calc() {
    22 
    23     cout << "is being constructor !" << endl;
    24 };
    25 
    26 //通过封装这个+-*/,并调用这个函数
    27 template<typename Tre, typename in>
    28 void calc<Tre, in >::show(in type, Tre a, Tre b) {
    29 
    30     char *p[5] = { "+","-","*","/" };
    31     printf("%lf %s %lf = %lf 
    ", a, p[type], b,this->Add(a,b));
    32     
    33 }
    34 
    35 #endif    

        Method.h 头文件

     1 #pragma once
     2 #ifndef _METHOD_H_
     3 #define _METHOD_H_
     4 #include <stdexcept>
     5 #include"Calc.h"
     6 
     7 /*
     8  实现 加 减 乘 除
     9 */
    10 template<typename T >
    11 class method{
    12 public :
    13       method() {};
    14      ~method() {};
    15      T  Add ( T  , T   )    ;
    16      T Sub (T   , T  )    ;
    17      T Mul (T  , T     );
    18      T Div ( T , T  );
    19 };
    20 
    21 
    22 template<typename T >
    23 T method< T >::Add(T a, T  b) {
    24 
    25     return a + b;
    26 }
    27 
    28 template<typename T >
    29 T  method< T >::Sub(T pre, T nex) {
    30 
    31     return pre - nex;
    32 }
    33 
    34 template<typename T >
    35 T method< T >::Mul(T a, T b) {
    36 
    37     return a*b;
    38 }
    39 
    40 template<typename T >
    41 T method< T >::Div(T a, T b) {
    42     if (b == 0) {
    43         throw out_of_range("被除数为0,这是违反的!");
    44         return  -INT_MAX;
    45     }
    46     return a / b;
    47 }
    48 
    49 #endif

        Main.cpp

     1 /* 设计模式之计算器 比如: 加 减 乘 除 */
     2 #include<iostream>
     3 #include"Calc.h"
     4 #include"Method.h"
     5 #include<stdio.h>
     6 
     7 using namespace std;
     8 
     9 int main(int argv ,char args [] ) {
    10 
    11     calc<double,int >  mycalc;
    12     printf("hello the worlkd !! 
    ");
    13     mycalc.show(0,4.0,2);
    14     getchar();
    15     return 0;
    16 }

       这种模式其实跟我们说所的继承差不离,但是继承只是一个语言功能,而这种模式是分配调度.....两者存在本质上的不同、就如上面的例子而言,其加减乘除全部是来自另一个calc类,而充当method的父类,method作为核心类,只是作为一个枢纽而已。它的计算功能依附其他的例,这在java就是interface(接口)来完成这些重要的功能。

    3 . 工厂方法模式:

         定义:

           工厂方法模式:核心工厂类不再负责所有产品的创建,而是将具体创建的工作交给子类去做,成为一个抽象工厂角色,仅负责给出具体工厂类必须实现的接口,而不接触哪一个产品类应当被实例化这种细节。

          那么,举个栗子: 

           额,这让我想起了<篮球火>,那就说说篮球的队,我们知道篮球队是有队员组成的,其中队员扮演不同的角色(5个吧),大前锋,中峰,小前锋,得分后卫,和控球后卫。   那么,我们可以将篮球队做成一个抽象类, 然后各个角色充当具体类。

         看代码:(简单的描述一下下) 

    //Game.h
    
    #pragma once
    #ifndef _GAME_H_
    #define _GAME_H_
    #include<iostream>
    #include<string>
    using namespace std;
    
    //篮球比赛
    class bigGame {
    
    private :
    
        //取名字
        string str;
    
    public:
    
        bigGame(string  st): str(st){ };
        virtual ~ bigGame() {};
    
        //全明星最有价值职位:
         void  famous_Role() {
            cout << "the most valuer of role is " << str << endl;
        };
    
    };
    
    
    #endif
    
    //    Roler.h
    
    #pragma once
    #ifndef _ROLER_H
    #define _ROLER_H
    #include "Team.h"
    #include "Game.h"
    class Roler : public Team {
      
    public :
        Roler();
        virtual ~ Roler();
        virtual bigGame * PlayShow();
    };
    
    #endif
    
    // team.h
    
    #pragma once
    #ifndef _TEAM_H_
    #define _TEAM_H_
    #include "Game.h"
    //充当team的扮演角色
    class Team {
    
    public :
    
       Team();
       virtual ~ Team();
       virtual bigGame * PlayShow(void ) =0 ;
    
    };
    #endif

    以上是头文件,然后是实现类:采用多文件形式,这个看个人的喜好!!

     1 //  Roler.cpp
     2 
     3 #include "Roler.h"
     4 #include "Game.h"
     5 #include<iostream>
     6 //构造函数
     7   Roler::Roler() {
     8 
     9  }
    10 
    11 //析构函数
    12   Roler::~Roler() {
    13 
    14   }
    15 
    16   //角色具体化
    17   bigGame * Roler::PlayShow() {
    18       //std::cout << "小前锋" << std::endl;
    19       return  new  bigGame("小前锋");
    20   }
    21 
    22 //   Team.cpp
    23 
    24 #include "Team.h"
    25 Team::Team() {}
    26 Team::~Team() {}
    27 
    28 
    29 //  Main.cpp
    30 
    31 #include"Roler.h"
    32 #include"Team.h"
    33 #include<iostream>
    34 using namespace std;
    35 
    36 int main(int args , char argv[]) {
    37 
    38 
    39     Roler myrole;
    40     bigGame *my = myrole.PlayShow();
    41     my->famous_Role();
    42     getchar();
    43     return 0;
    44 }

      其实,可以看出,工厂方法模式--其实注重的是对于方法函数的继承,当然工厂方法模式也是有简单工厂模式改进而来,所以有工厂模式的模式~~!

    -------------------------------------------------------------华丽丽的分割线----------------------------------------------------------------------------

                  由于是刚接触到设计模式,没有较为深度的理解,就我所理解的,分享一下下,欢迎大侠们指正!  

  • 相关阅读:
    【问题解决方案】单个文件夹嵌套时github仓库中最外层文件夹直接显示所有嵌套文件夹名的问题
    【问题解决方案】本地仓库删除远程库后添加到已有github仓库时仓库地址找不到的问题(github仓库SSH地址)
    【问题解决方案】git/github本地和远程仓库的重命名
    【学习总结】《大话数据结构》- 总
    【机器学习】李宏毅机器学习-Keras-Demo-神经网络手写数字识别与调参
    【问题解决方案】Keras手写数字识别-ConnectionResetError: [WinError 10054] 远程主机强迫关闭了一个现有的连接
    【学习总结】win7使用anaconda安装tensorflow+keras
    【问题解决方案】AttributeError: module 'pygal' has no attribute 'Worldmap'
    【问题解决方案】ImportError: No module named 'pygal'
    【问题解决方案】Github中的jupyter notebook文件(.ipynb)加载失败/失败
  • 原文地址:https://www.cnblogs.com/gongxijun/p/4370637.html
Copyright © 2011-2022 走看看