您的位置: 首页 - 站长

sqlite 网站开发建个网站平台需要多少钱

当前位置: 首页 > news >正文

sqlite 网站开发,建个网站平台需要多少钱,揭阳市建设局网站,创意设计图片大全前言#xff1a; 本期#xff0c;我将要讲解的是有关C中常见的设计模式之单例模式的相关知识#xff01;#xff01; 目录 #xff08;一#xff09;设计模式的六⼤原则 #xff08;二#xff09;设计模式的分类 #xff08;三#xff09;单例模式 1、定义 2、…前言 本期我将要讲解的是有关C中常见的设计模式之单例模式的相关知识 目录 一设计模式的六⼤原则 二设计模式的分类 三单例模式 1、定义 2、实现方式 1️⃣ 懒汉模式 2️⃣ 饿汉模式 四懒汉模式的安全实现 总结 首先我们需要知道的是设计模式是前辈们对代码开发经验的总结是解决特定问题的⼀系列套路。它不是语法规定⽽是⼀套⽤来提⾼代码可复⽤性、可维护性、可读性、稳健性以及安全性的解决⽅案。   一设计模式的六⼤原则 单⼀职责原则Single Responsibility Principle 类的职责应该单⼀⼀个⽅法只做⼀件事。职责划分清晰了每次改动到最⼩单位的⽅法或类。使用建议两个完全不⼀样的功能不应该放⼀个类中⼀个类中应该是⼀组相关性很⾼的函数、数据的封装用例⽹络聊天⽹络通信聊天应该分割成为⽹络通信类聊天类   开闭原则Open Closed Principle 对扩展开放对修改封闭使用建议对软件实体的改动最好⽤扩展⽽⾮修改的⽅式。用例超时卖货商品价格—不是修改商品的原来价格⽽是新增促销价格。 ⾥⽒替换原则Liskov Substitution Principle 通俗点讲就是只要⽗类能出现的地⽅⼦类就可以出现⽽且替换为⼦类也不会产⽣任何错误或异常。在继承类时务必重写⽗类中所有的⽅法尤其需要注意⽗类的protected⽅法⼦类尽量不要暴露⾃⼰的public⽅法供外界调⽤。使用建议⼦类必须完全实现⽗类的⽅法孩⼦类可以有⾃⼰的个性。覆盖或实现⽗类的⽅法时输⼊参数可以被放⼤输出可以缩⼩用例跑步运动员类 – 会跑步⼦类⻓跑运动员 – 会跑步且擅⻓⻓跑⼦类短跑运动员-会跑步且擅⻓短跑 依赖倒置原则Dependence Inversion Principle ⾼层模块不应该依赖低层模块两者都应该依赖其抽象。不可分割的原⼦逻辑就是低层模式原⼦逻辑组装成的就是⾼层模块。模块间依赖通过抽象接⼝发⽣具体类之间不直接依赖使用建议每个类都尽量有抽象类任何类都不应该从具体类派⽣。尽量不要重写基类的⽅法。结合⾥⽒替换原则使⽤。用例奔驰⻋司机类–只能开奔驰司机类–给什么⻋就开什么⻋开⻋的⼈司机–依赖于抽象 迪⽶特法则Law of Demeter⼜叫“最少知道法则” 尽量减少对象之间的交互从⽽减⼩类之间的耦合。⼀个对象应该对其他对象有最少的了解。对类的低耦合提出了明确的要求只和直接的朋友交流朋友之间也是有距离的。⾃⼰的就是⾃⼰的如果⼀个⽅法放在本类中既不增加类间关系也对本类不产⽣负⾯影响那就放置在本类中用例⽼师让班⻓点名–⽼师给班⻓⼀个名单班⻓完成点名勾选返回结果⽽不是班⻓点名⽼师勾选 接⼝隔离原则Interface Segregation Principle 客⼾端不应该依赖它不需要的接⼝类间的依赖关系应该建⽴在最⼩的接⼝上使用建议接⼝设计尽量精简单⼀但是不要对外暴露没有实际意义的接⼝。用例修改密码不应该提供修改⽤⼾信息接⼝⽽就是单⼀的最⼩修改密码接⼝更不要暴露数据库操作 从整体上来理解六⼤设计原则可以简要的概括为⼀句话⽤抽象构建框架⽤实现扩展细节具体到每⼀条设计原则则对应⼀条注意事项 单⼀职责原则告诉我们实现类要职责单⼀⾥⽒替换原则告诉我们不要破坏继承体系依赖倒置原则告诉我们要⾯向接⼝编程接⼝隔离原则告诉我们在设计接⼝的时候要精简单⼀迪⽶特法则告诉我们要降低耦合开闭原则是总纲告诉我们要对扩展开放对修改关闭。 二设计模式的分类 设计模式可以根据其目的和使用方式进行分类。以下是常见的设计模式分类 创建型模式Creational Patterns这些模式关注对象的创建过程用于实例化对象的方式。常见的创建型模式包括 单例模式Singleton Pattern工厂模式Factory Pattern抽象工厂模式Abstract Factory Pattern建造者模式Builder Pattern原型模式Prototype Pattern 结构型模式Structural Patterns这些模式关注对象之间的组合和关联方式以形成更大的结构。常见的结构型模式包括 适配器模式Adapter Pattern装饰器模式Decorator Pattern代理模式Proxy Pattern桥接模式Bridge Pattern组合模式Composite Pattern外观模式Facade Pattern享元模式Flyweight Pattern 行为型模式Behavioral Patterns这些模式关注对象之间的通信和交互方式以定义对象之间的责任分配和行为。常见的行为型模式包括 观察者模式Observer Pattern策略模式Strategy Pattern模板方法模式Template Method Pattern命令模式Command Pattern迭代器模式Iterator Pattern状态模式State Pattern职责链模式Chain of Responsibility Pattern中介者模式Mediator Pattern访问者模式Visitor Pattern备忘录模式Memento Pattern解释器模式Interpreter Pattern 除了这些主要的分类其实还有并发模式和线程池模式。 三单例模式 本期我们先学习设计模式中的第一种模式——单例模式。 1、定义 ⼀个类只能创建⼀个对象即单例模式该设计模式可以保证系统中该类只有⼀个实例并提供⼀个访问它的全局访问点该实例被所有程序模块共享。⽐如在某个服务器程序中该服务器的配置信息存放在⼀个⽂件中这些配置数据由⼀个单例对象统⼀读取然后服务进程中的其他对象再通过这个单例对象获取这些配置信息这种⽅式简化了在复杂环境下的配置管理。 2、实现方式 单例模式通常有两种模式分别为懒汉式单例和饿汉式单例。两种模式实现方式分别如下   1️⃣ 懒汉模式   如果单例对象构造十分耗时或者占用很多资源比如加载插件啊 初始化网络连接啊读取文件啊等等而有可能该对象程序运行时不会用到那么也要在程序一开始就进行初始化就会导致程序启动时非常的缓慢。 所以这种情况使用懒汉模式延迟加载更好 对于懒汉模式常见的有两种设计方法 a. 静态指针 用到时初始化b. 局部静态变量   1懒汉模式实现一静态指针 用到时初始化   templatetypename T class Singleton { public:static T getInstance(){if (!_value){_value new T();}return _value;}private:Singleton() {}~Singleton(){}static T _value; };templatetypename T T* SingletonT::_value NULL; 【解释说明】 在单线程中这样的写法是可以正确使用的但是在多线程中就不行了该方法是线程不安全的。 a. 假如线程A和线程B, 这两个线程要访问getInstance函数线程A进入getInstance函数并检测if条件由于是第一次进入value为空if条件成立准备创建对象实例。b. 但是线程A有可能被OS的调度器中断而挂起睡眠而将控制权交给线程B。c. 线程B同样来到if条件发现value还是为NULL因为线程A还没来得及构造它就已经被中断了。此时假设线程B完成了对象的创建并顺利的返回。d. 之后线程A被唤醒继续执行new再次创建对象这样一来两个线程就构建两个对象实例这就破坏了唯一性 另外还存在内存泄漏的问题new出来的东西始终没有释放下面是一种饿汉式的一种改进。   templatetypename T class Singleton { public:static T getInstance(){if (!_value){_value new T();}return _value;}private:// 实现一个内嵌垃圾回收类class CGarbo{public:~CGarbo(){if (Singleton::_value)delete Singleton::_value;}};static CGarbo Garbo;Singleton(){};~Singleton(){};static T _value; };templatetypename T T* SingletonT::_value nullptr; 【解释说明】 在程序运行结束时系统会调用 Singleton 的静态成员Garbo的析构函数该析构函数会删除单例的唯一实例。 使用这种方法释放单例对象有以下特征 在单例类内部定义专有的嵌套类在单例类内定义私有的专门用于释放的静态成员利用程序在结束时析构全局变量的特性选择最终的释放时机   【注意】 需要注意的是该代码在多线程环境下并不是线程安全的如果多个线程同时用 getInstance()有可能会创建多个对象。为了实现线程安全的单例模式需要使用适当的同步机制例如使用互斥锁或双重检查锁定这个下面会讲到 2懒汉模式实现二局部静态变量   templatetypename T class Singleton { public:static T getInstance() {static T instance;return instance;}private:Singleton() {}~Singleton() {}Singleton(const Singleton);Singleton operator(const Singleton); }; 【解释说明】 在上述代码中将拷贝构造函数和赋值操作符的声明放在了私有部分但没有给它们提供定义。这样任何尝试在类外部调用这些函数的操作都会导致链接错误。这种方式达到了限制拷贝的目的确保单例对象的唯一性。使用此模式时通过SingletonYourClass::getInstance() 调用 getInstance() 函数来获取到 YourClass 类的单例对象。这种实现方式也是一种常见的懒汉模式实现方法不需要使用 delete 关键字而是通过私有化拷贝构造函数和赋值操作符来限制拷贝行为从而实现单例的唯一性。 2️⃣ 饿汉模式 程序启动时就会创建⼀个唯⼀的实例对象。因为单例对象已经确定所以⽐较适⽤于多 线程环境中多线程获取单例对象不需要加锁可以有效的避免资源竞争提⾼性能。 1饿汉模式实现一直接定义静态对象   templatetypename T class Singleton { private:static T _eton; private:Singleton() {}~Singleton() {}public:Singleton(const Singleton) delete;Singleton operator(const Singleton) delete;static T getInstance(){return _eton;} };templatetypename T T SingletonT::_eton; 优点 实现简单多线程安全。 缺点 a. 如果存在多个单例对象且这几个单例对象相互依赖可能会出现程序崩溃的危险。原因:对编译器来说静态成员变量的初始化顺序和析构顺序是一个未定义的行为;b. 在程序开始时就创建类的实例如果Singleton对象产生很昂贵而本身有很少使用这种方式单从资源利用效率的角度来讲比懒汉式单例类稍差些。但从反应时间角度来讲则比懒汉式单例类稍好些。 使用条件 a. 当肯定不会有构造和析构依赖关系的情况。b. 想避免频繁加锁时的性能消耗 2饿汉模式实现二静态指针 类外初始化时new空间实现   templatetypename T class Singleton { private:static T* _eton;Singleton() {}~Singleton() {}public:Singleton(const Singleton) delete;Singleton operator(const Singleton) delete;static T getInstance(){return _eton;} };templatetypename T T SingletonT::_eton new T(); 【小结】 需要注意的是由于饿汉模式在程序启动时就创建了单例对象因此无法实现延迟加载的效果如果在程序运行过程中不一定需要使用该单例对象会导致不必要的资源消耗因此懒汉模式通常更常用只在需要时才创建单例对象。 四懒汉模式的安全实现 class Singleton { public:static Singleton* GetInstance(){// 双检查加锁if (m_pInstance nullptr) {m_mutex.lock();if (m_pInstance nullptr){m_pInstance new Singleton;}m_mutex.unlock();}return m_pInstance;}static void DelInstance(){m_mutex.lock();if (m_pInstance){delete m_pInstance;m_pInstance nullptr;}m_mutex.unlock();}// 实现一个内嵌垃圾回收类class CGarbo{public:~CGarbo(){DelInstance();}};// 定义一个静态成员变量程序结束时系统会自动调用它的析构函数从而释放单例对象static CGarbo Garbo;// 一般全局都要使用单例对象所以单例对象一般不需要显示释放// 有些特殊场景想显示释放一下void Add(const string str){_vmtx.lock();_v.push_back(str);_vmtx.unlock();}void Print(){_vmtx.lock();for (auto e : _v){cout e endl;}cout endl;_vmtx.unlock();}~Singleton(){// 持久化// 比如要求程序结束时将数据写到文件单例对象析构时持久化就比较好} private:mutex _vmtx;vectorstring _v;private:// 构造函数私有Singleton(){}// 防拷贝//Singleton(Singleton const);//Singleton operator (Singleton const);static mutex m_mutex; //互斥锁static Singleton* m_pInstance; // 单例对象指针 };Singleton* Singleton::m_pInstance nullptr; Singleton::CGarbo Garbo; mutex Singleton::m_mutex;int main() {srand(time(0));int n 3000;thread t1(n {for (size_t i 0; i n; i){Singleton::GetInstance()-Add(t1线程: to_string(rand()));}});thread t2(n {for (size_t i 0; i n; i){Singleton::GetInstance()-Add(t2线程: to_string(rand()));}});t1.join();t2.join();Singleton::GetInstance()-Print();return 0; } 总结 到此关于单例模式的讲解便到此结束了。接下来简单的回顾总结一下本文 懒汉模式和饿汉模式都是单例模式的实现方式都用于确保一个类只有一个实例并提供全局访问点。 懒汉模式是指在首次使用时才创建对象实例。具体实现上懒汉模式通常通过延迟加载的方式在getInstance()方法中进行判断如果实例尚未创建则在需要时才创建并返回。懒汉模式的优点是节省了资源只有在需要时才会创建实例但缺点是在多线程环境下需要额外的同步机制以确保线程安全。饿汉模式是指在类加载时即创建对象实例。具体实现上饿汉模式通过在类的静态成员变量中直接创建实例对象并在getInstance()方法中返回该实例。饿汉模式的优点是实现简单不需要考虑多线程同步的问题但缺点是在应用程序启动时就会创建实例可能会浪费一些资源。 在实际应用中根据具体情况权衡懒汉模式和饿汉模式的优缺点并选择适合的实现方式。 以上便是本文的全部内容感谢大家的观看和支持