首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > C++ >

小弟正在做多媒体相关的应用,现阶段正在写接口,不知设计是否完善,希望得到大家的指点

2013-12-05 
小弟正在做多媒体相关的应用,目前正在写接口,不知设计是否完善,希望得到大家的指点小弟的开发平台是win64

小弟正在做多媒体相关的应用,目前正在写接口,不知设计是否完善,希望得到大家的指点
小弟的开发平台是win64 VS2010
直接上代码:


MediaService.h
#pragma once

#include <string>
#include <list>

#include "talk/base/scoped_ptr.h"
#include "talk/xmpp/xmppthread.h"
#include "talk/xmpp/xmppclient.h"

// 名字空间multimedia,包含CMediaService、CMedium等所有媒体相关组件
namespace multimedia
{

// XMPP状态枚举:重定向枚举值,解耦用户和第三方库之间的联系,降低用户使用接口的复杂度
enum EXmppState
{
E_XMPP_STATE_NONE    = buzz::XmppEngine::STATE_NONE,  
E_XMPP_STATE_START   = buzz::XmppEngine::STATE_START,
E_XMPP_STATE_OPENING = buzz::XmppEngine::STATE_OPENING,
E_XMPP_STATE_OPEN    = buzz::XmppEngine::STATE_OPEN,   
E_XMPP_STATE_CLOSED  = buzz::XmppEngine::STATE_CLOSED
};

// 观察者模式:用户通过实现该接口,并将实现后的实例加入观察者队列,可监听随机事件XmppStateChange
class IXmppStateObserver
{
public:
virtual void XmppStateChange(const EXmppState& newXmppState) = 0;
};

class CMedium;

enum EMediumType
{
E_MEDIUM_PRESENCE,          // 出席状态
E_MEDIUM_CHAT,              // 文字、表情、图片等聊天
E_MEDIUM_PEERCONNECTION,    // 声音、视频实时通讯
E_MEDIUM_CONFERENCE,        // 会议
E_MEDIUM_RECORD,            // 录像
E_MEDIUM_PLAYBACK           // 媒体回放
};

class CMediaService : public sigslot::has_slots<>
{
public:
// 单例模式
static CMediaService& GetInstance(void)
{
/* 这种单例模式实例化方式是所有单例模式设计中比较优秀的一种,较好地解决了如下问题:
   1.多线程访问:采用局部静态变量的方式将多线程访问保护丢给操作系统,因为对于静态变量,
   操作系统会保证其仅被初始化一次,所以用户不必刻意加锁以保证实例的唯一性;
   2.实例销毁时机:如果采用在堆上实例化单例模式,则需考虑的一个问题是何时销毁该实例(这种情况在动态库中较难处理),
   如果销毁时机不当,会导致之后的调用出错,增加了用户维护该实例的难度;
   3.IO资源释放:单例模式中很可能在构造函数中初始化了一些IO资源,而这些资源要等到析构函数调用时才释放,那么,
   如何保证析构函数一定被调用且时机得当?由于静态局部变量存储于静态存储器中,当程序退出时系统会自动释放静态存储区中的对象,
   所以,局部静态实例的析构函数被系统自动调用,即保证了析构函数被调用,又保证了一定在程序退出时在调用,一举两得;
   4.饿汉懒汉:饿汉方式可以保证实例一定存在,但如果用户没有用到该实例,则会造成内存的浪费,
   而局部静态变量则由系统保证其在第一次被使用时初始化,且被初始化一次,是一种巧妙的饿汉模式;
   (备注:delete操作符的作用:1.调用被操作对象的析构函数,2.将对象占用的内存返还给堆)
*/
static CMediaService sMediaService;
return sMediaService;
}

// m_pXmppClient不允许在外部修改,所以返回const指针的引用,以防止意外复制和修改
buzz::XmppClient * const & GetXmppClient()
{
// 通过m_pXmppClient->jid()可以得到自己的login ID,该ID格式为“用户名@域/资源”,具体参考class Jid定义
return m_pXmppClient;
}

void DoLogin(std::string& usrName, 
         const std::string& passWd,
         const std::string& serverIPAddr, 
         const std::string& resourceName = "");
void DoLogout();

/* 1.该接口实现的是所有媒体组件的简单工厂模式,即所有媒体组件都从CMedium基类派生,创建时只需指定一个组件枚举ID,
   由该接口在堆上创建组件并返回一个CMedium基类指针,而用户需要使用dynamin_cast操作符将基类指针转为具体的媒体组件,
   从而调用各组件上的特有方法;
   2.所有媒体组件的构造函数和析构函数都定义为私有函数,从而不允许用户直接创建媒体组件,
   而CreateMedium函数为各媒体组件的友元函数,从而可以创建该类的实例,达到集中创建的目的。
*/
CMedium* CreateMedium(const EMediumType& eMediumType);
/* 1.DestroyMedium函数为所有媒体组件的友元函数,从而可以销毁该类的实例,达到集中销毁的目的;
   2.传入参数为指针的引用,删除实例后将指针置为NULL并通过引用传出,在一定程度上可防止外部对无效实例的使用。
*/
void DestroyMedium(CMedium* & pMedium);

private:
CMediaService(void);
~CMediaService(void);

void OnXmppStateChange(const buzz::XmppEngine::State state);
void NotifyXmppStateObserver(const EXmppState& newXmppState);

private:
static const int                             DEFAULT_XMPPSERVER_PORT = 5222;

/* talk_base::scoped_ptr<T>属于智能指针,不用显式调用delete删除,系统会自动回收,
   所以,该类型的成员变量随着宿主类对象的消亡而消亡
*/
talk_base::scoped_ptr<talk_base::Thread>     m_pXmppThread;
talk_base::scoped_ptr<buzz::XmppPump>        m_pXmppPump;
buzz::XmppClient*                            m_pXmppClient;
buzz::XmppClientSettings                     m_xmppClientSetting;
/* list当中存放元素的拷贝,所以当以指针为参数时,一定要注意指针的有效性,
   即当指针所指对象被在某处释放时,要同步更新list中的数据,否则可能引起野指针调用。
   C++允许引用多态,但list不允许引用参数,所以此处使用指针,const的作用是防止对象被意外修改
*/
typedef std::list<IXmppStateObserver* const> XmppStateObserverList_t;
XmppStateObserverList_t                      m_lstXmppStateObserver;


};

}


MediaService.cpp
void CMediaService::NotifyXmppStateObserver(const EXmppState& newXmppState)
{
XmppStateObserverList_t::iterator iter = m_lstXmppStateObserver.begin();
while(iter != m_lstXmppStateObserver.end())
{
if ((*iter) != NULL)
{
(*iter)->XmppStateChange(newXmppState);
}
++iter;
}
}

CMedium* CMediaService::CreateMedium(const EMediumType& eMediumType)
{
if (m_pXmppClient->GetState() != E_XMPP_STATE_OPEN)
{
return NULL;
}

CMedium* pMedium = NULL;

switch(eMediumType)
{
case E_MEDIUM_PRESENCE:          // 出席状态
{
pMedium = new CPresence();
}
break;

case E_MEDIUM_CHAT:              // 文字、表情、图片等聊天
{

}
break;

case E_MEDIUM_PEERCONNECTION:    // 声音、视频实时通讯
{

}
break;

case E_MEDIUM_CONFERENCE:        // 会议
{

}
break;

case E_MEDIUM_RECORD:            // 录像
{

}
break;

case E_MEDIUM_PLAYBACK:          // 媒体回放
{

}
break;

default:
break;
}

return pMedium;
}

void CMediaService::DestroyMedium(CMedium* & pMedium)
{
// delete空指针不会引起错误,但delete野指针会引发不可预知的行为
delete pMedium;
pMedium = NULL;
}

Presence.h
#pragma once

#include "medium.h"
#include "MediaService.h"
#include "talk/xmpp/presencestatus.h"
#include "talk/xmpp/presenceouttask.h"
#include "talk/xmpp/presencereceivetask.h"

// 名字空间前向声明
namespace buzz 
{
class PresenceReceiveTask;
class PresenceOutTask;
class PresenceStatus;
}  // namespace buzz
  
// 名字空间multimedia,包含CMediaService、CMedium等所有媒体相关组件
namespace multimedia 
{

// 出席状态枚举:重定向枚举值,解耦用户和第三方库之间的联系,降低用户使用接口的复杂度
enum EPresStatus
{
E_PRES_SHOW_NONE    = buzz::PresenceStatus::SHOW_NONE,
E_PRES_SHOW_OFFLINE = buzz::PresenceStatus::SHOW_OFFLINE,
E_PRES_SHOW_XA      = buzz::PresenceStatus::SHOW_XA,
E_PRES_SHOW_AWAY    = buzz::PresenceStatus::SHOW_AWAY,
E_PRES_SHOW_DND     = buzz::PresenceStatus::SHOW_DND,
E_PRES_SHOW_ONLINE  = buzz::PresenceStatus::SHOW_ONLINE,
E_PRES_SHOW_CHAT    = buzz::PresenceStatus::SHOW_CHAT
};

// 类型重定义:减少用户对第三方数据类型的引入,降低用户使用接口的复杂度
typedef buzz::PresenceStatus CPresStatus;

// 观察者模式:用户通过实现该接口,并将实现后的实例加入观察者队列,可监听随机事件PresUpdate
class IPresenceStatusObserver
{
public:
virtual void PresUpdate(const CPresStatus& newPresStatus) = 0;
};

class CPresence : public CMedium
{
public:
void InitPres();
void UninitPres();
bool const & IsPresInit() { return m_bIsPresInit; }
void SetPresStatus(const bool& available, const EPresStatus& show);
void AddPresStatusObserver(IPresenceStatusObserver* const & pObserver)
{
m_lstPresStatusObserver.push_back(pObserver);
}
void RemovePresStatusObserver(IPresenceStatusObserver* const & pObserver)
{
m_lstPresStatusObserver.remove(pObserver);
}

private:
/* 1.私有构造函数和析构函数,不允许外部创建、销毁和继承该类(实例);
   2.通过友元函数的方式创建和销毁类实例,在一定程度上破坏了类的封装性,
   但另一方面达到了集中创建和销毁类实例的目的。
*/
friend CMedium* CMediaService::CreateMedium(const EMediumType& eMediumType);
friend void CMediaService::DestroyMedium(CMedium* & pMedium);
CPresence(void);
~CPresence(void);

void OnPresUpdate(const buzz::PresenceStatus& status);
void NotifyPresStatusObserver(const CPresStatus& newPresStatus);

private:
bool                                              m_bIsPresInit;
buzz::PresenceStatus                              m_presStatus;
/* 1.Task不必显式调用Stop或Abort方法终止,由析构函数自动调用,但是在没有执行任何任务的情况下析构会引发一个断言;
   2.talk_base::scoped_ptr<T>属于智能指针,不用显式调用delete删除,系统会自动回收,所以,
   该类型的成员变量随着宿主类对象的消亡而消亡
*/
talk_base::scoped_ptr<buzz::PresenceOutTask>      m_pPresOutTask;
talk_base::scoped_ptr<buzz::PresenceReceiveTask>  m_pPresRecvTask;
/* list当中存放元素的拷贝,所以当以指针为参数时,一定要注意指针的有效性,
   即当指针所指对象被在某处释放时,要同步更新list中的数据,否则可能引起野指针调用。


   C++允许引用多态,但list不允许引用参数,所以此处使用指针,const的作用是防止对象被意外修改
*/
typedef std::list<IPresenceStatusObserver* const> PresStatusObserverList_t;
PresStatusObserverList_t                          m_lstPresStatusObserver;

};

}

小弟分少,总共只有50分,全上了,请各路大侠指点,不胜感激! 单例模式观察者模式?工厂模式?友元函数? 单例模式 工厂模式 观察者模式 接口设计
[解决办法]
代码量太多实在无心去看...


//个人习惯,我一般用#ifndef方式 取代#pragma once
#ifndef XXXX
#define XXXX
  
#endif


[解决办法]
贴代码的时候最好用代码格式,不然实在看不清楚。最好是一个头文件一段:

//A.h
……

//B.h
……

代码太多了,不想去看...
[解决办法]
编码器接口
解码器接口
滤波器接口
用户控制接口
传输接口
媒体流接口
[解决办法]
接口没有细看,但感觉不应该是这样子的,
[解决办法]
看接口,把头文件,协议按格式贴出来 就一目了然了!
不需要实现文件的!
头文件加一些必要的注释就好!

热点排行