1 甲方框架
在企业开发的过程中,往往甲方只需要搭建整体框架,并提供接口声明,具体的功能实现又乙方完成
例如,要开发一款游戏,甲方搭建的框架以及涉及的接口声明如下:
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
//初始化游戏 //参数1:玩家指针 参数2:人物姓名
typedef void(*INIT_GAME)(void** player, char* name);
//核心战斗 若战斗胜利返回1,失败返回0 //参数1:玩家 参数2:副本难度
typedef int(*FIGHT_GAME)(void* player, int gameDiff);
//查看玩家信息
typedef void(*PRINT_GAME)(void* player);
//退出游戏
typedef void(*EXIT_GAME)(void* player);
//甲方框架
void playGame(INIT_GAME init, FIGHT_GAME fight, PRINT_GAME printGame, EXIT_GAME exitGame)
{
void* player = NULL;
char buf[1024];
printf("请输入玩家的姓名:");
scanf("%s", buf);
//初始化游戏
init(&player, buf);
//游戏难度设定
int diff = -1;
printf("请选择游戏难度:\n");
printf("1、简单\n");
printf("2、中等\n");
printf("3、困难\n");
scanf("%d", &diff);
//战斗
int ret = fight(player, diff);
if (ret == 0)
{
printf("游戏结束,请再接再厉!\n");
}
else
{
printf("恭喜胜利!\n");
//查看当前玩家状态
printf("当前玩家状态为:\n");
printGame(player);
}
//退出游戏
exitGame(player);
}
int main() {
return EXIT_SUCCESS;
}
上面的框架是一个回调函数,函数指针的在定义的时候,相当于给出了接口,因为能看到函数的返回值和参数。可以在VS中生成一下(即编译链接),如果没有语法错误,说明甲方的框架搭建完成,接下来是让乙方实现功能。
甲方需要哪些功能模块,往往不是自己单独确定,而是需要和乙方商量确定,换句话说,具体需求的确定,是双方沟通交流的结果。
2 乙方功能实现
乙方根据上面的框架,实现各个函数的具体功能。
新建一个名为gameCompany1.h的文件,这里Company1表示第一家乙方公司,因为乙方可能有多家游戏厂商,下面的函数中,若名字里有COMPANY1,也表示来自第一家乙方公司的函数,gameCompany1.h的内容如下:
#pragma once
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
struct Player
{
char name[64];
int exp; //经验
int level; //等级
};
//初始化游戏 //参数1:玩家指针 参数2:人物姓名
void INIT_GAME_COMPANY1(void** player, char* name);
//核心战斗 若战斗胜利返回1,失败返回0 //参数1:玩家 参数2:副本难度
int FIGHT_GAME_COMPANY1(void* player, int gameDiff);
//查看玩家信息
void PRINT_GAME_COMPANY1(void* player);
//退出游戏
void EXIT_GAME_COMPANY1(void* player);
接下来新建一个名为gameCompany1.c的文件,实现上述接口,内容如下:
#include "gameCompany1.h"
//初始化游戏 //参数1:玩家指针 参数2:人物姓名
void INIT_GAME_COMPANY1(void** player, char* name)
{
//分配内存
struct Player* pl = malloc(sizeof(struct Player));
if (pl == NULL)
{
return;
}
*player = pl;
strcpy(pl->name, name); //姓名赋值
pl->exp = 0; //开局经验为0
pl->level = 0; //开局等级为0
}
//获得的经验奖励 //参数1:胜率 参数2:难度
int getExp(int winRate, int diff)
{
int random = rand() % 100 + 1;
if (random <= winRate)
{
//胜利
return diff * 10;
}
else
{
//失败
return 0;
}
}
//核心战斗 若战斗胜利返回1,失败返回0 //参数1:玩家 参数2:副本难度
int FIGHT_GAME_COMPANY1(void* player, int gameDiff)
{
//转换数据类型
struct Player* pl = player; //之后只需要对pl进行操作
int addExp = 0; //给玩家增加的经验变量
//根据难度确定经验变量的取值
switch (gameDiff)
{
//不同难度有不同的胜率,获胜的情况下,相应的经验奖励也不同
case 1:
addExp = getExp(90, 1);
break;
case 2:
addExp = getExp(50, 2);
break;
case 3:
addExp = getExp(30, 3);
break;
default:
break;
}
//更新玩家的经验和等级
pl->exp += addExp;
pl->level = pl->exp / 10; //经验除以10得到等级
//根据获得的经验来判断是否胜利
if (0 == addExp)
{
//游戏失败
return 0;
}
else
{
//游戏胜利
return 1;
}
}
//查看玩家信息
void PRINT_GAME_COMPANY1(void* player)
{
//转换数据类型
struct Player* pl = player; //之后只需要对pl进行操作
//打印
printf("玩家的姓名:%s\n", pl->name);
printf("当前的经验:%d\n", pl->exp);
printf("当前的等级:%d\n", pl->level);
}
//退出游戏
void EXIT_GAME_COMPANY1(void* player)
{
if (player == NULL)
{
return;
}
free(player);
player = NULL;
}
3 测试
乙方实现功能之后,需要使用甲方给的框架来测试,内容如下:
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<time.h>
#include "gameCompany1.h" //导入乙方的函数声明
//初始化游戏 //参数1:玩家指针 参数2:人物姓名
typedef void(*INIT_GAME)(void** player, char* name);
//核心战斗 若战斗胜利返回1,失败返回0 //参数1:玩家 参数2:副本难度
typedef int(*FIGHT_GAME)(void* player, int gameDiff);
//查看玩家信息
typedef void(*PRINT_GAME)(void* player);
//退出游戏
typedef void(*EXIT_GAME)(void* player);
//甲方框架
void playGame(INIT_GAME init, FIGHT_GAME fight, PRINT_GAME printGame, EXIT_GAME exitGame)
{
void* player = NULL;
char buf[1024];
printf("请输入玩家的姓名:");
scanf("%s", buf);
//初始化游戏
init(&player, buf);
//游戏难度设定
int diff = -1;
printf("请选择游戏难度:\n");
printf("1、简单\n");
printf("2、中等\n");
printf("3、困难\n");
scanf("%d", &diff);
//战斗
int ret = fight(player, diff);
if (ret == 0)
{
printf("游戏结束,请再接再厉!\n");
}
else
{
printf("恭喜胜利!\n");
//查看当前玩家状态
printf("当前玩家状态为:\n");
printGame(player);
}
//退出游戏
exitGame(player);
}
int main() {
srand((unsigned int)time(NULL)); //设置随机数种子
//将乙方写的函数名,作为参数传入
playGame(INIT_GAME_COMPANY1, FIGHT_GAME_COMPANY1, PRINT_GAME_COMPANY1, EXIT_GAME_COMPANY1);
return EXIT_SUCCESS;
}
结果:
至此,测试成功!
4 甲乙对接
乙方测试成功后,可以将函数封装成动态库提交给甲方,甲乙双方对接确认结果后,甲方支付尾款。如果有第二家乙方公司实现了上述的所有功能,可以将所有函数声明写在gameCompany2.h中,然后按照同样的流程。
尽管游戏的功能比较简单,我们还是已经掌握了面向接口编程。
文章评论