概述:
模板方法本质是将既定不变的步骤,流程,方法,算法封装起来对外提供统一的接口,以复用这些流程或算法步骤;我们以登录界面为例,假设有两种用户普通用户client和管理员用户master,他们都需要登录login,即包含获取用户信息find_get_user,密码加密encrypt_pwd,匹配获得结果match这几步,只是具体的实现可能不同。我们将登录步骤抽象为统一的模板,封装为login方法,实现过程复用。
1. login_template抽象类定义,实现:
#ifndef _LOGIN_TEMPLATE_H
#define _LOGIN_TEMPLATE_H
#include<stdbool.h>
#include"login_model.h"
struct login_template_vmt
;
struct login_template
{
const struct login_template_vmt
* vptr
;
bool
(*login
)(struct login_template
* pthis
, struct login_model
* plm
);
struct login_model
* (*find_login_user
)(struct login_template
* pthis
, int id
);
char* (*encrypt_pwd
)(struct login_template
* pthis
, char* pwd
);
bool
(*match
)(struct login_template
* pthis
, struct login_model
* plm
, struct login_model
* pdb
);
};
struct login_template_vmt
{
struct login_model
* (*find_login_user_vm
)(struct login_template
* pthis
, int id
);
char* (*encrypt_pwd_vm
)(struct login_template
* pthis
, char* pwd
);
};
extern void login_template_init(struct login_template
* pthis
);
#endif
#include<stdio.h>
#include<stdlib.h>
#include<stdbool.h>
#include<string.h>
#include"login_model.h"
#include"login_template.h"
static bool
login(struct login_template
* pthis
, struct login_model
* plm
)
{
struct login_model
* dblm
= pthis
->find_login_user(pthis
, plm
->get_id(plm
));
if (dblm
!= NULL) {
char* crypwd
= pthis
->encrypt_pwd(pthis
, plm
->get_pwd(plm
));
plm
->set_pwd(plm
, crypwd
);
return pthis
->match(pthis
, plm
, dblm
);
}
}
static struct login_model
* find_login_user(struct login_template
* pthis
, int id
)
{
pthis
->vptr
->find_login_user_vm(pthis
, id
);
}
static char* encrypt_pwd(struct login_template
* pthis
, char* pwd
)
{
if (pthis
->vptr
->encrypt_pwd_vm
!= NULL) {
pthis
->vptr
->encrypt_pwd_vm(pthis
, pwd
);
} else {
printf("default plain text\n");
return pwd
;
}
}
static bool
match(struct login_template
* pthis
, struct login_model
* plm
, struct login_model
* pdb
)
{
if (plm
->get_id(plm
) == pdb
->get_id(pdb
)
&& !strcmp(plm
->get_pwd(plm
), pdb
->get_pwd(pdb
))) {
printf("login successfully!\n");
return true
;
}
return false
;
}
void login_template_init(struct login_template
* pthis
)
{
static const struct login_template_vmt vmt
= {
.find_login_user_vm
= NULL,
.encrypt_pwd_vm
= NULL,
};
pthis
->vptr
= &vmt
;
pthis
->login
= login
;
pthis
->find_login_user
= find_login_user
;
pthis
->encrypt_pwd
= encrypt_pwd
;
pthis
->match
= match
;
}
2. client_login子类定义,实现:
#ifndef _CLIENT_LOGIN_H
#define _CLIENT_LOGIN_H
#include<stdbool.h>
#include"login_model.h"
#include"login_template.h"
struct client_login
{
struct login_template super
;
bool
(*login
)(struct login_template
* pthis
, struct login_model
* plm
);
struct login_model
* (*find_login_user
)(struct login_template
* pthis
, int id
);
char* (*encrypt_pwd
)(struct login_template
* pthis
, char* pwd
);
bool
(*match
)(struct login_template
* pthis
, struct login_model
* plm
, struct login_model
* pdb
);
};
extern struct client_login
* construct_client_login(void);
extern void destruct_client_login(struct client_login
* pthis
);
#endif
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include"login_template.h"
#include"login_model.h"
#include"client_login.h"
static struct login_model
* find_login_user_ov(struct login_template
* pthis
, int id
)
{
struct login_model
* plm
= construct_login_model();
plm
->set_id(plm
, id
);
plm
->set_pwd(plm
, "xxdk");
return plm
;
}
static void client_login_init(struct client_login
* pthis
)
{
static const struct login_template_vmt vmt
= {
.find_login_user_vm
= find_login_user_ov
,
};
login_template_init(&pthis
->super
);
pthis
->super
.vptr
= &vmt
;
pthis
->login
= pthis
->super
.login
;
pthis
->match
= pthis
->super
.match
;
pthis
->encrypt_pwd
= pthis
->super
.encrypt_pwd
;
}
struct client_login
* construct_client_login(void)
{
struct client_login
* pthis
= malloc(sizeof(*pthis
));
memset(pthis
, 0, sizeof(*pthis
));
client_login_init(pthis
);
return pthis
;
}
void destruct_client_login(struct client_login
* pthis
)
{
free(pthis
);
}
3. master_login子类定义,实现:
#ifndef _MASTER_LOGIN_H
#define _MASTER_LOGIN_H
#include<stdbool.h>
#include"login_model.h"
#include"login_template.h"
struct master_login
{
struct login_template super
;
bool
(*login
)(struct login_template
* pthis
, struct login_model
* plm
);
struct login_model
* (*find_login_user
)(struct login_template
* pthis
, int id
);
char* (*encrypt_pwd
)(struct login_template
* pthis
, char* pwd
);
bool
(*match
)(struct login_template
* pthis
, struct login_model
* plm
, struct login_model
* pdb
);
};
extern struct master_login
* construct_master_login(void);
extern void destruct_master_login(struct master_login
* pthis
);
#endif
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include"login_template.h"
#include"login_model.h"
#include"master_login.h"
static struct login_model
* find_login_user_ov(struct login_template
* pthis
, int id
)
{
struct login_model
* plm
= construct_login_model();
plm
->set_id(plm
, id
);
plm
->set_pwd(plm
, "xxdk");
return plm
;
}
static char* encrypt_pwd_ov(struct login_template
* pthis
, char* pwd
)
{
printf("master encrypt pwd\n");
return pwd
;
}
static void master_login_init(struct master_login
* pthis
)
{
static const struct login_template_vmt vmt
= {
.find_login_user_vm
= find_login_user_ov
,
.encrypt_pwd_vm
= encrypt_pwd_ov
,
};
login_template_init(&pthis
->super
);
pthis
->super
.vptr
= &vmt
;
pthis
->login
= pthis
->super
.login
;
pthis
->match
= pthis
->super
.match
;
}
struct master_login
* construct_master_login(void)
{
struct master_login
* pthis
= malloc(sizeof(*pthis
));
memset(pthis
, 0, sizeof(*pthis
));
master_login_init(pthis
);
return pthis
;
}
void destruct_master_login(struct master_login
* pthis
)
{
free(pthis
);
}
4. 辅助的login_model类定义,实现, 用于封装用户信息:
#ifndef _LOGIN_TEMPLATE_H
#define _LOGIN_TEMPLATE_H
#include<stdbool.h>
#include"login_model.h"
struct login_template_vmt
;
struct login_template
{
const struct login_template_vmt
* vptr
;
bool
(*login
)(struct login_template
* pthis
, struct login_model
* plm
);
struct login_model
* (*find_login_user
)(struct login_template
* pthis
, int id
);
char* (*encrypt_pwd
)(struct login_template
* pthis
, char* pwd
);
bool
(*match
)(struct login_template
* pthis
, struct login_model
* plm
, struct login_model
* pdb
);
};
struct login_template_vmt
{
struct login_model
* (*find_login_user_vm
)(struct login_template
* pthis
, int id
);
char* (*encrypt_pwd_vm
)(struct login_template
* pthis
, char* pwd
);
};
extern struct login_template
* construct_login_template(void);
extern void login_template_init(struct login_template
* pthis
);
extern void desturct_login_template(struct login_template
* pthis
);
#endif
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include"login_model.h"
static int get_id(struct login_model
* pthis
)
{
return pthis
->id
;
}
static void set_id(struct login_model
* pthis
, int id
)
{
pthis
->id
= id
;
}
static char* get_pwd(struct login_model
* pthis
)
{
return pthis
->pwd
;
}
static void set_pwd(struct login_model
* pthis
, char* pwd
)
{
strncpy(pthis
->pwd
, pwd
, 16);
}
static void login_model_init(struct login_model
* pthis
)
{
pthis
->get_id
= get_id
;
pthis
->set_id
= set_id
;
pthis
->get_pwd
= get_pwd
;
pthis
->set_pwd
= set_pwd
;
}
struct login_model
* construct_login_model(void)
{
struct login_model
* pthis
= malloc(sizeof(*pthis
));
login_model_init(pthis
);
return pthis
;
}
void destruct_login_model(struct login_model
* pthis
)
{
free(pthis
);
}
5. 测试文件:
#include<stdio.h>
#include<stdbool.h>
#include"login_template.h"
#include"login_model.h"
#include"client_login.h"
#include"master_login.h"
int main()
{
struct login_model
* usr
;
struct login_template
* plt
;
usr
= construct_login_model();
usr
->set_id(usr
, 1);
usr
->set_pwd(usr
, "xxdk");
printf("client user login: \n");
plt
= (struct login_template
*)construct_client_login();
plt
->login(plt
, usr
);
destruct_client_login((struct client_login
*)plt
);
printf("master user login: \n");
plt
= (struct login_template
*)construct_master_login();
plt
->login(plt
, usr
);
destruct_master_login((struct master_login
*)plt
);
destruct_login_model(usr
);
return 0;
}
转载请注明原文地址: https://mac.8miu.com/read-407282.html