欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

初论c程序的分层架构案例

程序员文章站 2024-02-23 21:36:04
...

懒得码字,直接借用朱有鹏老师课件内容
主题:结构体内嵌函数指针实现分层
(1)程序为什么要分层?因为复杂程序东西太多一个人搞不定,需要更多人协同工作,于是乎就要分工。
要分工先分层,分层之后各个层次由不同的人完成,然后再彼此调用组合共同工作。
(2)本程序要完成一个计算器,我们设计了2个层次:
上层是framework.c,实现应用程序框架;下层是cal.c,实现计算器。
实际工作时cal.c是直接完成工作的,但是cal.c中的关键部分是调用的framework.c中的函数来完成的。
(3)先写framework.c,由一个人来完成。这个人在framework.c中需要完成计算器的业务逻辑,
并且把相应的接口写在对应的头文件中发出来,将来别的层次的人用这个头文件来协同工作。
(4)另一个人来完成cal.c,实现具体的计算器;
这个人需要framework层的工作人员提供头文件来工作(但是不需要framework.c)
(5)总结:
第一:本节和上节实际完成的是同一个习题,但是采用了不同的程序架构。
第二:对于简单问题来说,上节的不分层反而容易理解,反而简单;本节的分层代码不好理解,
看起来有点把简单问题复杂化的意思。原因在于我们这个问题本身确实是简单问题,而简单问题就应该用简单方法处理。
我们为什么明知错误还要这样做?目的是向大家演示这种分层的写代码的思路和方法。
第三:分层写代码的思路是:有多个层次结合来完成任务,每个层次专注各自不同的领域和任务;
不同层次之间用头文件来交互。
第四:分层之后上层为下层提供服务,上层写的代码是为了在下层中被调用。
第五:上层注重业务逻辑,与我们最终的目标相直接关联,而没有具体干活的函数。
第六:下层注重实际干活的函数,注重为上层填充变量,并且将变量传递给上层中的函数
(其实就是调用上层提供的接口函数)来完成任务。
第七:上层代码中其实核心是一个结构体变量(譬如本例中的struct cal_t),
写下层代码的逻辑其实很简单:第一步先定义结构体变量;
第二步填充结构体变量;
第三步调用上层写好的接口函数,把结构体变量传给它既可。
linux驱动内核架构就是这样的,uboot是上层提供结构 而我们是下层。驱动的关键在于结构体变量怎么定义,调用什么接口
函数,其余的就是填充了。

个人理解
上层:完成现实框架 ——》 抽出接口成头文件 自己加入头文件
下层:填充变量 ——》 调用实现框架
两层交互的关键就是(头文件)

注意几点 :
自定义头文件打双引号
自定义头文件时按模板 防止重复使用
初论c程序的分层架构案例
因为方便调试自己就直接在linux里面建立makefile文件方便调试
初论c程序的分层架构案例

#ifndef _CAL_H_
#define _CAL_H_


typedef int (*pcal)(int, int);

struct cal_t
{
    int a;
    int b;
    pcal p;
};

int calculator(const struct cal_t * p);





#endif
#include "cal_t.h"


int calculator(const struct cal_t * p)
{

    return p->p(p->a, p->b);

}

/*
//提出接口建立头文件
typedef int (*pcal)(int, int);

int calculator(int a, int b, pcal p)
{
    return p(a, b);
}
*/



#include "cal_t.h"
#include <stdio.h>

int add(int a, int b)
{
    return a+b;
}
int sub(int a, int b)
{
    return a-b;
}
int multiple(int a, int b)
{
    return a*b;
}
int divide(int a, int b)
{
    return a/b;
}
int main(void)
{
    int ret = 0;
    struct cal_t mycal;
    mycal.a = 24;
    mycal.b = 4;
    mycal.p = add;
    ret = calculator(&mycal);
    printf("ret = %d\n", ret);

}