• 沒有找到結果。

資料簡述及資料選取

第四章 雛形系統建置

第一節 資料簡述及資料選取

本研究的資料是將 73 個專案原始碼加以分析,雖然這 73 個專案都是 Microsoft Visual C++的程式,但是這 73 個專案的屬性、功能性質都不太 相同,有些專案是應用程式、有些專案是 ActiveX 元件、COM 元件,有些則 是程式庫。這 73 個專案所有的資料包括了 1465 個 CPP 檔、1644 個 H 檔,

760 個類別,7748 個方法。原始資料格式如下:原始的 H 檔格式如圖 4.1.1、

原始的 CPP 檔格式為圖 4.1.2。

我們依這 73 個專案的屬性不同,將這些專案的個數統計如表 4.1.1,

並將這些屬性的意義說明如下:應用程式是 Microsoft Windows 程式,附檔 名為 EXE,主要提供給使用者操作使用,使用者操作的結果可能是呈現在畫 面上或是輸出到檔案、印表機等裝置。程式庫是 Microsoft 平台下的 DLL 檔 案,提供其他應用程式呼叫、使用,程式設計師可以將常用的功能寫在程式 庫中,已提供給每個應用程式共同使用,特別注意 DLL 版本問題即可。

ActiveX 元件是將常用的使用者介面放在 DLL 中,ActiveX 元件的程式可以 包含使用者的操作使用介面或顯示使用介面。COM 元件是 Microsoft 為了達 成程式分散成多層式架構的一種程式寫法,COM 元件附檔名也是 DLL。雖然 ActiveX 元件與 COM 元件附檔名都是 DLL 但是跟一般的程式庫 DLL 程式寫法 不同,且必須註冊後才可使用。

表 4.1.1 73 個專案屬性列表

功能性 專案個數

應用程式 51

程式庫 5

ActiveX 元件 6

COM 元件 11

合計 73

// DRMPIDoc.h : interface of the CDRMPIDoc class

/////////////////////////////////////////////////////////////////////////////

#if !defined(AFX_DRMPIDOC_H__40AD8943_B1DB_43FF_907B_BB25D129315E__INCLUDED_)

#define AFX_DRMPIDOC_H__40AD8943_B1DB_43FF_907B_BB25D129315E__INCLUDED_

#if _MSC_VER > 1000

#pragma once

#endif // _MSC_VER > 1000 class CDRMPISrvrItem;

class CDRMPIDoc : public COleServerDoc {

protected: // create from serialization only CDRMPIDoc();

DECLARE_DYNCREATE(CDRMPIDoc) // Attributes

public:

CDRMPISrvrItem* GetEmbeddedItem()

{ return (CDRMPISrvrItem*)COleServerDoc::GetEmbeddedItem(); } // Operations

public:

// Overrides

// ClassWizard generated virtual function overrides //{{AFX_VIRTUAL(CDRMPIDoc)

protected:

virtual COleServerItem* OnGetEmbeddedItem();

public:

virtual BOOL OnNewDocument();

virtual void Serialize(CArchive& ar);

//}}AFX_VIRTUAL // Implementation public:

virtual ~CDRMPIDoc();

#ifdef _DEBUG

virtual void AssertValid() const;

virtual void Dump(CDumpContext& dc) const;

#endif protected:

virtual CDocObjectServer* GetDocObjectServer(LPOLEDOCUMENTSITE pDocSite);

protected:

//{{AFX_MSG(CDRMPIDoc)

// NOTE - the ClassWizard will add and remove member functions here.

// DO NOT EDIT what you see in these blocks of generated code !

// Microsoft Visual C++ will insert additional declarations immediately before the previous line.

#endif // !defined(AFX_DRMPIDOC_H__40AD8943_B1DB_43FF_907B_BB25D129315E__INCLUDED_)

圖 4.1.1 原始資料 H 檔格式

// DRMPIDoc.cpp : implementation of the CDRMPIDoc class

#include "stdafx.h"

#include "DRMPI.h"

#include "DRMPIDoc.h"

#include "SrvrItem.h"

#ifdef _DEBUG

#define new DEBUG_NEW

#undef THIS_FILE

static char THIS_FILE[] = __FILE__;

#endif

/////////////////////////////////////////////////////////////////////////////

// CDRMPIDoc

IMPLEMENT_DYNCREATE(CDRMPIDoc, COleServerDoc) BEGIN_MESSAGE_MAP(CDRMPIDoc, COleServerDoc)

//{{AFX_MSG_MAP(CDRMPIDoc)

// NOTE - the ClassWizard will add and remove mapping macros here.

// DO NOT EDIT what you see in these blocks of generated code!

//}}AFX_MSG_MAP END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////

{

// Use OLE compound files EnableCompoundFile(false);

// TODO: add one-time construction code here }

CDRMPIDoc::~CDRMPIDoc() {

}

BOOL CDRMPIDoc::OnNewDocument() {

if (!COleServerDoc::OnNewDocument()) return FALSE;

// TODO: add reinitialization code here // (SDI documents will reuse this document) return TRUE;

}

/////////////////////////////////////////////////////////////////////////////

// CDRMPIDoc server implementation

COleServerItem* CDRMPIDoc::OnGetEmbeddedItem() {

// OnGetEmbeddedItem is called by the framework to get the COleServerItem // that is associated with the document. It is only called when necessary.

CDRMPISrvrItem* pItem = new CDRMPISrvrItem(this);

ASSERT_VALID(pItem);

return pItem;

}

/////////////////////////////////////////////////////////////////////////////

// CDRMPIDoc Active Document server implementation

CDocObjectServer *CDRMPIDoc::GetDocObjectServer(LPOLEDOCUMENTSITE pDocSite) {

return new CDocObjectServer(this, pDocSite);

}

/////////////////////////////////////////////////////////////////////////////

// CDRMPIDoc serialization

void CDRMPIDoc::Serialize(CArchive& ar) {

if (ar.IsStoring())

// TODO: add storing code here }

else {

// TODO: add loading code here }

}

/////////////////////////////////////////////////////////////////////////////

// CDRMPIDoc diagnostics

#ifdef _DEBUG

void CDRMPIDoc::AssertValid() const {

COleServerDoc::AssertValid();

}

void CDRMPIDoc::Dump(CDumpContext& dc) const {

COleServerDoc::Dump(dc);

}

#endif //_DEBUG

/////////////////////////////////////////////////////////////////////////////

// CDRMPIDoc commands

圖 4.1.2 原始資料 CPP 檔格式

我們利用第二章所提到的資料探勘的技術來發掘重用樣式,首先我們假 設在我們執行過的軟體專案中有許多類別方法彼此之間是有關係的,而這些 類別方法與類別方法之間的關係是常常在許多專案中被重用,所以我們利用 關聯法則分析來挖掘程式類別方法與程式類別方法間的關聯。例如:

BOOL CBookMarkOper::AddBookMark(CString sKey,CString sText) {

CCryptClass crypt;

CString sOut;

crypt.EncryptString(sKey,sText,sOut);

……

return TRUE;

}

圖 4.1.3 程式呼叫片段

圖 4.1.3 表示了 CbookMarkOper 類別中的 AddBookMark 方法呼叫了 CcryptClass 類別中的 EncrytString 方法。這樣的一個程式片段就代表一 筆交易資料。透過資料探勘的技術,我們可以分析這些交易資料的支持度與 可信度來了解這樣的關係是否可以當成程式庫樣式。

我們資料庫的設計基碼(schema)如圖 4.1.4,欄位 id 為自動編號,新 增每筆資料時會自動加一,欄位 InvocClass 為呼叫的類別,欄位

InvocMethod 為呼叫的方法,欄位 Class 為被呼叫的類別,欄位 Method 為 被呼叫的方法。我們將每個程式片段分析後,轉變成每筆每筆交易資料存放 在資料庫中,再透過資料探勘的技術找出最常使用的呼叫類別方法與被呼叫 類別方法,最後使用主題地圖來顯示結果供軟體工程師參考。

If exists (select * from dbo.sysobjects where id = object_id(N'[dbo].[tblInvocation]') and OBJECTPROPERTY(id, N'IsUserTable') = 1)

drop table [dbo].[tblInvocation]

GO

CREATE TABLE [dbo].[tblInvocation] (

[id] [int] IDENTITY (1, 1) NOT FOR REPLICATION NOT NULL ,

[InvocClass] [varchar] (50) COLLATE Chinese_Taiwan_Stroke_CI_AS NOT NULL , [InvocMethod] [varchar] (50) COLLATE Chinese_Taiwan_Stroke_CI_AS NOT NULL , [Class] [varchar] (50) COLLATE Chinese_Taiwan_Stroke_CI_AS NOT NULL , [Method] [varchar] (50) COLLATE Chinese_Taiwan_Stroke_CI_AS NOT NULL ) ON [PRIMARY]

GO

CONSTRAINT [PK_tblInvocation] PRIMARY KEY CLUSTERED (

[id]

) ON [PRIMARY]

GO

圖 4.1.4 建立類別方法呼叫類別方法資料庫的 script

相關文件