带你搞懂设计模式

tech2022-08-20  82

1.UML图

2. 常见设计模式

(1) 工厂模式

1)简单工厂:

简单工厂是工厂模式最简单的一种实现,对于不同产品的创建定义一个工厂类,将产品的类型作为参数传入到工厂的创建函数,根据类型分支选择不同的产品构造函数。

2) 工厂方法:

工厂方法模式在简单工厂模式的基础上增加对工厂的基类抽象,不同的产品创建采用不同的工厂创建(从工厂的抽象基类派生),这样创建不同的产品过程就由不同的工厂分工解决。(基类抽象,增加了开闭原则,便于产品扩展)

3)抽象工厂:

抽象工厂方法适用于产品种类结构多的场合,就是当具有多个抽象产品类型时,抽象工厂便可以派上用场。 抽象工厂模式更适合实际情况,受生产线所限,让低端工厂生产不同种类的低端产品,高端工厂生产不同种类的高端产品。

(2) 策略模式:

策略模式定义了一系列的算法,并将每一个算法封装起来,而且使它们还可以相互替换。策略模式让算法独立于使用它的客户而独立变化。

(3) 单例模式:

保证一个类只有一个实例,并提供一个访问它的全局访问点,使得系统中只有唯一的一个对象实例。(简单,功能单一,适合管理资源,日志等)参考多线程的单例模式。

1)饿汉模式:

在类加载时就完成了初始化,但是加载比较慢,获取对象比较快,类一加载就实例化。

2)懒汉模式:

在类加载的时候不被初始化,第一次被引用时才实例化

(4) 装饰模式:

动态的给对象添加一些额外的职责

(5) 代理模式:

为其他对象提供一种代理,以控制对这个对象的访问(相当于媒人)

3. 设计模式常见五项原则

(1)单一职责原则

单一职责有2个含义,一个是避免相同的职责分散到不同的类中,另一个是避免一个类承担太多职责。减少类的耦合,提高类的复用性。

(2)接口隔离原则

表明客户端不应该被强迫实现一些他们不会使用的接口,应该把胖接口中额方法分组,然后用多个接口代替它,每个接口服务于一个子模块。简单说,就是使用多个专门的接口比使用单个接口好很多。 该原则观点如下: 1)一个类对另外一个类的依赖性应当是建立在最小的接口上

2)客户端程序不应该依赖它不需要的接口方法。

(3)开放-封闭原则

open模块的行为必须是开放的、支持扩展的,而不是僵化的。 closed在对模块的功能进行扩展时,不应该影响或大规模影响已有的程序模块。一句话概括:一个模块在扩展性方面应该是开放的而在更改性方面应该是封闭的。

核心思想就是对抽象编程,而不对具体编程。

(4)里氏替换原则

子类型必须能够替换掉他们的父类型、并出现在父类能够出现的任何地方。

主要针对继承的设计原则

1)父类的方法都要在子类中实现或者重写,并且派生类只实现其抽象类中生命的方法,而不应当给出多余的,方法定义或实现。

2)在客户端程序中只应该使用父类对象而不应当直接使用子类对象,这样可以实现运行期间绑定。

(5)迪米特法则

如果两个类不必彼此直接通信,那么两个就不应当发生直接的相互作用。如果其中一个类需要调用另一类的某一个方法的话,可以直接通过第三者转发这个调用。

(6)依赖倒置原则

上层模块不应该依赖于下层模块,他们共同依赖于一个抽象,即:父类不能依赖子类,他们都要依赖抽象类。抽象不能依赖于具体,具体应该要依赖于抽象。

生产消费模式

这里使用环形队列来实现生产者与消费者的写与读过程。首先我们知道队列的底层存储数据的方式其实就是一个数组,只要控制好对于队头和队尾的相关计算,我们就可以实现循环队列,而生产者依旧是在有空间的时候进行存放数据,没有空间时进入挂起等待状态,消费者则是在有数据时进行取数据,没有数据时进行挂起等待操作,这样我们便可以实现生产者和消费模型

1 #include <stdlib.h> 2 #include <pthread.h> 3 #include <stdio.h> 4 #include <semaphore.h> 5 #include <unistd.h> 6 7 #define NUM 4 8 int queue[NUM];//循环队列长度 9 10 sem_t blank_number, product_number; 11 12 void *producer(void *arg) 13 { 14 int p = 0; 15 while(1){ 16 sem_wait(&blank_number);//等待信号量,信号量减1 17 queue[p] = rand() % 1000 + 1;//循环队列头 18 printf("produce %d\n", queue[p]); 19 p = (p + 1) % NUM; 20 sem_post(&product_number);//信号量增加1 21 sleep(1); 22 23 } 24 } 25 26 void *consumer(void *arg) 27 { 28 int c = 0, i; 29 while(1) { 30 sem_wait(&product_number); 31 for(i=0; i < NUM; i++) { 32 printf("%d ", queue[i]); 33 } 34 putchar('\n'); 35 36 printf("consume %d\n", queue[c]); 37 queue[c] = 0; 38 sem_post(&blank_number); 39 c = (c+1)%NUM; 40 sleep(3); 4 42 } 43 } 44 45 int main() 46 { 47 pthread_t pid, cid; 48 49 50 sem_init(&blank_number, 0, NUM); 51 sem_init(&product_number, 0, 0); 52 pthread_create(&pid, NULL, producer, NULL);//创建线程 53 pthread_create(&cid, NULL, consumer, NULL); 54 pthread_join(pid, NULL);//等待线程结束 55 pthread_join(cid, NULL); 56 sem_destroy(&blank_number);//销毁信号量 57 sem_destroy(&product_number); 58 return 0; 59 }
最新回复(0)