良好的設(shè)計應(yīng)該只暴露接口給用戶,所有的實現(xiàn)細(xì)節(jié)對用戶來說應(yīng)該是隱藏的,也就是說用戶只要給接口傳遞相應(yīng)的參數(shù)就行了,不需要管內(nèi)部是如何實現(xiàn)的,比如我們使用fopen,fseek,CreateWindow等函數(shù)會發(fā)現(xiàn)很好用,而不需要管fopen,fseek,CreateWindow函數(shù)內(nèi)部代碼是如何實現(xiàn)的,數(shù)據(jù)結(jié)構(gòu)是如何組織的,也就是說絕對不能暴露任何的細(xì)節(jié)給用戶,包括數(shù)據(jù)組織在內(nèi)。
我現(xiàn)在用C和C++舉一個例子,來說說C/C++分別是如何實現(xiàn)的,然后來看看哪種實現(xiàn)更好。
先來看C++用類實現(xiàn)的封裝:
--------------------------- interface1.h ---------------------------
#ifndef INTERFACE1_H
#define INTERFACE1_H
class DATA
{
private:
int _i;
short _j;
public:
DATA();
~DATA();
void set(int i, short j);
void get(int* i, short* j);
};
#endif
--------------------------- interface1.cpp ---------------------------
#include "interface1.h"
DATA::DATA()
{
_i = _j = 0;
}
DATA::~DATA()
{
_i = _j = 0;
}
void DATA::set(int i, short j)
{
_i = i;
_j = j;
}
void DATA::get(int* i, short* j)
{
*i = _i;
*j = _j;
}
--------------------------- test.cpp ---------------------------
#include <stdio.h>
#include "interface1.h"
int main()
{
DATA data;
int i;
short j;
data.set(2, 3);
data.get(&i, &j);
printf("i = %d, j = %d\n", i, j);
return 0;
}
再來看 C 如何巧妙的封裝以及隱藏實現(xiàn)細(xì)節(jié):
--------------------------- interface.h ---------------------------
#ifndef INTERFACE_H
#define INTERFACE_H
void* data_create();
void data_set(void* dummy, int i, short j);
void data_get(void* dummy, int* i, short * j);
void data_destroy(void* dummy);
#endif
--------------------------- interface.c ---------------------------
#include <stdlib.h>
struct DATA
{
int i;
short j;
};
void* data_create()
{
return malloc(sizeof(struct DATA));
}
void data_set(void* dummy, int i, short j)
{
struct DATA* data = dummy;
data->i = i;
data->j = j;
}
void data_get(void* dummy, int* i, short * j)
{
struct DATA* data = dummy;
*i = data->i;
*j = data->j;
}
void data_destroy(void* dummy)
{
free(dummy);
}
--------------------------- test.c ---------------------------
#include <stdio.h>
#include "interface.h"
int main()
{
int i;
short j;
void* data = data_create();
data_set(data, 2, 3);
data_get(data, &i, &j);
printf("i = %d, j = %d\n", i, j);
data_destroy(data);
return 0;
}
可以看的出來,C的實現(xiàn)只暴露了接口給用戶,內(nèi)部的實現(xiàn)細(xì)節(jié)都隱藏了起來,可是C++用類實現(xiàn)反而在頭文件暴露了實現(xiàn)細(xì)節(jié)。
當(dāng)然用C++也可以做到只暴露接口給用戶,不過實現(xiàn)起來會比較復(fù)雜,而且需要消耗更多的內(nèi)存(使用了虛函數(shù))。
-------------------------------------- parent.h --------------------------------------
#ifndef PARENT_H
#define PARENT_H
class PARENT
{
public:
virtual void set(int i, short j) = 0;
virtual void get(int* i, short* j) = 0;
};
PARENT* get_child();
#endif
-------------------------------------- parent.cpp --------------------------------------
#include "parent.h"
#include "child.h"
PARENT* get_child()
{
return new CHILD;
}
-------------------------------------- child.h --------------------------------------
#ifndef CHILD_H
#define CHILD_H
#include "parent.h"
class CHILD : public PARENT
{
private:
int _i;
short _j;
public:
CHILD();
~CHILD();
void set(int i, short j);
void get(int* i, short* j);
};
#endif
-------------------------------------- child.cpp --------------------------------------
#include "child.h"
CHILD::CHILD()
{
_i = _j = 0;
}
CHILD::~CHILD()
{
_i = _j = 0;
}
void CHILD::set(int i, short j)
{
_i = i;
_j = j;
}
void CHILD::get(int* i, short* j)
{
*i = _i;
*j = _j;
}
-------------------------------------- test.cpp --------------------------------------
#include <stdio.h>
#include "parent.h"
int main()
{
int i;
short j;
PARENT* parent = get_child();
parent->set(2, 3);
parent->get(&i, &j);
printf("i = %d, j = %d\n", i, j);
return 0;
}