OOP设计原则、单例模式、工厂模式

设计模式简介:https://www.runoob.com/design-pattern/design-pattern-intro.html

单例模式和工厂模式都是创建型模式

这些设计模式提供了一种在创建对象的同时隐藏创建逻辑的方式,而不是使用 new 运算符直接实例化对象。这使得程序在判断针对某个给定实例需要创建哪些对象时更加灵活。

设计模式的六大原则

  • 开闭原则:在程序需要进行拓展的时候,不能去修改原有的代码,实现一个热插拔的效果。简言之,是为了使程序的扩展性好,易于维护和升级。想要达到这样的效果,我们需要使用接口和抽象类,后面的具体设计中我们会提到这点。

  • 迪米特法则:最少知道原则是指:一个实体应当尽量少地与其他实体之间发生相互作用,使得系统功能模块相对独立。

  • 合成复用原则:继承和组合,优先使用组合。

  • 接口隔离原则:客户端只依赖于它所需要的接口;它需要什么接口就提供什么接口,把不需要的接口剔除掉。类间的依赖关系应建立在最小的接口上。

  • 依赖倒转原则:针对接口编程,依赖于抽象而不依赖于具体。

  • 里氏代换原则(LSP):任何基类可以出现的地方,子类一定可以出现。LSP 是继承复用的基石,只有当派生类可以替换掉基类,且软件单位的功能不受到影响时,基类才能真正被复用,而派生类也能够在基类的基础上增加新的行为。里氏代换原则是对开闭原则的补充。实现开闭原则的关键步骤就是抽象化,而基类与子类的继承关系就是抽象化的具体实现,所以里氏代换原则是对实现抽象化的具体步骤的规范。

简单工厂模式

利用工厂类去创建需要的对象

优点:

  1. 客户端和实现类解耦

  1. 对于一些创建比较复杂的类,客户端不用考虑

缺点:

  1. 增加新的功能需要修改源代码(与开闭原则不符)

  1. 在实现类过多的时候,工厂类的职责过重

适用场景:

需要创建的类不多的时候。

工厂方法模式

由于简单工厂模式不符合开闭原则,那么工厂方法模式通过将工厂抽象出去,以达到与开闭原则相符的效果

优点相对简单工厂模式来说,符合了开闭原则,但这也导致增加一个类就需要增加一个工厂,增加了维护成本。

简单工厂模式 + “开闭原则” = 工厂方法模式

适用场景:

客户端不知道具体需要哪种东西的时候,如上图所示。

使用场景: 1、日志记录器:记录可能记录到本地硬盘、系统事件、远程服务器等,用户可以选择记录日志到什么地方。 2、数据库访问,当用户不知道最后系统采用哪一类数据库,以及数据库可能有变化时。 3、设计一个连接服务器的框架,需要三个协议,"POP3"、"IMAP"、"HTTP",可以把这三个作为产品类,共同实现一个接口。

注意:作为一种创建类模式,在任何需要生成复杂对象的地方,都可以使用工厂方法模式。有一点需要注意的地方就是复杂对象适合使用工厂模式,而简单对象,特别是只需要通过 new 就可以完成创建的对象,无需使用工厂模式。如果使用工厂模式,就需要引入一个工厂类,会增加系统的复杂度。

抽象工厂模式

抽象工厂针对的是产品族,而不是产品等级结构。

产品族:属于同一产地或厂商功能不同

产品等级结构:功能相同,产地或厂商不同

抽象工厂模式,针对的是产品族而不是产品等级结构,因为如果要扩充产品族的话,工厂需要增加代码来实现,从而不符合开闭原则;但是扩充产品等级结构则不需要修改工厂代码,只需要新增一个派生类即可。

如上图所示,需要相应的东西直接使用对应的工厂进行生产即可,在定义水果或工厂时,也不需要指定具体的工厂或水果。

优点:当一个产品族中的多个对象被设计成一起工作时,它能保证客户端始终只使用同一个产品族中的对象。

缺点:产品族扩展非常困难,要增加一个系列的某一产品,既要在抽象的 Creator 里加代码,又要在具体的里面加代码。

单例模式

这种模式涉及到一个单一的类,该类负责创建自己的对象,同时确保只有单个对象被创建。这个类提供了一种访问其唯一的对象的方式,可以直接访问,不需要实例化该类的对象。

注意:

  • 1、单例类只能有一个实例

  • 2、单例类必须自己创建自己的唯一实例

  • 3、单例类必须给所有其他对象提供这一实例。

  • 实现单例模式的步骤

//懒汉模式
class SingletonLazy
{
private:
    SingletonLazy(){}

private:
    static SingletonLazy* pSingleton;
public:
    static SingletonLazy* getInstance(){
        if (pSingleton == nullptr) {
            pSingleton = new SingletonLazy;
        }
        return pSingleton;
    }
};
SingletonLazy* SingletonLazy::pSingleton = nullptr;
//饿汉模式
class SingletonHungary
{
private:
    SingletonHungary(){}

private:
    static SingletonHungary* pSingleton;
public:
    static SingletonHungary* getInstance(){
        return pSingleton;
    }
};
SingletonHungary* SingletonLazy::pSingleton = new SingletonHungary;//初始化创建
  1. 单例模式下的对象一般不需要释放

  1. 饿汉式对多线程是安全的,因为其在初始化就创建了

  1. 懒汉式对多线程是不安全的,因为可能存在两个线程同时调用实例化的情况存在。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值