Я раньше делал такого рода вещь в C, прежде чем я знал, каково ООП было.
следующее является примером, который реализует буфер данных, который растет по требованию, учитывая минимальный размер, инкрементный и максимальный размер. Эта конкретная реализация была базирующимся "элементом", который должен сказать, что это было разработано для разрешения подобного списку набора любого типа C, не только буфера байта переменной длины.
идея состоит в том, что объект инстанцируют с помощью xxx_crt () и удалил использование xxx_dlt (). Каждый из "членских" методов берет конкретно введенный указатель для работы на.
я реализовал связанный список, циклический буфер и много других вещей этим способом.
я должен признаться, я никогда не уделял внимания о том, как реализовать наследование с этим подходом. Я предполагаю, что некоторое смешение предлагаемого Kieveli могло бы быть хорошим путем.
dtb.c:
#include <limits.h>
#include <string.h>
#include <stdlib.h>
static void dtb_xlt(void *dst, const void *src, vint len, const byte *tbl);
DTABUF *dtb_crt(vint minsiz,vint incsiz,vint maxsiz) {
DTABUF *dbp;
if(!minsiz) { return NULL; }
if(!incsiz) { incsiz=minsiz; }
if(!maxsiz || maxsiz<minsiz) { maxsiz=minsiz; }
if(minsiz+incsiz>maxsiz) { incsiz=maxsiz-minsiz; }
if((dbp=(DTABUF*)malloc(sizeof(*dbp))) == NULL) { return NULL; }
memset(dbp,0,sizeof(*dbp));
dbp->min=minsiz;
dbp->inc=incsiz;
dbp->max=maxsiz;
dbp->siz=minsiz;
dbp->cur=0;
if((dbp->dta=(byte*)malloc((vuns)minsiz)) == NULL) { free(dbp); return NULL; }
return dbp;
}
DTABUF *dtb_dlt(DTABUF *dbp) {
if(dbp) {
free(dbp->dta);
free(dbp);
}
return NULL;
}
vint dtb_adddta(DTABUF *dbp,const byte *xlt256,const void *dtaptr,vint dtalen) {
if(!dbp) { errno=EINVAL; return -1; }
if(dtalen==-1) { dtalen=(vint)strlen((byte*)dtaptr); }
if((dbp->cur + dtalen) > dbp->siz) {
void *newdta;
vint newsiz;
if((dbp->siz+dbp->inc)>=(dbp->cur+dtalen)) { newsiz=dbp->siz+dbp->inc; }
else { newsiz=dbp->cur+dtalen; }
if(newsiz>dbp->max) { errno=ETRUNC; return -1; }
if((newdta=realloc(dbp->dta,(vuns)newsiz))==NULL) { return -1; }
dbp->dta=newdta; dbp->siz=newsiz;
}
if(dtalen) {
if(xlt256) { dtb_xlt(((byte*)dbp->dta+dbp->cur),dtaptr,dtalen,xlt256); }
else { memcpy(((byte*)dbp->dta+dbp->cur),dtaptr,(vuns)dtalen); }
dbp->cur+=dtalen;
}
return 0;
}
static void dtb_xlt(void *dst,const void *src,vint len,const byte *tbl) {
byte *sp,*dp;
for(sp=(byte*)src,dp=(byte*)dst; len; len--,sp++,dp++) { *dp=tbl[*sp]; }
}
vint dtb_addtxt(DTABUF *dbp,const byte *xlt256,const byte *format,...) {
byte textÝ501¨;
va_list ap;
vint len;
va_start(ap,format); len=sprintf_len(format,ap)-1; va_end(ap);
if(len<0 || len>=sizeof(text)) { sprintf_safe(text,sizeof(text),"STRTOOLNG: %s",format); len=(int)strlen(text); }
else { va_start(ap,format); vsprintf(text,format,ap); va_end(ap); }
return dtb_adddta(dbp,xlt256,text,len);
}
vint dtb_rmvdta(DTABUF *dbp,vint len) {
if(!dbp) { errno=EINVAL; return -1; }
if(len > dbp->cur) { len=dbp->cur; }
dbp->cur-=len;
return 0;
}
vint dtb_reset(DTABUF *dbp) {
if(!dbp) { errno=EINVAL; return -1; }
dbp->cur=0;
if(dbp->siz > dbp->min) {
byte *newdta;
if((newdta=(byte*)realloc(dbp->dta,(vuns)dbp->min))==NULL) {
free(dbp->dta); dbp->dta=null; dbp->siz=0;
return -1;
}
dbp->dta=newdta; dbp->siz=dbp->min;
}
return 0;
}
void *dtb_elmptr(DTABUF *dbp,vint elmidx,vint elmlen) {
if(!elmlen || (elmidx*elmlen)>=dbp->cur) { return NULL; }
return ((byte*)dbp->dta+(elmidx*elmlen));
}
dtb.h
typedef _Packed struct {
vint min; /* initial size */
vint inc; /* increment size */
vint max; /* maximum size */
vint siz; /* current size */
vint cur; /* current data length */
void *dta; /* data pointer */
} DTABUF;
#define dtb_dtaptr(mDBP) (mDBP->dta)
#define dtb_dtalen(mDBP) (mDBP->cur)
DTABUF *dtb_crt(vint minsiz,vint incsiz,vint maxsiz);
DTABUF *dtb_dlt(DTABUF *dbp);
vint dtb_adddta(DTABUF *dbp,const byte *xlt256,const void *dtaptr,vint dtalen);
vint dtb_addtxt(DTABUF *dbp,const byte *xlt256,const byte *format,...);
vint dtb_rmvdta(DTABUF *dbp,vint len);
vint dtb_reset(DTABUF *dbp);
void *dtb_elmptr(DTABUF *dbp,vint elmidx,vint elmlen);
пз: vint был просто определением типа интервала - я использовал его, чтобы напомнить мне, что это - длина, было переменным от платформы до платформы (для портирования).
Термин « Уровень » в моем опыт обычно относится к разделению физических приложений, например, уровень клиента и уровень сервера.
MVC - относится к 3 « уровням », при этом проблема заключается в разделении вокруг 3-х проблем, которые он подробно описывает Модель (данные) , Представление (пользовательский интерфейс), контроллер (логика приложения).
Теперь, когда я сделал это различие в отношении моей терминологии ...
Не слишком ли много отдельного приложения для доступа к данным в приложении mvc?
Я бы сказал Нет (опять же, в зависимости от того, что вы подразумеваете под приложением), это не излишество , так как на самом деле это может привести к созданию более удобной в обслуживании системы. Ваш ORM , возможно, позволит подключать новые параметры доступа к данным, но что, если вы хотите добавить новый ORM? Наличие четко разделенного уровня доступа к данным (DAL) обеспечит гораздо большую гибкость в будущем в этом аспекте вашего приложения.
С другой стороны, в зависимости от масштаба и видения приложения создание полностью автономной опции доступа к данным может будет излишним, но в двух словах разделение DAL на разные сборки является очень рекомендуемой практикой в составе приложения, реализующего шаблон MVC.
Надеюсь, это поможет, если вам нужно больше подробностей, сделайте комментарий.
но что, если вы хотите добавить новый ORM? Наличие четко разделенного уровня доступа к данным (DAL) обеспечит гораздо большую гибкость в будущем в этом аспекте вашего приложения.С другой стороны, в зависимости от масштаба и видения приложения создание полностью автономной опции доступа к данным может будет излишним, но в двух словах разделение DAL на разные сборки является очень рекомендуемой практикой в составе приложения, реализующего шаблон MVC.
Надеюсь, это поможет, если вам нужно больше подробностей, сделайте комментарий.
но что, если вы хотите добавить новый ORM? Наличие четко разделенного уровня доступа к данным (DAL) обеспечит гораздо большую гибкость в будущем в этом аспекте вашего приложения.С другой стороны, в зависимости от масштаба и видения приложения создание полностью автономной опции доступа к данным может будет излишним, но в двух словах разделение DAL на разные сборки является очень рекомендуемой практикой в составе приложения, реализующего шаблон MVC.
Надеюсь, это поможет, если вам нужно больше подробностей, сделайте комментарий.
Замечательный комментарий Тобиаса.
Я говорю, что добавьте достаточно слоев, чтобы это имело смысл для вас и облегчало обслуживание. Также, чтобы сохранить разделение проблем.
Ну, я думаю, это немного зависит от того, говорите ли вы о уровнях (физический) или уровнях (логические / проекты).
Что касается многоуровневости - вы можете взглянуть на что-то вроде архитектуры s # arp ( code.google.com/p/sharp-architecture/ ) в качестве примера того, как они это делают (они взяли довольно максимальный подход к наслоению).
Для примера более минималистичных представлений, взгляните на блог Айенде: ayende.com/Blog/
Что касается уровней - я думаю, излишне добавлять дополнительные уровни и переносить что-либо по сети просто снизит вашу производительность, если вам не нужно делать это из соображений емкости. Получите слои правильно, и они разделят их на группы, так как вам нужно настроить емкость (не потребуется слишком много рефакторинга, если вы