当前位置:网站首页>Composite mode

Composite mode

2022-06-26 13:11:00 baboon_ chen

Reference resources :

Composite design patterns (refactoringguru.cn)

Portfolio model ( Detailed Edition ) (biancheng.net)

design-patterns-cpp/composite at master · JakubVojvoda/design-patterns-cpp · GitHub

One 、 What is a combination pattern ?

Definition : Combine objects into a tree hierarchy , So that the user can understand Leaf nodes ( Single object ) and Tree node ( Combine objects ) Have consistent accessibility .

The most important point is , The objects that users need to process can be represented in a hierarchical structure . The tree itself is a recursive hierarchical structure . If both tree nodes and leaf nodes implement the same interface , So no matter how the tree is expanded or reduced , Will not affect its access .

For example, the armies of most countries adopt hierarchical management . Each unit consists of several divisions , A division consists of brigades , Brigade consists of regiments , The regiment can continue to be divided into rows . Last , Each platoon consists of a small group of real soldiers . Military orders are issued at the highest level , Pass... Through each level , Until every soldier knows what he should obey . No matter how variable the number of troops , Orders are always given .


 Insert picture description here

 Insert picture description here

Two 、 Realization

Combine (Composite ) The pattern includes the following main characters :

  1. Abstract component (Component) role : Its main function is to declare the common interface for the leaf component and the branch component , And implement their default behavior . Abstract components also declare interfaces to access and manage subclasses in transparent composition patterns ; Interfaces to access and manage subclasses are not declared in a secure composite pattern , The management work is done by the branch component .( Total abstract class or interface , Define some general methods , For example, adding 、 Delete )
  2. Leaf components (Leaf) role : Is the leaf node object in the assembly , It has no child nodes , Used to inherit or implement abstract components .
  3. Tree branches (Composite) role / Intermediate members : Is the branch node object in the composite , It has children , Used to inherit and implement abstract components . Its main function is to store and manage sub components , Usually contains Add()、Remove()、GetChild() Other methods .

The combination mode can be divided into transparent combination mode and safe combination mode .

1、 Transparent way

Leaf nodes (Leaf) And Tree node (Composite) It's all done Abstract component (Component) Interface . If Component It defines Add()Remove()GetChild() Other methods , Leaf nodes don't need , But to achieve them ( Empty implementation or throw exception ), This will bring some security problems . This has the advantage that the client does not have to distinguish between leaf objects and branch objects , Transparent to clients .

 Insert picture description here

/*
 * C++ Design Patterns: Composite
 * Author: Jakub Vojvoda [github.com/JakubVojvoda]
 * 2016
 *
 * Source code is licensed under MIT License
 * (for more details see LICENSE)
 *
 */

#include <iostream>
#include <vector>

/*
 * Component
 *  Declare common interfaces for leaf and branch components 
 *  Here is the transparent combination mode , Abstract artifacts also declare interfaces to access and manage subclasses :Add\remove\getChild
 */
class Component
{
public:
  virtual ~Component() {}
  
  virtual Component *getChild( int )
  {
    return 0;
  }
  
  virtual void add( Component * ) { /* ... */ }
  virtual void remove( int ) { /* ... */ }
  
  virtual void operation() = 0;
};

/*
 * Composite
 *  Is the tree node object in the composition , It has children , Used to inherit and implement abstract components .
 *  Its main function is to store and manage sub components 
 */
class Composite : public Component
{
public:
  ~Composite()
  {
    for ( unsigned int i = 0; i < children.size(); i++ )
    {
      delete children[ i ];
    }
  }
  
  Component *getChild( const unsigned int index )
  {
    return children[ index ];
  }
  
  void add( Component *component )
  {
    children.push_back( component );
  }
  
  void remove( const unsigned int index )
  {
    Component *child = children[ index ];
    children.erase( children.begin() + index );
    delete child;
  }
  
  void operation()
  {
    for ( unsigned int i = 0; i < children.size(); i++ )
    {
      children[ i ]->operation();
    }
  }
  
private:
  std::vector<Component*> children;
};

/*
 * Leaf
 *  The leaf node object in the combination , It has no child nodes , Used to inherit or implement abstract components 
 */
class Leaf : public Component
{
public:
  Leaf( const int i ) : id( i ) {}
  
  ~Leaf() {}
  
  void operation()
  {
    std::cout << "Leaf "<< id <<" operation" << std::endl;
  }

private:
  int id;
};


int main()
{
  Composite composite;
  
  for ( unsigned int i = 0; i < 5; i++ )
  {
    composite.add( new Leaf( i ) );
  }
  
  composite.remove( 0 );
  composite.operation();
  
  return 0;
}

2、 safe mode

The method of managing leaf nodes is implemented only in tree nodes (Add、Remove etc. ).

 Insert picture description here

#include <iostream>
#include <vector>

class Component
{
public:
  virtual ~Component() {}
   
  virtual void operation() = 0;
};

class Composite : public Component
{
public:
  ~Composite()
  {
    for ( unsigned int i = 0; i < children.size(); i++ )
    {
      delete children[ i ];
    }
  }
  
  Component *getChild( const unsigned int index )
  {
    return children[ index ];
  }
  
  void add( Component *component )
  {
    children.push_back( component );
  }
  
  void remove( const unsigned int index )
  {
    Component *child = children[ index ];
    children.erase( children.begin() + index );
    delete child;
  }
  
  void operation()
  {
    for ( unsigned int i = 0; i < children.size(); i++ )
    {
      children[ i ]->operation();
    }
  }
  
private:
  std::vector<Component*> children;
};

class Leaf : public Component
{
public:
  Leaf( const int i ) : id( i ) {}
  
  ~Leaf() {}
  
  void operation()
  {
    std::cout << "Leaf "<< id <<" operation" << std::endl;
  }

private:
  int id;
};


int main()
{
  Composite composite;
  
  for ( unsigned int i = 0; i < 5; i++ )
  {
    composite.add( new Leaf( i ) );
  }
  
  composite.remove( 0 );
  composite.operation();
  
  return 0;
}

3、 ... and 、 Advantages and disadvantages , Applicable scenario

advantage

  • The composite pattern allows client code to consistently handle individual and composite objects .
  • It's easier to add new objects to the mix , The client will not change the source code because of adding new objects , It satisfies the open close principle .

shortcoming

  • The design is more complicated , The client needs to spend more time clarifying the hierarchical relationship between classes .
  • For classes with different functions , It may be difficult to provide a common interface .

原网站

版权声明
本文为[baboon_ chen]所创,转载请带上原文链接,感谢
https://yzsam.com/2022/177/202206261224552304.html