请问你了解哪些设计模式?
常见的设计模式如下:
单例模式:确保单例类全局只有一个实例,并提供该实例的全局访问点。单例模式的实现核心是将 类 的构造函数设置为私有,并预留一个获取全局唯一对象的静态函数,用于外界获得该实例。根据实例化的时间可以分为懒汉模式和饿汉模式,区别就在于是使用的时候实例化还是在系统启动的时候就初始化。
工厂模式:是一个创建对象的接口,但是由子类决定实例化哪个类。工厂方法把实例化操作延迟到子类。
生成器模式:是一个创建型设计模式,如果一个类包含大量的部件,可以通过一个额外的生成器来分步骤创建复杂的对象,然后将创建的对象返回。
模板模式:定义算法框架,并将一些步骤延迟到子类实现,例如 常见的目标检测,包含了图像读取,预处理,检测,可视化,这几个子过程。如果更改其中的预处理的方法,那么只用在子类中重写预处理函数即可,其他过程都可以复用。weak_ptr
观察者模式:原理类似于所有观察者都实现一个 updata 接口,然后将所有的观察者注册进被观察者中,当被观察者状态变化时循环通过 update 接口通知所有观察者。
装饰模式:是静态继承的一种替代,通过装饰模式可以动态的给原有的对象增加新的功能。装饰类和被装饰类之间不存在耦合不相互影响。这种模式对被装饰类进行包装,在装饰类中持有被装饰类的对象,实现在保持原有功能前提下实现新的功能。除了最底层的原始对象不需要依赖以外,其他装饰对象都要携带一个指针指向它装饰的对象,装饰的过程像一个链表层层叠加。
请你说一说OOP的设计模式的五项原则
单一职责原则:每个类只负责单一的责任,如果一个任务很复杂,应该将他分散的多个类种实现,减少类的耦合,提高类的复用性。 依赖倒置原则:核心是面向接口编程的思想。高层模块不能依赖于底层模块,他们应该共同依赖于抽象(接口),因为抽象更稳定。在高层模块和底层模块之间抽象出一个稳定的接口层,降低他们之间的耦合。 里氏替换原则:这个原则是说 子类对象要能够完全替换父类,即可以使用父类的地方也要能使用子类替换。并在客户端中使用父类指针或引用类型来引用子类,以实现动态绑定。 接口隔离原则:不应该强迫客户依赖于它们不用的方法。因此使用多个专门的接口比使用单一的总接口要好。 开放-封闭原则:在新增功能时,不需要修改原有的代码 最少知识原则:
请问如何保证单例模式只有唯一实例?你知道的都有哪些方法?
构造函数设置为私有属性,只有通过该类提供的静态方法来得到该类的唯一实例。在静态方法中判断 指向实例的静态成员指针为空,就实例化类,否则直接返回。(必须是静态成员指针,因为静态成员函数无法访问非静态成员变量)
单例模式有懒汉模式,可能会线程不安全,如果多个线程同时通过了指针空判断,就会创建出多个实例,通过双重锁来实现线程安全。(判空,上锁,再判空,为啥要用双重锁?如果已经实例化了,通过第一个判空操作能避免读的时候加锁等待,提高性能。第二个锁就是为了防止创建对象的时候多线程竞争) 另一个是饿汉模式,在程序运行时就完成了对象初始化,因此不存在不安全问题。
请你说说工厂模式的优点?
为了解耦,将对象的使用过程和创建过程分离。如果对象创建过程包含了复杂的创建逻辑,可以统一放在工厂类中实现,实现代码复用。充分利用了面向对象的多态性质,工厂对象返回的是指向具体子类的基类指针,如果后续修改了子类的业务逻辑,也只用修改工厂中的初始化逻辑,方便维护。
请你说一下观察者模式
观察者模式中分为观察者和被观察者,当被观察者发生装填改变时,观察者会受到通知。主要为了解决对象状态改变给其他对象通知的问题,其实现类似于观察者在被观察者那注册了一个回调函数。
说一说装饰模式
是静态继承的一种替代,通过装饰模式可以动态的给原有的对象增加新的功能。装饰类和被装饰类之间不存在耦合不相互影响。这种模式对被装饰类进行包装,在装饰类中持有被装饰类的对象,实现在保持原有功能前提下实现新的功能。除了最底层的原始对象不需要依赖以外,其他装饰对象都要携带一个指针指向它装饰的对象,装饰的过程像一个链表层层叠加。
使用场景:1、扩展一个类的功能。 2、动态增加功能,动态撤销。
手撕单例模式
1 | using namespace std; |