C 語言-- 原型設計模式

// main.h
#ifndef _MAIN_H
#define _MAIN_H

typedef struct _AdvTemplate AdvTemplate;
struct _AdvTemplate
{
	char acAdvSubject[50];
	char acAdvContext[50];

	char* (*getAdvSubject)(AdvTemplate *pAdvTemplate);
	char* (*getAdvContext)(AdvTemplate *pAdvTemplate);

	void (*DeleteAdvTemplate)(AdvTemplate *pAdvTemplate);
};


typedef struct _Mail Mail;
struct _Mail
{
	char receiver[20];
	char subject[50];
	char appellation[20];
	char context[50];
	char tail[20];

	AdvTemplate *pAdvTemplate;

	Mail*(*CloneMail)(Mail *pMail);


	char* (*getReceiver)(Mail *pMail);
	void (*setReceiver)(char *pString,Mail *pMail);
	void (*setAppellation)(char *pString,Mail *pMail);
	void (*setTail)(char *pString,Mail *pMail);

	void (*DeleteMail)(Mail *pMail);

};


#endif


// main.h

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "main.h"


char* getAdvSubject(AdvTemplate *pAdvTemplate)
{
	return pAdvTemplate->acAdvSubject;
}

char* getAdvContext(AdvTemplate *pAdvTemplate)
{
	return pAdvTemplate->acAdvContext;
}


void DeleteAdvTemplate(AdvTemplate *pAdvTemplate)
{
	if(pAdvTemplate != NULL)
	{
		free(pAdvTemplate);
		pAdvTemplate=NULL;
	}
}

AdvTemplate *CreateAdvTemplate(void)
{
	AdvTemplate *pAdvTemplate = (AdvTemplate*)malloc(sizeof(AdvTemplate));

	if(!pAdvTemplate)
	{
		return NULL;
	}

	memset(pAdvTemplate,0,sizeof(AdvTemplate));
	strcpy(pAdvTemplate->acAdvSubject,"This is subject");
	strcpy(pAdvTemplate->acAdvContext,"This is context");


	pAdvTemplate->getAdvSubject=getAdvSubject;
	pAdvTemplate->getAdvContext=getAdvContext;
	pAdvTemplate->DeleteAdvTemplate=DeleteAdvTemplate;

	return pAdvTemplate;
}


char* getReceiver(Mail *pMail)
{
	return pMail->receiver;
}

void setReceiver(char* pString,Mail *pMail)
{
	if(pString)
	{
		strcpy(pMail->receiver,pString);
	}
}

void setAppelltion(char* pString,Mail *pMail)
{
	if(pString)
	{
		strcpy(pMail->appellation,pString);
	}
}

void setTail(char *pString,Mail *pMail)
{
	if(pString)
	{
		strcpy(pMail->tail,pString);
	}
}

// 指向和預留空間的區別是什麼.
Mail *CloneMail(Mail *pMail)
{
	Mail *pCloneMail = (Mail*)malloc(sizeof(Mail));
	if(pCloneMail)
	{
		memcpy(pCloneMail,pMail,sizeof(Mail));
	}
	return pCloneMail;
}


/**
	注意釋放的過程, 先釋放父類上的內容,
	在釋放當前.
	須要與free操做作對比測試.
**/
void DeleteMail(Mail *pMail)
{
    
    if(pMail->pAdvTemplate)
    {
        pMail->pAdvTemplate->DeleteAdvTemplate(pMail->pAdvTemplate);
    }
    if(pMail)
    {
        free(pMail);
        pMail = NULL;
    }
}



Mail *CreateMail(void)
{
    Mail *pMail = (Mail *)malloc(sizeof(Mail));
    if(!pMail)
    {
        return NULL;
    }
    memset(pMail, 0, sizeof(Mail));
    pMail->pAdvTemplate = CreateAdvTemplate();
    if(!pMail->pAdvTemplate)
    {
        return NULL;
    }
    pMail->setAppellation = setAppelltion;
    pMail->setReceiver = setReceiver;
    pMail->setTail = setTail;
    pMail->getReceiver = getReceiver;
    pMail->DeleteMail = DeleteMail;
    pMail->CloneMail = CloneMail;
    strcpy(pMail->context,pMail->pAdvTemplate->acAdvContext);
    strcpy(pMail->subject,pMail->pAdvTemplate->acAdvSubject);
    return pMail;
}

char *GetAppell()
{
    return "abc";
}


char *GetReceiver()
{
    return "abc";
}


void sendMail(Mail *pMail,int i)
{
	printf("=======================================\r\n");
	printf("receiver:%d---%s\r\n",i,pMail->getReceiver(pMail));
	printf("subject:%s\r\n",pMail->subject);
	printf("appellation:%s\r\n",pMail->appellation);
	printf("context:%s\r\n",pMail->context);
	printf("=======================================\r\n");
}

int main()
{
	int max_count = 6; /*發送信件的數量*/
	int i=1;
    Mail *pMail = NULL;
    Mail *pCloneMail = NULL;

	pMail = CreateMail();
    pMail->setTail("xxx copyright.", pMail);

	while(max_count)
    {
        max_count--;
        
        /*克隆出一封Mail*/
        pCloneMail = pMail->CloneMail(pMail); 


        /*設置每封Mail的不一樣部分*/
        pCloneMail->setAppellation(GetAppell(), pCloneMail);
        pCloneMail->setReceiver(GetReceiver(), pCloneMail);


        /*發送郵件*/
		sendMail(pCloneMail,i);

		//pCloneMail->DeleteMail(pCloneMail);
		// 此處不要調用DeleteMail()操做, 主要的緣由是由於父類中的內會被修改.致使克隆的數據不可用.
		// free只釋放克隆時申請的空間, 不修改父類中的的信息. 是的程序服務調用父類中 的釋放操做.
        free(pCloneMail);
		i++;
    }


    pMail->DeleteMail(pMail);
	return 0;
}
相關文章
相關標籤/搜索