C++学习笔记-设计模式

一、单例模式

用于某个类只能存在一个实例。主要组成为单例类、访问类。

单例类:由于只能同时存在一个实例,需要将构造函数封装(避免调用多个构造产生多个实例),并提供一个获取实例的方法。

访问类:通过单例类的方法来访问实例。

主要实现方法是实例类中包含一个静态的该类指针,将构造函数封装,外部通过该方法获得对象实例。

#include<iostream>
class A{
private:
    static A* ptr;
    A(){};
public: 
    static A* getA(){
        if(ptr != nullptr) std::cout<<"get A:"<<(void*)ptr<<std::endl;
        else ptr = new A();
        return ptr;
    }
    ~A(){};
};
A* A::ptr = nullptr;
int main(){
    A* a1=A::getA();
    A* a2=A::getA();
    A* a3=A::getA();
}

上例将构造函数封装,只能通过getA方法获得对象,并且保证了只有一个A对象。

懒汉模式:只有当第一次用到时才会实例化一个类,上述代码为懒汉模式。懒汉模式在多线程下可能会出错,例如多个线程同时使用getA()可能会实例化了多个A类。

饿汉模式:程序开始时就直接实例化。这样线程安全,但如果这个对象没有被用到,会造成资源的浪费。

如果多个不同单例模式析构函数有顺序依赖,可能会造成错误,因为单例模式构造相互依赖时析构函数顺序可能出错。

二、工厂模式

解耦合,良好的封装性,符合最少知识原则(简单讲就是避免类互相调用方法)

1. 简单工厂模式

假设你要吃饭,直接使用菜单获得想要的菜。

菜单就是一个工厂类,工厂类根据参数返回具体产品。

优点是:简单,耦合性低;缺点是:推出一个新的菜时要重新改菜单,即重写工厂类的方法。

2. 工厂模式

餐馆又推出了新的菜,写在了新菜单上,你吃新菜时找新菜单,吃旧菜时找旧菜单即可。

这样有新的菜时,只需要实现新的菜单类,不用修改已有的菜单类。

3. 抽象工厂模式

其实和工厂模式没有什么大区别,只不过抽象工厂加入了更多的方法来获得不同的产品,具体工厂实现这些方法。

优点:可以有更多类型的产品。缺点:想要添加更多类型的产品时还是要改变抽象工厂类。

三、修饰器模式

主要构成有:抽象构件(提供我们要用的方法接口)、具体构件(实现具体方法)、抽象修饰(提供对方法修饰后的方法调接口)、具体修饰(实现构件方法添加修饰后的方法)

#include<iostream>
class Hi{
public:
    virtual void sayHi(){
        std::cout<<std::endl<<"hi";
    }
};
class A:public Hi{
public:
    virtual void sayHi(){
        Hi::sayHi();
    }
};
class B:public A{
public:
    virtual void sayHi(){
        A::sayHi();
        std::cout<<"!";
    }
};
void func(Hi* hi){
    hi->sayHi();
}
int main(){
    B b;
    func(&b);
}

这里在不改变Hi类的情况下通过具体修饰改变了sayHi函数,进而可以通过传入不同的具体修饰器来使func调用不同的方法。

这也是修饰器模式的优点:可以在不改变原构件类的情况下动态添加修饰。缺点会引入较多子类,比较复杂。

  • 7
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值