商業引擎的介面設計

2021-04-06 20:07:57 字數 3585 閱讀 8620

對於商業庫來說最重要的就是**的安全和介面的清晰了,換句話說,乙個好的商業庫

要提供給客戶乙個清晰的介面,讓使用者一目了然的同時,讓使用者無法看到具體的實現.

為了達到以上的設計目的,我推薦dll + 抽象類 為設計形式.

在這裡我用乙個商業物理引擎novodex的介面結構作為示例來分析出它一些內部的設

計方法.它的介面形式非常類似於directx,只不過為了保證跨平台性,而沒使用com,但dll +

抽象類的設計本身就合com非常像,也可以說成是一種簡化的com.

我先自己寫乙個基於dll + 抽象類 形式的小庫,了解了這庫,再和novodex提供的介面

(抽象類)作對比,就不難了解novodex的核心結構的設計了.

暴露給使用者的介面所處的檔案:myobject.h , myobject2.h , myobject3.h ,.............

庫設計者對介面的實現:myobjectimp.h , myobject2imp.h , myobject3imp.h , ...........

myobjectimp.cpp,myobject2imp.cpp,myobject3imp.cpp,........

還有兩個特殊的檔案:createmyobject.cpp createmyobject.h

其中:createmyobject.h檔案中宣告有乙個dllexport的全域性函式

:_declspec(dllexport)myobject *createmyobject();用來返回乙個myobject介面指標,但實際上

內部用new操作符建立了乙個myobjectimp的物件,並把該物件的指標返回,這樣我們的一切

就明朗了,在客戶那裡只需要得到介面(比如myobject.h這樣的檔案),並且建立介面物件指標,

而不需要知道這些抽象類的具體實現(在myobjectimp.x 檔案中),然後用createmyobject返回

myobjectimp這個實現類的指標,這樣便能用介面指標操作介面內的一些成員函式了,這些成

員函式在介面中被定義為純虛函式,所以當介面呼叫這些函式時,實際上是呼叫介面實現類

(myobjectimp.x)中的成員函式.

同樣的,可以在myobject.h中宣告乙個myobject2 *createmyobject2()函式來建立另一

個介面,這點類似抽象工廠設計模式(abtract fartory),但這裡的createmyobject2()函式就不用

宣告為dllexport(為什麼自己考慮吧,很簡單的).

就此完成了這個商業庫的結構設計,擴充套件性也非常強,優點非常多.

下面是例項庫的**:

createmyobject.h:

#include "myobject.h"

_declspec(dllexport)myobject *createmyobject();

createmyobject.cpp:

#include "createmyobject.h"

#include "myobjectimp.h"

_declspec(dllexport)myobject *createmyobject()

myobject.h:

#pragma once

//#include "myobject2.h"

class myobject2;

class myobject

;myobject2.h:

#pragma once

class myobject2

;myobject3.h:( 類似不寫出來了)

myobjectimp.h:

#pragma once

#include "myobject.h"

class myobjectimp :

public myobject

;myobjectimp.cpp:

#include "myobjectimp.h"

#include "iostream"

#include "myobject2imp.h"

myobjectimp::myobjectimp(void)

{}myobjectimp::~myobjectimp(void)

{}void myobjectimp::printhello()

myobject2 *myobjectimp::createmyobject2()

myobject2imp.h:

#pragma once

#include "myobject2.h"

class myobject2imp :

public myobject2

;myobject2imp.cpp:

#include "./myobject2imp.h"

#include "iostream"

myobject2imp::myobject2imp(void)

{}myobject2imp::~myobject2imp(void)

void myobject2imp::printhello()

客戶使用測試:

#include "myobject.h"

#include "myobject2.h"

#include "createmyobject.h"

myobject *obj;

myobject2 *obj2;

int _tmain(int argc, _tchar* argv)

現在,來研究novodex的設計結構,基於以上的知識,我們就算沒有novodex的源**,但

依然能搞清novodex到底是怎麼設計介面的.

novodex最高層提供乙個檔案physixloder.h,其中有乙個dll匯出函式:

nxphysxloaderdll_api nxphysicssdk *nxcreatephysicssdk(nxu32 sdkversion,

nxuserallocator* allocator = null, nxuseroutputstream* outputstream = null, const

nxphysicssdkdesc &desc = nxphysicssdkdesc());

用於建立乙個nxphysicssdk 物件指標,哈哈,這裡是不是和我的createmyobject很像?

很好,得到了nxphysicssdk物件後,通過nxphysicssdk介面我們可以看到他有乙個成員函式:

virtual nxscene* createscene(const nxscenedesc& scenedesc) = 0;

用來建立乙個nxscene指標,又和我的myobject中的createmyobject2()很像對吧?

同樣的nxscene又提供了乙個函式:virtual nxactor* createactor(const

nxactordescbase& desc) = 0;

又和我們myobject2中createmyobject3()很像吧,呵呵,自此novodex核心介面設計方式就搞

清楚了,它其它函式大同小異.

這篇文章並沒有研究引擎的具體**,而是展示了乙個通用商業引擎比較好的介面設

計方式,能隱蔽**的同時提供最清晰的介面,希望能對大家有所幫助.

UI介面設計 介面設計流程

人類社會逐步向非物質社會邁進,網際網路資訊產業已經走入我們的生活。在這樣乙個非物質社會中,與軟體這些非物質產品再也不象過去那樣緊緊靠技術就能處於不敗之地。工業設計開始關注非物質產品。但是在國內依然普遍存在這樣乙個稱呼 美工 工 的意思就是沒有思想緊緊靠體力工作的人。這是乙個很愚昧的做法,愚昧在於稱呼...

介面設計文件 介面設計的五點建議!

介面是目前 前後端互動 rest 系統互動 rpc 最普遍的一種方式。乙個好的介面,應該清晰易懂,職責明確,易於維護。反之,則會造成很多困擾。特別是open api,誰做誰知道。基於這樣的前提以及自己之前踩過的坑,就成了這篇文章的由來。文件與程式設計師之間有著一種非常奇妙的關係。一句話概括就是 寫之...

介面設計定理

介面設計定理 模組分解原理探索 模組分解原理與三權分立 介面關係穩定原理探索 前面幾篇文章中講過模組分解原理和介面關係穩定原理,這篇文章中將使用模組分解原理和介面關係穩定原理來推導乙個重要的定理 介面設計定理。在講解介面設計定理前,先看一下robert c.martin著的 敏捷軟體開發 一書中提到...