<読書ノート>Thinking in python(Pythonデザインモード)1.Singltonのc++とpythonの実現

83207 ワード

1.pythonの天然の汎用的な特徴のため、pythonにはインタフェースの継承がなく、すべての継承は継承を実現し、サブクラスは親の実現を継承する.
 
2.Singlton単品モード
  • singlton in c++

  • 次に、最も簡単なC++実装を見てみましょう.
    クラスstatic変数、およびデフォルトのコンストラクション関数をプライベート化します.
    GlobalClassのエンティティは1つしか存在しません
           1 #include 
     2 
    using
     
    namespace
     std;
     3 
     4 
    class
     GlobalClass {
     5 
        
    public
    :
     6 
            
    static
     GlobalClass
    *
     instance();
     7 
            
    static
     
    void
     create();
     8 
            
    static
     
    void
     destroy();
     9 
            
    void
     print() {
    10 
                cout 
    <<
     
    "
    haha
    "
     
    <<
     endl;
    11 
            }
    12 
        
    private
    :
    13 
            
    static
     GlobalClass
    *
     s_instance;
    14 
            GlobalClass();
    15 
            
    ~
    GlobalClass(){
    16 
                
    //
    destroy();
    17 
                cout 
    <<
     
    "
    destruct
    "
     
    <<
     endl;
    18 
    19 
            }
    20 
    };
    21 
    22 
    GlobalClass
    *
     GlobalClass::s_instance 
    =
     NULL;
    23 
    24 
    GlobalClass::GlobalClass() {
    25 
        cout 
    <<
     
    "
    construct global class
    "
     
    <<
     endl;
    26 
    }
    27 
    //
    GloblaClass::~GlobalClass() {
    28 
    //
        destroy();
    29 
    //
        cout << "destruct" << endl;
    30 
    //
    }
    31 
    GlobalClass
    *
     GlobalClass::instance() {
    32 
        
    return
     s_instance;
    33 
    }
    34 
    35 
    void
     GlobalClass::create() {
    36 
        
    if
     (
    !
    s_instance)
    37 
            s_instance 
    =
     
    new
     GlobalClass();
    38 
    }
    39 
    40 
    void
     GlobalClass::destroy() {
    41 
        delete s_instance;
    42 
        s_instance 
    =
     NULL;
    43 
        cout 
    <<
     
    "
    delete ok
    "
     
    <<
     endl;
    44 
    }
    45 
    46 
    int
     main(
    int
     argc, 
    char
     
    *
    argv[])
    47 
    {
    48 
        
    //
    GlobalClass my_global_class;  //can't create by this
    49 
        GlobalClass::create();
    50 
        GlobalClass
    *
     p_global_class 
    =
     GlobalClass::instance();
    51 
        p_global_class
    ->
    print();
    52 
        GlobalClass::destroy();
    53 
        
    return
     
    0
    ;
    54 
    }
    //result
    construct global class
    haha
    destruct
    delete ok

    effective c++ , local static 。 Siglton
    
     
      1  // file singlton.h
      2 
      3  #ifndef _SINGLTON_H_
      4  #define  _SINGLTON_H_
      5  #include  < iostream >
      6  using   namespace  std;
      7 
      8  class  GlobalClass {
      9       public :
     10           static  GlobalClass &  instance( int  weight  =   3 ){
     11               static  GlobalClass global_object(weight);
     12               return  global_object;
     13          }
     14           void  print() {
     15              cout  <<   " haha "   <<   this   <<  endl;
     16              cout  <<  m_weight  <<  endl  <<  endl;
     17          }
     18           ~ GlobalClass(){
     19              cout  <<   " destruct "   <<   this   <<  endl;
     20 
     21          }
     22           void  addOne() {
     23              m_weight  +=   1 ;
     24          }
     25 
     26       private :
     27          GlobalClass() {
     28              cout  <<    " construct global class "   <<   this   <<  endl;
     29 
     30          }
     31          GlobalClass( int  weight):m_weight(weight){ cout  <<   " construct global class with weight "   <<   this   <<  endl;}
     32          GlobalClass &   operator = const  GlobalClass & );
     33          GlobalClass( const  GlobalClass & );
     34           int  m_weight;
     35  };
     36  #endif
     37 
     38 
     39  // file use_singlton.h
     40  #ifndef USE_SIGLTON_H
     41  #define  USE_SIGLTON_H
     42 
     43  #include  " singlton.h "
     44  void  useSinglton();
     45   
     46  #endif
     47 
     48  // file use_singlton.cc
     49  #include  < iostream >
     50  #include  " use_singlton.h "
     51  using   namespace  std;
     52  void  useSinglton() {
     53      GlobalClass &  p_global_class  =  GlobalClass::instance( 16 );
     54      p_global_class.print();
     55      p_global_class.addOne();
     56      p_global_class.print();
     57 
     58      GlobalClass &  p_global_class2  =  GlobalClass::instance( 46 );
     59      p_global_class2.print();
     60      p_global_class2.addOne();
     61      p_global_class2.print();
     62  }
     63 
     64  // file test_singlton.cc
     65  #include  < iostream >
     66  #include  " singlton.h "
     67  #include  " use_singlton.h "
     68  using   namespace  std;
     69 
     70  int  main( int  argc,  char   * argv[])
     71  {
     72      cout  <<   " use singlton "   <<  endl;
     73      useSinglton();
     74 
     75      cout  <<   " wa ha ha  "   <<  endl;
     76      GlobalClass &  p_global_class  =  GlobalClass::instance( 4 );
     77      p_global_class.print();
     78      p_global_class.addOne();
     79      p_global_class.print();
     80 
     81      GlobalClass &  p_global_class2  =  GlobalClass::instance( 8 );
     82      p_global_class2.print();
     83      p_global_class2.addOne();
     84      p_global_class2.print();
     85 
     86      cout  <<   " ha ha wa "   <<  endl;
     87      useSinglton();    
     88 
     89       return   0 ;
     90  }
     91 
     92  // allen:~/study/design_pattern/singlton_test$ g++ -g -o test_singlton  test_singlton.cc use_singlton.cc 
     93  allen: ~/ study / design_pattern / singlton_test$ . / test_singlton 
     94  use singlton
     95  construct  global   class  with weight0x804a5c0
     96  haha0x804a5c0
     97  16
     98 
     99  haha0x804a5c0
    100  17
    101 
    102  haha0x804a5c0
    103  17
    104 
    105  haha0x804a5c0
    106  18
    107 
    108  wa ha ha 
    109  haha0x804a5c0
    110  18
    111 
    112  haha0x804a5c0
    113  19
    114 
    115  haha0x804a5c0
    116  19
    117 
    118  haha0x804a5c0
    119  20
    120 
    121  ha ha wa
    122  haha0x804a5c0
    123  20
    124 
    125  haha0x804a5c0
    126  21
    127 
    128  haha0x804a5c0
    129  21
    130 
    131  haha0x804a5c0
    132  22
    133 
    134  destruct0x804a5c0
    135 
    local static , , , static ,
          main          ,                。

    Singlton        ,   C++  ,       ,            。
                   singlton  ,          ,     shared_ptr,          。
          OPEMESH  singlton     ,              static  (             )。
            main      siglton    , shared_ptr     new   , OPEMESH   static       (       ).
    //  shared_ptr   singlton   
    
     
     1  #include  < iostream >
     2  #include  < tr1 / memory >
     3  using   namespace  std;
     4  using   namespace  std::tr1;
     5  template  < typename T >
     6  class  Singlton {
     7       public :
     8           static  T *  instance();
     9           static   void  create();
    10           void  print() {
    11               cout  <<   " haha "   <<  endl;
    12          }
    13           ~ Singlton() {
    14              cout  <<   " destruct singlton "   <<  endl;
    15          }
    16       protected :
    17          Singlton();
    18       // private:
    19       protected :
    20           static  shared_ptr < T >  s_instance; 
    21           // Singlton();
    22  };
    23  template  < typename T >
    24  shared_ptr < T >  Singlton < T > ::s_instance;
    25 
    26  template  < typename T >
    27  Singlton < T > ::Singlton() {
    28      cout  <<   " construct singlton "   <<  endl;
    29  }
    30 
    31  template  < typename T >
    32  T *  Singlton < T > ::instance() {
    33       return  s_instance. get ();
    34  }
    35 
    36  template  < typename T >
    37  void  Singlton < T > ::create() {
    38       if  ( ! s_instance. get ())
    39          s_instance.reset( new  T);
    40 
    41  }
    42 
    43  //  well  , Singlton<T>::create()   MySinglton ,
    44  //      Singlton<MySinglton>::create()
    45  // class MySinglton : public Singlton<MySinglton> {
    46  //      // private:
    47  //     public:
    48  //         MySinglton(){
    49  //             cout << "construct my singlton" << endl;
    50  //         }
    51  //
    52  // };
    53  class  MySinglton :  public  Singlton < MySinglton >  {
    54          friend   class  Singlton < MySinglton > ;
    55       private :
    56          MySinglton(){
    57              cout  <<   " construct my singlton "   <<  endl;
    58          }
    59          MySinglton  *  MyInstance() {
    60               return  s_instance. get ();
    61          }
    62  };
    63 
    64  // or can directyly define one class like MyClass1, and to not consider siglton part,
    65  // than use Singlton<MyClass1>  is OK. May be typedef Singlton<MyClass1> MyClass1Singlton 
    66  // and use MyClass1Siglton
    67  int  main( int  argc,  char   * argv[])
    68  {
    69         
    70      MySinglton::create();
    71      MySinglton *  p_my_singlton  =  MySinglton::instance();
    72      p_my_singlton -> print();
    73       return   0 ;
    74  }
    75  /* result
    76  construct singlton
    77  construct my singlton
    78  haha
    79  destruct singlton
    80  */
    OPMESH singlton      ,        :)
    
      
      1  // SingltonT.hh
      2  // =============================================================================
      3  //
      4  //   Implements a simple singleton template
      5  //
      6  // =============================================================================
      7 
      8 
      9  #ifndef __SINGLETON_HH__
     10  #define  __SINGLETON_HH__
     11 
     12 
     13  // === INCLUDES ================================================================
     14 
     15  //  OpenMesh
     16  #include  < OpenMesh / Core / System / config.h >
     17 
     18  //  STL
     19  #include  < stdexcept >
     20  #include  < iostream >
     21 
     22 
     23  // == NAMESPACES ===============================================================
     24 
     25 
     26  namespace  OpenMesh {
     27 
     28 
     29  // === IMPLEMENTATION ==========================================================
     30 
     31 
     32  /* * A simple singleton template.
     33      Encapsulates an arbitrary class and enforces its uniqueness.
     34  */
     35 
     36  template  < typename T >
     37  class  SingletonT
     38  {
     39  public :
     40 
     41     /* * Singleton access function.
     42        Use this function to obtain a reference to the instance of the 
     43        encapsulated class. Note that this instance is unique and created
     44        on the first call to Instance().
     45     */
     46 
     47     static  T &  Instance()
     48    {
     49       if  ( ! pInstance__)
     50      {
     51         //  check if singleton alive
     52         if  (destroyed__)
     53        {
     54      OnDeadReference();
     55        }
     56         //  first time request -> initialize
     57         else
     58        {
     59      Create();
     60        }
     61      }
     62       return   * pInstance__;
     63    }
     64 
     65 
     66  private :
     67 
     68     //  Disable constructors/assignment to enforce uniqueness
     69    SingletonT();
     70    SingletonT( const  SingletonT & );
     71    SingletonT &   operator = ( const  SingletonT & );
     72 
     73     //  Create a new singleton and store its pointer
     74     static   void  Create()
     75    {
     76       static  T theInstance;
     77      pInstance__  =   & theInstance;
     78    }
     79    
     80     //  Will be called if instance is accessed after its lifetime has expired
     81     static   void  OnDeadReference()
     82    {
     83       throw  std::runtime_error( " [Singelton error] - Dead reference detected!
    " );
     84    }
     85 
     86     virtual   ~ SingletonT()
     87    {
     88      pInstance__  =   0 ;
     89      destroyed__  =   true ;
     90    }
     91    
     92     static  T *      pInstance__;
     93     static   bool    destroyed__;
     94  };
     95 
     96 
     97 
     98  // =============================================================================
     99  //  namespace OpenMesh
    100  // =============================================================================
    101  #if  defined(OM_INCLUDE_TEMPLATES) && !defined(OPENMESH_SINGLETON_C)
    102  #  define OPENMESH_SINGLETON_TEMPLATES
    103  #  include  " SingletonT.cc "
    104  #endif
    105  // =============================================================================
    106  #endif   //  __SINGLETON_HH__
    107  // =============================================================================
    108 
    109 
    110  // SingltonT.cc
    111  // =============================================================================
    112  //
    113  //   Implements a simple singleton template
    114  //
    115  // =============================================================================
    116 
    117 
    118  #define  OPENMESH_SINGLETON_C
    119 
    120 
    121  // == INCLUDES =================================================================
    122 
    123 
    124  //  header
    125  #include  < OpenMesh / Core / Utils / SingletonT.hh >
    126 
    127 
    128  // == NAMESPACES ===============================================================
    129 
    130 
    131  namespace  OpenMesh {
    132 
    133 
    134  // == SINGLETON'S DATA =========================================================
    135 
    136 
    137  template  < class  T >  
    138  T *  SingletonT < T > ::pInstance__  =   0 ;
    139 
    140  template  < class  T >
    141  bool  SingletonT < T > ::destroyed__  =   false ;
    142 
    143 
    144  // =============================================================================
    145  //  namespace OpenMesh
    146  // =============================================================================
    147 
    typedef SingletonT<LoopSchemeMaskDouble>    LoopSchemeMaskDoubleSingleton;
    
  • singlton in python

  • pythonでは著者らが述べたsingltonの概念が緩和され,
               Alex Martelli makes the observation that what we really want with a            Singleton is to have a single set of state data for all objects. That is, you            could create as many objects as you want and as long as they all refer to            the same state information then you achieve the effect of Singleton.
    任意に多くのオブジェクトを持つことができますが、同じステータス情報、すなわちsingltonを指します.Borg利用_dict__属性が巧みに一つ実現した
    singltonモード.
    
    
      
     1  class  Borg():
     2      shared_dict  =  {}
     3       def   __init__ (self):
     4          self. __dict__   =  self.shared_dict  
     5 
     6  class  Singleton(Borg):
     7       def   __init__ (self, arg):
     8          Borg. __init__ (self)
     9          self.val  =  arg
    10       def   __str__ (self): 
    11           print (self. __dict__ )
    12           return  self.val
    13 
    14 
    15  if   __name__   ==   ' __main__ ' :
    16      x  =  Singleton( ' abc ' )
    17      y  =  Singleton( ' def ' )
    18       print (x)
    19       print (y)
    20 
    21  output  =   '''
    22  {'val': 'def'}
    23  def
    24  {'val': 'def'}
    25  def
    26  '''

    このスキームは,簡潔で明確であり,継承によって多重化しやすい.もちろん著者らは,以下の方法と比較して,多くの他の実装方法についても言及した.
      1 class OnlyOne:
     2 
     3 
        
    class
     
    __OnlyOne
    :
     4 
            
    def
     
    __init__
    (self, arg):
     5 
                self.val 
    =
     arg
     6 
            
    def
     
    __str__
    (self):
     7 
                
    return
     
    '
    self
    '
     
    +
     self.val
     8 
                
    #
    return `self` + self.val
     9 
        instance 
    =
     None
    10 
        
    def
     
    __init__
    (self, arg):
    11 
            
    if
     
    not
     OnlyOne.instance:
    12 
                OnlyOne.instance 
    =
     OnlyOne.
    __OnlyOne
    (arg)
    13 
            
    else
    :
    14 
                OnlyOne.instance.val 
    =
     arg
    15 
        
    def
     
    __getattr__
    (self, name):
    16 
            
    return
     getattr(self.instance, name)
    17 
    18 
    19 

    =
     OnlyOne(
    '
    sausage
    '
    )
    20 
    print
    (x)
    21 

    =
     OnlyOne(
    '
    eggs
    '
    )
    22 
    print
    (y)
    23 

    =
     OnlyOne(
    '
    spam
    '
    )
    24 
    print
    (z)
    25 
    26 
    print
    (x)
    27 
    print
    (y)
    28 
    print
    (z)
    29 
    print
    (
    '
    x
    '
    )
    30 
    print
    (
    '
    y
    '

    31 
    print
    (
    '
    z
    '

    32 
    33 
    print
    (x.instance)
    34 
    output 
    =
     
    '''
    35 
    selfsausage
    36 
    selfeggs
    37 
    selfspam
    38 
    selfspam
    39 
    selfspam
    40 
    selfspam
    41 
    x
    42 
    y
    43 
    z
    44 
    selfspam
    45 
    '''