【GeekBand】设计模式3

1.单件模式

1.1使用动机

必须保证一些特殊的类在系统中只有一个实例,以确保逻辑的正确性和效率。比如数据层,网络层。
绕过常规的构造器,提供一种机制来保证一个类只有一个实例,以解决性能问题。(工厂模式绕过构造器是要解决紧耦合的问题。)
有必要只提供一个唯一的实例,不让有“能生成多个实例”的机会。模式定义
保证一个类仅有一个实例,并提供一个该实例的全局访问点。--《设计模式》GoF结构


【GeekBand】设计模式3_第1张图片

单件模式

1.2要点总结

单件模式中的实例构造器可以设置为protected以允许子类派生。
单件模式一般不要支持拷贝构造函数和Clone接口,因为这有可能导致出现多个对象实例而有悖初衷
注意多线程环境下安全的单件模式,注意对双检查锁的正确实现。

1.3 实现方法

class singleton  
{  
public:  
    ~singleton()  
    {//析构时使用  
    }  
    static singleton* getInstance()  
    {  
        if(_instance == NULL)  
        {  
            _instance = new singleton();  
        }  
        return _instance;  
    }  
  
private:  
    static singleton *_instance;  
  
private:  
//最好将所有此类的实例化的进口全部堵死  
    singleton()  
    {  
  
    }  
    singleton(const singleton&)  
    {  
  
    }  
    singleton& operator=(const singleton &)  
    {  
  
    }  
};  
singleton *singleton::_instance = NULL;  

2.享元模式

2.1 定义

(英语:Flyweight Pattern)是一种软件设计模式。它使用共享物件,用来尽可能减少内存使用量以及分享资讯给尽可能多的相似物件;它适合用于只是因重复而导致使用无法令人接受的大量内存的大量物件。通常物件中的部分状态是可以分享。常见做法是把它们放在外部数据结构,当需要使用时再将它们传递给享元。

2.2 使用场景

如果一个应用程序使用了大量的对象,而这些对象造成了很大的存储开销的时候就可以考虑是否可以使用享元模式。
例如,如果发现某个对象的生成了大量的实例,并且这些实例除了几个参数外基本是相同的,如果把那些共享参数移到类外面,在方法调用时将他们传递进来,就可以通过共享大幅度单个实例的数目。

2.3 实现

class FontFactory{
private:
    map fontPool;
    
public:
    Font* GetFont(const string& key){

        map::iterator item=fontPool.find(key);
        
        if(item!=footPool.end()){
            return fontPool[key];
        }
        else{
            Font* font = new Font(key);
            fontPool[key]= font;
            return font;
        }

    }
    
    void clear(){
        //...
    }
};

3.状态模式

3.1 定义

当一个对象的内在状态改变时允许改变其行为,这个对象看起来像是改变了其类。
状态模式主要解决的是当控制一个对象状态的条件表达式过于复杂时的情况。把状态的判断逻辑转移到表示不同状态的一系列类中,可以把复杂的判断逻辑简化。

3.2 适用 场景

1.一个对象的行为取决于它的状态,并且它必须在运行时刻根据状态改变它的行为。
2.一个操作中含有庞大的多分支结构,并且这些分支决定于对象的状态。

3.3 实现

class NetworkState{

public:
    NetworkState* pNext;
    virtual void Operation1()=0;
    virtual void Operation2()=0;
    virtual void Operation3()=0;

    virtual ~NetworkState(){}
};


class OpenState :public NetworkState{
    
    static NetworkState* m_instance;
public:
    static NetworkState* getInstance(){
        if (m_instance == nullptr) {
            m_instance = new OpenState();
        }
        return m_instance;
    }

    void Operation1(){
        
        //**********
        pNext = CloseState::getInstance();
    }
    
    void Operation2(){
        
        //..........
        pNext = ConnectState::getInstance();
    }
    
    void Operation3(){
        
        //$$$$$$$$$$
        pNext = OpenState::getInstance();
    }
    
    
};

class CloseState:public NetworkState{ }
//...


class NetworkProcessor{
    
    NetworkState* pState;
    
public:
    
    NetworkProcessor(NetworkState* pState){
        
        this->pState = pState;
    }
    
    void Operation1(){
        //...
        pState->Operation1();
        pState = pState->pNext;
        //...
    }
    
    void Operation2(){
        //...
        pState->Operation2();
        pState = pState->pNext;
        //...
    }
    
    void Operation3(){
        //...
        pState->Operation3();
        pState = pState->pNext;
        //...
    }

};


4.组合模式

4.1 定义

将对象组合成树形结构以表示“部分整体”的层次结构。组合模式使得用户对单个对象和组合对象的使用具有一致性。

4.2 适用场景

以下情况下适用Composite模式:
1.你想表示对象的部分-整体层次结构
2.你希望用户忽略组合对象与单个对象的不同,用户将统一地使用组合结构中的所有对象。

4.3 实现

#include 
#include 
#include 
#include 

using namespace std;

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

class Composite : public Component{
    
    string name;
    list elements;
public:
    Composite(const string & s) : name(s) {}
    
    void add(Component* element) {
        elements.push_back(element);
    }
    void remove(Component* element){
        elements.remove(element);
    }
    
    void process(){
        
        //1. process current node
        
        
        //2. process leaf nodes
        for (auto &e : elements)
            e->process(); 
         
    }
};


class Leaf : public Component{
    string name;
public:
    Leaf(string s) : name(s) {}
            
    void process(){
        //process current node
    }
};


void Invoke(Component & c){
    //...
    c.process();
    //...
}


int main()
{

    Composite root("root");
    Composite treeNode1("treeNode1");
    Composite treeNode2("treeNode2");
    Composite treeNode3("treeNode3");
    Composite treeNode4("treeNode4");
    Leaf leat1("left1");
    Leaf leat2("left2");
    
    root.add(&treeNode1);
    treeNode1.add(&treeNode2);
    treeNode2.add(&leaf1);
    
    root.add(&treeNode3);
    treeNode3.add(&treeNode4);
    treeNode4.add(&leaf2);
    
    process(root);
    process(leaf2);
    process(treeNode3);
  
}

你可能感兴趣的:(【GeekBand】设计模式3)