Calligra 中的設計模式(一)—— Private class data 模式

KDE 是一個強大的圖形桌面環境,各項關於 KDE 使用上的問題或討論歡迎在此提出。

版主: AceLan, Franklin

Calligra 中的設計模式(一)—— Private class data 模式

文章訪客 » 週一 1月 31, 2011 9:26 pm

加入 Calligra 之前對設計模式這東西一點兒也不瞭解,看過 Calligra 龐大而複雜的代碼後才明白良好的設計模式對大型軟體的工程化開發是多麼的重要。從現在開始我會不定期地介紹一下 Calligra 開發中遇到的一些設計模式,一方面讓自己更好地理解這些設計方法,另一方面也能把 Calligra 的設計思路介紹給大家。

這次介紹的 Private class data 模式可以說的上是 Qt/KDE 裡最常見的設計模式了,Private class data 模式又叫 PIMPL (Private IMPLementation) ,Opaque pointer,handle/body 或 cheshire cat,該模式把類屬性包裝到獨立的資料物件中來最小化資料的可見性,以避免在物件構建後對資料誤操作。該模式在 Qt/KDE 稱為 D-Pointers,不僅起到了包裝類屬性的作用,而且很好地解決了二進位相容性的問題。先看下面一段代碼:

代碼: 選擇全部
view source
print?
class KoShapeShadow::Private
{
public:
 Private()
 : offset(0, 0), color(Qt::black), blur(8), visible(true), refCount(0) {
 }
 QPointF offset;
 QColor color;
 qreal blur;
 bool visible;
 QAtomicInt refCount;
};
 
KoShapeShadow::KoShapeShadow()
 : d(new Private())
{
}
 
KoShapeShadow::~KoShapeShadow()
{
 delete d;
}
 
void KoShapeShadow::fillStyle(KoGenStyle &style, KoShapeSavingContext &context)
{
 Q_UNUSED(context);
 
 style.addProperty("draw:shadow", d->visible ? "visible" : "hidden");
 style.addProperty("draw:shadow-color", d->color.name());
 if (d->color.alphaF() != 1.0)
 style.addProperty("draw:shadow-opacity", QString("%1%").arg(d->color.alphaF() * 100.0));
 style.addProperty("draw:shadow-offset-x", QString("%1pt").arg(d->offset.x()));
 style.addProperty("draw:shadow-offset-y", QString("%1pt").arg(d->offset.y()));
 if (d->blur != 0)
 style.addProperty("koffice:shadow-blur-radius", QString("%1").arg(d->blur));
}


非 常簡單的一種設計模式。建立一個 Private 類用於存儲所有資料,Private 類的構造函數初始化所有 KoShapeShadow 類的資料的值,構造 KoShapeShadow 時新建一個 Private 物件賦給指標 d,這樣需要調用 KoShapeShadow 物件的資料時使用 d->xx 就可以了。

D- Pointers在 Qt 庫,kdelibs 和 Calligra-libs 中應用非常廣泛,但它們最主要的功能並不是最小化資料的可見性,它們是為了保證二進位相容性。什麼是二進位相容性呢?如果一個庫升級了,原來動態連結到該 庫的應用程式不需要重新編譯即可連結到新的二進位版本,這個庫就是二進位相容的。否則如果應用程式需要重編譯(但不需要修改)這個庫就是源碼相容的。二進 制相容性保證了每次系統裡的 Qt 包升級後不用把所有 Qt 程式也更新一遍。如果沒有 D-Pointers,由於所有的成員變數直接寫在類定義裡,新增成員變數後各變數在新的庫檔中的位址就可能發生變化,應用程式和庫檔的位址映射就不對應了,而使用 D-Pointers 之後,應用程式只知道庫檔有一個叫 d 的指標,d 的位址是不變的。

參考閱讀:

http://techbase.kde.org/Policies/Librar ... D-Pointers
http://techbase.kde.org/index.php?title ... th_C%2B%2B

http://philacorns.wordpress.com/2011/01 ... %E5%BC%8F/
訪客
 

回到 KDE 一般討論

誰在線上

正在瀏覽這個版面的使用者:Google [Bot] 和 1 位訪客