ĐẠI HỌC QUỐC GIA HÀ NỘI TRƯỜNG ĐẠI HỌC CÔNG NGHỆ

Nguyễn Thế Nam NGHIÊN CỨU THIẾT KẾ THEO HỢP ĐỒNG VÀ XÂY DỰNG CÔNG CỤ HỖ TRỢ

KHOÁ LUẬN TỐT NGHIỆP ĐẠI HỌC HỆ CHÍNH QUY Ngành: Công Nghệ Thông Tin

HÀ NỘI - 2010

ĐẠI HỌC QUỐC GIA HÀ NỘI TRƯỜNG ĐẠI HỌC CÔNG NGHỆ

Nguyễn Thế Nam NGHIÊN CỨU THIẾT KẾ THEO HỢP ĐỒNG VÀ XÂY DỰNG CÔNG CỤ HỖ TRỢ KHOÁ LUẬN TỐT NGHIỆP ĐẠI HỌC HỆ CHÍNH QUY Chuyên ngành: Công Nghệ Phần Mềm Cán bộ hướng dẫn: TS. Trương Ninh Thuận

HÀ NỘI - 2010

LỜI CẢM ƠN

Sinh viên thực hiện khoá luận tốt nghiệp đề tài “Nghiên cứu thiết kế theo hợp

đồng và xây dựng công cụ hỗ trợ” xin được bày tỏ lòng chân thành biết ơn tới các thầy

cô giáo Trường Đại học Công Nghệ, Đại học Quốc Gia Hà Nội nói chung và thầy cô

Bộ môn Công nghệ Phần mềm nói riêng. Trong suốt bốn năm qua thầy cô không những tận tình truyền đạt kiến thức mà còn luôn động viên chúng tôi trong học tập

cũng như trong cuộc sống.

Đặc biệt, chúng tôi xin chân thành cảm ơn thầy giáo hướng dẫn, thầy Trương

Ninh Thuận, đã tận tình chỉ bảo, tạo mọi điều kiện cơ sở vật chất cũng như tinh thần cho chúng tôi hoàn thành khóa luận và sửa chữa những sai sót trong suốt quá trình

thực hiện đề tài.

Chúng tôi cũng xin cảm ơn tới các bạn sinh viên K51 đã cho chúng tôi những ý

kiến đóng góp có giá trị khi thực hiện đề tài này.

Đề tài “Nghiên cứu thiết kế theo hợp đồng và xây dựng công cụ hỗ trợ” được

hoàn thành trong thời gian hạn hẹp nên không tránh khỏi những khiếm khuyết. Chúng

tôi rất mong nhận được ý kiến đóng góp từ thầy cô giáo và các bạn để có thể tiếp tục

hoàn thiện hệ thống này hơn.

Hà nội ngày 24 tháng 4 năm 2010

Sinh viên

Nguyễn Thế Nam

TÓM TẮT NỘI DUNG

Khóa luận tìm hiểu về công nghệ thiết kế theo hợp đồng (Design by Contract) [3]

và trình bày những khái niệm cơ bản. Đây là công nghệ giúp cho chúng ta xây dựng đặc tả giữa các lớp trong một thành phần và xem xét sự kết hợp giữa chúng với nhau.

Mở rộng hơn nữa là đặc tả các thành phần trong một phần mềm và các thành phần phải thỏa mãn những điều kiện nào đó mới có thể liên kết với nhau để tạo thành phần mềm

có tính tin cậy, tính đúng đắn cao.

Bên cạnh đó khóa luận còn đưa ra một số khái niệm và cơ chế cho tính đúng đắn

của phần mềm. Các cấu trúc đơn giản thường có tính tin cậy hơn những phần mềm có cấu trúc phức tạp. Nhưng điểm yếu của nó lại không thể phục vụ được nhu cầu ngày

càng tăng lên của người phát triển và người sử dụng. Vì thế, một số cơ chế như cố

gắng giữ cho cấu trúc của phần mềm càng đơn giản càng tốt. Viết văn bản mô tả phần

mềm để người phát triển sau này có thể đọc lại hoặc viết lại. Quản lý bộ nhớ, hay còn

được gọi là “kỹ thuật thu gom rác” cũng làm cho phần mềm tối ưu hơn bình thường.

Hoặc là việc sử dụng lại những công cụ có sẵn của những phần mềm đáng tin cậy

trước đó cũng là một giải pháp thường được các nhà phát triển ứng dụng. Chi tiết hơn

nữa là phát triển tất cả các giai đoạn: phân tích, thiết kế, lập trình, kiểm thử, bảo trì

trong một dự án phần mềm.

Tiếp theo, khóa luận còn đưa ra các mô hình dựa trên CORBA. Khái niệm về kỹ

nghệ phần mềm hướng thành phần. Một phần mềm được tạo ra là do sự ghép nối các

thành phần độc lập lại với nhau. Các thành phần này sẽ không cần phải biên dịch lại

hoặc không cần phải chỉnh sửa lại khi thêm mới một thành phần khác hay là chỉnh sửa

một thành phần có sẵn. Mô hình thành phần CORBA là mô hình chính mà chúng tôi

nghiên cứu và ứng dụng nó trong việc xây dựng công cụ hỗ trợ.

Ngoài ra khóa luận còn đi vào xây dựng công cụ đặc tả và kiếm chứng hỗ trợ

người dùng kiểm tra sự phù hợp của các thành phần khi kết nối với nhau một cách trực quan. Công cụ có áp dụng những công nghệ mới hiện nay như mô hình Model – View – Controller (M-V-C) [6] hoặc sử dụng thư viện layer trong lập trình java game, dễ dàng cho việc lập trình công cụ.

MỤC LỤC Mở đầu .......................................................................................................................1

CHƯƠNG 1. Tính đúng đắn, tính tin cậy của phần mềm .......................................3

1.1. Một số cơ chế mang lại tính đúng đắn.............................................................3

1.2. Biểu diễn một đặc tả .......................................................................................4

1.2.1. Những công thức của tính đúng đắn......................................................4

1.2.2. Những điều kiện yếu, mạnh ..................................................................5

1.3. Giao ước cho tính tin cậy của phần mềm ........................................................7

1.3.1. Quyền lợi..............................................................................................8

1.3.2. Nghĩa vụ ...............................................................................................8

CHƯƠNG 2. Giới thiệu về Design by Contract .......................................................9

2.1. Giới thiệu .......................................................................................................9

2.2. Khái niệm về hợp đồng.................................................................................10

2.3. Tiền điều kiện, hậu điều kiện và tính bất biến ...............................................11

2.3.1. Tiền điều kiện và hậu điều kiện...........................................................11

2.3.2. Tính bất biến.......................................................................................12

2.4. Design By Contract trong Eiffel....................................................................12

2.4.1. Biểu diễn Design by Contract trong Eiffel ..........................................13

2.4.2. Ví dụ minh họa ...................................................................................14

CHƯƠNG 3. Mô hình thành phần CORBA...........................................................16

3.1. Khái niệm cơ bản về công nghệ phần mềm hướng thành phần ......................16

3.1.1. Giới thiệu............................................................................................16

3.1.2. Thành phần .........................................................................................17

3.1.3. Đối tượng và thành phần.....................................................................17

3.1.4. Giao diện ............................................................................................18

3.1.5. Hợp đồng............................................................................................19

3.1.6. Khuôn mẫu .........................................................................................21

3.1.7. Frameworks ........................................................................................21

3.1.8. Frameworks và thành phần .................................................................22

3.2. Khái niệm CORBA.......................................................................................22

3.2.1. Giới thiệu............................................................................................22

3.2.2. Ngôn ngữ đặc tả giao tiếp IDL............................................................23

3.3. Mô hình thành phần CORBA........................................................................25

3.3.1. Giao diện và sự nối ghép.....................................................................25

3.3.2. Đặc tả CCM bằng ngôn ngữ IDL ........................................................27

3.3.2.1. Thành phần .....................................................................................27

3.3.2.2. Facets..............................................................................................27

3.3.2.3. Receptacles .....................................................................................28

3.3.2.4. Event Sources..................................................................................28

3.3.2.5. Event Sinks .....................................................................................30

3.3.3. Điều kiện kết nối.................................................................................30

CHƯƠNG 4. Xây dựng công cụ đặc tả và kiểm chứng thành phần......................31

4.1. Mô tả công cụ ...............................................................................................31

4.2. Ngôn ngữ phát triển công cụ.........................................................................31

4.3. Phân tích công cụ đặc tả và kiểm chứng thành phần......................................31

4.3.1. Mô tả công cụ .....................................................................................31

4.3.2. Mô hình hoạt động..............................................................................32

4.3.3. Thiết kế các lớp và đối tượng..............................................................32

4.3.3.1. Sơ đồ tương tác giữa các đối tượng .................................................33

4.3.3.2. Mô tả chi tiết các lớp đối tượng.......................................................35

4.4. Triển khai .....................................................................................................37

4.5. Thử nghiệm ..................................................................................................37

4.5.1. Bài toán ..............................................................................................37

4.5.2. Giao diện khởi động chương trình.......................................................40

4.5.3. Giao diện khi làm việc với các thành phần..........................................41

4.5.4. Giao diện làm việc với các cổng .........................................................42

4.5.5. Giao diện sau khi kiểm chứng kết nối giữa các thành phần .................45

Kết luận ....................................................................................................................47

Hướng phát triển .....................................................................................................48

Tài liệu tham khảo ...................................................................................................49

Phụ lục......................................................................................................................50

DANH MỤC HÌNH VẼ Hình 1: Giao diện thành phần CORBA và các cổng...................................................26

Hình 2: Mô hình MVC...............................................................................................32

Hình 3: Sơ đồ lớp thể hiện mối liên hệ giữa các đối tượng trong ứng dụng ................34

Hình 4: Sơ đồ lớp thể hiện mối quan hệ kế thừa của các cổng....................................34

Hình 5: Lớp Component ............................................................................................35

Hình 6: Lớp port ........................................................................................................35

Hình 7: Lớp canvaspanel ...........................................................................................36

Hình 8: Lớp Contract .................................................................................................37

Hình 9: Kiến trúc CCM của hệ thống Stock Quoter. ..................................................38

Hình 10: Giao diện thành phần CORBA và các cổng. ................................................38

Hình 11: Giao diện khởi động ứng dụng ....................................................................40

Hình 12: Giao diện điền thông tin khi thêm mới 1 thành phần ...................................41

Hình 13: Giao diện kết quả sau khi thêm một thành phần thành công ........................42

Hình 14: Giao diện điền thông tin khi thêm một cổng mới.........................................43

Hình 15: Giao diện kết quả khi thêm mới cổng thành công ........................................44

Hình 16: Giao diện khi kết nối thành công các cổng ..................................................45

Hình 17: Giao diện khi kết nối không thành công các cổng........................................46

DANH MỤC BẢNG BIỂU

Bảng 1: Hợp đồng giữa một hãng hàng không và khành hàng....................................10

Bảng 2: Hợp đồng chèn một từ vào từ điển ................................................................11

Bảng 3: Bảng ánh xạ từ IDL sang java.......................................................................24

Bảng 4: Các lớp đối tượng trong ứng dụng ................................................................33

Bảng 5: Chi tiết lớp component .................................................................................35

Bảng 6: Chi tiết lớp port ............................................................................................36

Bảng 7: Chi tiết lớp canvaspanel................................................................................36

Bảng 8: Chi tiết lớp Contract .....................................................................................37

DANH MỤC CÔNG THỨC

Công thức 1: Công thức tính đúng đắn.........................................................................4

Công thức 2: Tiền điều kiện mạnh, hậu điều kiện không cần phải quan tâm.................5

Công thức 3: Hậu điều kiện mạnh, tiền điều kiện không cần phải quan tâm. ................6

Công thức 4: Điều kiện bất biến trong công thức tính đúng đắn .................................12

BẢNG KÝ HIỆU, CHỮ VIẾT TẮT

Viết tắt Viết đầy đủ Giải nghĩa

DbC Design by Contract Thiết kế theo hợp đồng

Kĩ nghệ phần mềm hướng thành phần CBSE Component-Based Software Engineering

Component-Based Phát triển hướng thành phần CBD Development

Common Object Request Kiến trúc môi giới gọi các đối tượng CORBA Broker Architecture phân tán

CORBA component CCM Mô hình thành phần CORBA Model

Application Giao diện lập trình ứng dụng API Programming Interface

Mở đầu

Trong phát triển phần mềm, thay đổi yêu cầu là một tất yếu diễn ra hết sức

thường xuyên mà những nhà phát triển phải chấp nhận và cố gắng điều chỉnh nó. Phần mềm này ra đời thay thế phần mềm khác là một điều vô cùng bình thường, dễ hiểu. Tại

sao lại như thế? Bởi vì người sử dụng luôn mong muốn có được một phần mềm hữu ích hơn, tiện lợi hơn và hoạt động tốt hơn. Tuy nhiên, dù phần mềm có thể đáp ứng

những nhu cầu của người sử dụng trong thời gian hiện tại thì cũng không thể đảm bảo

nó sẽ luôn được ưa chuộng. Để có thể tồn tại lâu dài, phần mềm phải thật sự chất

lượng. Điều này đồng nghĩa với việc nó phải không ngừng được cập nhật. Mà như chúng ta đã biết, phần mềm càng đúng đắn, đáng tin cậy và rõ ràng bao nhiêu thì công

việc nâng cấp và phát triển nó càng dễ dàng bấy nhiêu. Do đó, có thể nói, một trong

những tiêu chí của ngành công nghệ phần mềm mà bất kỳ thời đại nào, bất kỳ sản

phẩm phần mềm nào cũng đều hướng đến là tính đáng tin cậy và đúng đắn. Xuất phát

từ nhu cầu ấy, công nghệ thiết kế theo hợp đồng (Design By Contract) đã ra đời nhằm

giúp cho việc đảm bảo cho tính đáng tin cậy của phần mềm. Đó cũng chính là lý do mà

chúng tôi đã chọn đề tài này.

Với mục đích tìm hiểu công nghệ thiết kế theo hợp đồng một cách khá kỹ lưỡng,

chúng tôi đã tiếp cận nó bằng các tài liệu lý thuyết cũng như qua các công cụ có khả

năng hỗ trợ Design By Contract cho các ngôn ngữ lập trình hiện đại. Không dừng ở

đó, chúng tôi còn xây dựng một công cụ về đặc tả và kiểm chứng cho các thành phần

trong ngôn ngữ Java.

Đối tượng và phạm vi nghiên cứu: ý tưởng chính của thiết kế theo hợp đồng là

lập một “hợp đồng” giữa các đối tượng cung cấp (supplier) và những khách hàng

(client) của nó, tức là những lớp đối tượng khác gọi đến các phương thức của lớp này.

Những client này phải bảo đảm một số điều kiện nhất định khi gọi một phương thức

của một supplier gọi là tiền điều kiện (precondition); đáp lại, sau khi thực thi thủ tục, supplier phải đáp ứng một số điều kiện tương ứng gọi là hậu điều kiện (postcondition). Những điều kiện của hợp đồng sẽ được kiểm tra bởi trình biên dịch, và bất cứ sự vi phạm nào của phần mềm cũng sẽ được phát hiện. Mở rộng hơn là nghiên cứu thành phần phần mềm. Nó là một trong những nghiên cứu quan trọng trong kỹ nghệ phần mềm hướng thành phần, thể hiện bước đầu tiên hướng tới việc tái sử dụng thành phần, đặc tả thành phần mang lại những thông tin cần thiết để người sử dụng có thể hiểu

được vì sao và như thế nào mà thành phần có thể sử dụng được hoặc tái sử dụng. Từ

1

đó nghiên cứu mối quan hệ giữa các thành phần trong một phần mềm và điều kiện để

các thành phần đó có thể liên kết được với nhau. Song song với việc nghiên cứu công

nghệ thiết kế theo hợp đồng, chúng tôi cũng đã nghiên cứu sâu hơn về ngôn ngữ java, mô hình thiết kế Model – View – Controller (M-V-C) và xây dựng công cụ đặc tả,

2

kiếm chứng giúp cho việc làm sáng rõ thêm công nghệ mà chúng tôi đã nghiên cứu.

CHƯƠNG 1. Tính đúng đắn, tính tin cậy của phần mềm

1.1. Một số cơ chế mang lại tính đúng đắn

Trước hết, phải nói rằng kỹ thuật định nghĩa thuộc tính của một đối tượng gần

như là có liên quan với cấu trúc của những hệ thống phần mềm. Những kiến trúc đơn giản, riêng biệt và có khả năng mở rộng sẽ giúp chúng ta đảm bảo tính đáng tin cậy

của phần mềm dễ dàng hơn so với những cấu trúc phức tạp. Đặc biệt, cố gắng giới hạn

sự liên quan giữa các môđun với nhau đến mức tối thiểu nhất sẽ là tiêu điểm cho việc

thảo luận về tính riêng biệt. Điều này giúp ngăn chặn những rủi ro thông thường của tính đáng tin cậy, ví dụ như những biến toàn cục và việc định nghĩa những cơ chế liên

lạc bị giới hạn, client và những mối quan hệ kế thừa. Nói đến chất lượng phần mềm thì

không thể bỏ qua tính đáng tin cậy. Chúng ta cố gắng giữ cho những cấu trúc càng đơn

giản càng tốt. Tuy rằng điều này vẫn chưa đủ đảm bảo cho tính đáng tin cậy của phần

mềm, nhưng dù sao, nó cũng là một điều kiện cần thiết.

Một cơ chế khác nữa là làm cho phần mềm của chúng ta tối ưu và dễ đọc. Văn

bản mô tả phần mềm không những được viết một lần mà nó còn phải được đọc đi đọc

lại và viết đi viết lại nhiều lần. Sự trong sáng và tính đơn giản của các câu chú thích là

những yêu cầu cơ bản để nâng cao tính đáng tin cậy của phần mềm.

Thêm vào đó, một cơ chế cũng rất cần thiết là việc quản lý bộ nhớ một cách tự

động, đặc biệt là kỹ thuật thu gom rác (garbage collection). Đây là cơ chế được sử

dụng phổ biến trong việc viết ứng dụng hiện nay. Các ứng dụng một cách tự động có

thể thu hồi hoặc xóa đi các mảnh vụn bộ nhớ không còn được sử dụng nữa. Bất kỳ hệ

thống nào có khởi tạo và thao tác với cấu trúc dữ liệu động mà lại thực hiện thu hồi bộ

nhớ bằng tay (tức là do người lập trình điều khiển) hoặc bộ nhớ không hề được thu hồi

thì thật là nguy hiểm.

Ngoài ra, việc sử dụng lại những công cụ của những phần mềm đáng tin cậy trước đó cũng tăng thêm tính tin cậy cho phần mềm của chúng ta hơn là khi ta xây dựng một hệ thống mới hoàn toàn.

Tóm lại, tất cả những cơ chế này cung cấp một nền tảng cần thiết để ta có cái

3

nhìn gần hơn về một hệ thống phần mềm đúng đắn và bền vững.

1.2. Biểu diễn một đặc tả

1.2.1. Những công thức của tính đúng đắn

Giả sử A thực hiện một vài thao tác (ví dụ A là một câu lệnh hay thân của một

thủ tục). Một công thức của tính đúng đắn là một cách biểu diễn theo dạng sau:

{P} A {Q}

Công thức 1: Công thức tính đúng đắn

Ý nghĩa của công thức tính đúng đắn {P} A {Q}

Bất kỳ thi hành nào của A, bắt đầu ở trạng thái P thì sẽ kết thúc với trạng thái Q

Những công thức của tính đúng đắn (còn được gọi là bộ ba Hoare [7]) là một ký

hiệu toán học, không phải là một khái niệm lập trình; chúng không phải là một trong

số những ngôn ngữ phần mềm mà chỉ được thiết kế nhằm giúp cho việc thể hiện

những thuộc tính của các thành phần phần mềm. Trong công thức 1, A biểu thị cho

một thao tác, P và Q là những thuộc tính của những thực thể khác nhau có liên quan

hay còn được gọi là những xác nhận. Trong hai xác nhận này, P được gọi là tiền điều

kiện (precondition) và Q được gọi là hậu điều kiện (postcondition).

Ví dụ, chúng ta có một công thức bình thường của tính đúng đắn như sau với giả

sử rằng x là một số nguyên:

{x>=10} x := x+6 {x>=15}

Công thức tính đúng đắn được sử dụng để đánh giá tính đúng đắn của phần mềm.

Điều đó cũng có nghĩa là tính đúng đắn chỉ được xét đến khi nó gắn với một đặc tả nào

đó. Như vậy, khi thảo luận về tính đúng đắn của phần mềm, ta không nói đến những

thành phần phần mềm riêng lẻ A, mà nó là bộ ba bao gồm một thành phần phần mềm

A, một tiền điều kiện P và một hậu điều kiện Q. Mục đích duy nhất của việc này là

thiết lập kết quả cho những công thức tính đúng đắn {P} A {Q}.

Trong ví dụ trên, con số 15 ở hậu điều kiện không phải là lỗi do in ấn hay gõ phím. Giả sử thực hiện đúng phép tính trên số nguyên ở công thức trên: với điều kiện

x>=7 là đúng trước câu lệnh, x>=15 sẽ đúng sau khi thực hiện câu lệnh.

Tuy nhiên, chúng ta thấy được nhiều điều thú vị hơn:

- Với một tiền điều kiện như vậy, hậu điều kiện hay nhất phải là điều kiện

4

mạnh nhất, và trong trường hợp này là x>=16.

- Còn với hậu điều kiện đã đưa ra thì tiền điều kiện hay nhất phải là tiền

điều kiện yếu nhất, ở đây là x>=9.

Từ một công thức đã cho, chúng ta luôn có thể có được một công thức khác bằng

cách mở rộng tiền điều kiện hay nới lỏng đi hậu điều kiện. Bây giờ, chúng ta sẽ cùng

nhau xem xét nhiều hơn về những khái niệm “mạnh hơn” và “yếu hơn” là thế nào.

1.2.2. Những điều kiện yếu, mạnh

Một cách để xem xét đặc tả theo dạng {P} A {Q} là xem nó như một mô tả các

công việc cho A. Điều này cũng giống như có một mục quảng cáo tuyển người trên

báo đăng rằng “Cần tuyển một người có khả năng thực hiện công việc A khi A có trạng thái bắt đầu là P, và sau khi A được hoàn tất thì nó phải thỏa mãn Q”.

Giả sử, một người bạn của bạn đang kiếm việc và tình cờ đọc được những quảng

cáo tương tự như thế này, tất cả lương và lợi ích của chúng đều như nhau, chỉ có điều

là chúng khác nhau ở những cái P và Q. Cũng giống như nhiều người, bạn của bạn thì

lười nhác, có thể nói rằng, anh ta muốn có một công việc dễ nhất. Và anh ta hỏi ý kiến

bạn là nên chọn công việc nào. Trong trường hợp này, bạn sẽ khuyên anh ấy thế nào?

Trước hết, với P: bạn khuyên anh ta nên chọn một công việc với tiền điều kiện

yếu hay mạnh? Câu hỏi tương tự cho hậu điều kiện Q. Bạn hãy suy nghĩ và chọn cho

mình một quyết định trước khi xem câu trả lời ở phần dưới.

Trước hết, ta nói về tiền điều kiện. Từ quan điểm của người làm công tương lai,

tức là người sẽ thực hiện công việc A, tiền điều kiện P định nghĩa những trường hợp

mà ta sẽ phải thực hiện công việc. Do đó, một P mạnh là tốt, vì P càng mạnh thì các

trường hợp bạn phải thực hiện A càng được giới hạn. Như vậy, P càng mạnh thì càng

dễ cho người làm công. Và tuyệt vời nhất là khi kẻ làm công chẳng phải làm gì cả tức

là hắn ta là kẻ ăn không ngồi rồi. Điều này xảy ra khi công việc A được định nghĩa

bởi:

{False} A {…}

Công thức 2: Tiền điều kiện mạnh, hậu điều kiện không cần phải quan tâm

5

Trong trường hợp này, hậu điều kiện không cần thiết phải đề cập bởi dù nó có là gì thì cũng không có ảnh hưởng. Nếu có bao giờ bạn thấy một mục tuyển người như vậy thì đừng mất công đọc hậu điều kiện mà hãy chớp lấy công việc đó ngay lập tức. Tiền điều kiện False là sự xác nhận mạnh nhất có thể vì nó không bao giờ thỏa mãn một trạng thái nào cả. Bất cứ yêu cầu nào để thực thi A cũng sẽ không đúng, và lỗi

không nằm ở trách nhiệm của A mà là ở người yêu cầu hay khách hàng (client) bởi nó

đã không xem xét bất cứ tiền điều kiện nào cần đến. Dù cho A có làm hay không làm gì đi nữa thì nó cũng luôn đúng với đặc tả.

Còn với hậu điều kiện Q, tình trạng bị đảo ngược. Một hậu điều kiện mạnh là

một tin xấu: nó chỉ ra rằng bạn phải mang lại nhiều kết quả hơn. Q càng yếu, càng tốt

cho người làm thuê. Thực tế, công việc ăn không ngồi rồi tốt nhì trên thế giới là công việc được định nghĩa mà không chú ý đến tiền điều kiện:

{…} A {True}

Công thức 3: Hậu điều kiện mạnh, tiền điều kiện không cần phải quan tâm.

Hậu điều kiện True là một xác nhận yếu nhất vì nó thỏa mãn mọi trường hợp.

Khái niệm “mạnh hơn” hay “yếu hơn” được định nghĩa một cách hình thức từ

logic:

P1 được gọi là mạnh hơn P2, và P2 yếu hơn P1 nếu P1 bao hàm P2 và chúng

không bằng nhau. Khi mọi lời xác nhận bao hàm True, và False bao hàm mọi xác nhận

thì thật là hợp lý để nói rằng True như là yếu nhất và False như là mạnh nhất với tất cả

xác nhận có thể.

Đến đây, có một câu hỏi được đặt ra: “Tại sao công thức 2 là công việc tốt nhì

trên thế giới?” Câu trả lời chính là một điểm tinh tế trong phần định nghĩa ý nghĩa của

công thức {P} A {Q}: sự kết thúc. Định nghĩa nói rằng sự thực thi phải kết thúc trong

tình trạng thoả Q miễn là khi bắt đầu nó thoả P.

Với công thức 1, không có trường hợp nào thoả P. Do đó, A là gì cũng không

thành vấn đề, ngay cả nó là một đoạn mã mà khi thi hành, chương trình sẽ bị rơi vào

một vòng lặp không điểm dừng hay là sẽ gây hỏng máy cũng chẳng sao.

Vì dù A là gì thì cũng đúng với đặc tả của nó. Tuy nhiên, với công thức 2, vấn đề

là ở trạng thái kết thúc, nó không cần thoả mãn bất kỳ thuộc tính đặc biệt nào nhưng trạng thái kết thúc phải được đảm bảo là có tồn tại.

6

Những ai đã quen với lý thuyết khoa học máy tính hay những kỹ thuật chứng minh lập trình sẽ thấy rằng công thức {P} A {Q} dùng ở đây ám chỉ toàn bộ tính đúng đắn, bao gồm cả sự kết thúc cũng như việc phù hợp với đặc tả. (Tính chất mà một chương trình sẽ thoả mãn với đặc tả của nó lúc kết thúc là một phần của tính đúng đắn).

Chúng ta đã thảo luận một xác nhận mạnh hơn hay yếu hơn là những “tin tốt”

hay “tin xấu” là dựa trên quan điểm của một người làm công trong tương lai. Nếu bây giờ thay đổi cách nhìn, đứng trên cương vị của một người chủ, ta thấy mọi thứ sẽ thay

đổi: một tiền điều kiện yếu sẽ là những tin tốt nếu ta muốn các trường hợp thực thi

công việc được tăng lên, và một hậu điều kiện mạnh sẽ là tốt nếu ta muốn những kết

quả của công việc thật sự có ý nghĩa.

Sự đảo ngược của những tiêu chuẩn này là đặc trưng của việc thảo luận về tính

đúng đắn của phần mềm, và sẽ xuất hiện lại như khái niệm chính trong luận văn này:

hợp đồng giữa những khách hàng và những môđun cung cấp là một sự ràng buộc giữa

hai bên. Để sản xuất ra một phần mềm hiệu quả và đáng tin cậy thì cần phải có một hợp đồng đại diện cho sự thoả hiệp tốt nhất của tất cả mối liên hệ giữa những nhà cung

cấp và khách hàng.

1.3. Giao ước cho tính tin cậy của phần mềm

Bằng cách kết hợp những mệnh đề tiền điều kiện pre và hậu điều kiện post trong

thủ tục r, lớp đối tượng “tuyên bố” với những khách hàng của nó:

Nếu các bạn hứa gọi r thỏa mãn pre, tôi hứa sẽ trả về kết quả thỏa mãn post [3]

Trong mối liên hệ giữa người và người hoặc giữa các công ty với nhau, hợp đồng

là một văn bản làm cho những điều khoản của mối quan hệ trở nên trong sáng, rõ ràng.

Thật đáng ngạc nhiên khi trong lĩnh vực phần mềm, nơi mà sự đúng đắn, rõ ràng có

vai trò sống còn, ý tưởng hợp đồng này lại phải mất quá nhiều thời gian để thể hiện

mình. Tiền điều kiện và hậu điều kiện mô tả một hợp đồng giữa thủ tục (đóng vai trò

nhà cung cấp) và những đối tượng gọi đến nó (vai trò khách hàng).

Đặc tính quan trọng nhất của hợp đồng trong công việc của con người là sự đòi

hỏi về “nghĩa vụ” (obligation) và “quyền lợi” (right) cho cả 2 bên – thường là nghĩa vụ

của bên này sẽ trở thành quyền lợi của bên kia. Điều này cũng đúng đối với hợp đồng

giữa các lớp đối tượng:

- Tiền điều kiện ràng buộc khách hàng: nó định nghĩa những điều kiện để một lời gọi đến thủ tục trở nên hợp pháp. Đây là nghĩa vụ của khách hàng và là quyền lợi của nhà cung cấp.

- Hậu điều kiện ràng buộc lớp đối tượng: nó định nghĩa những điều kiện cần phải được đảm bảo bởi thủ tục khi trả về. Đây là quyền lợi của khách hàng

7

và là nghĩa vụ của nhà cung cấp.

1.3.1. Quyền lợi

Đối với khách hàng, đó là sự đảm bảo những thuộc tính phải có được sau khi gọi

thủ tục.

Đối với nhà cung cấp, đó là sự đảm bảo những tính chất phải được thỏa mãn ở

bất cứ nơi nào thủ tục được gọi.

1.3.2. Nghĩa vụ

Đối với khách hàng, đó là sự đáp ứng những yêu cầu được phát biểu trong tiền

điều kiện.

8

Đối với nhà cung cấp, đó là những gì phải làm mà hậu điều kiện đã định ra.

CHƯƠNG 2. Giới thiệu về Design by Contract

2.1. Giới thiệu

Khi xét đến sự phát triển các phương thức và công cụ của một phần mềm mới,

các nhà phát triển đã có khuynh hướng chú trọng đến năng suất hơn là chất lượng của phần mềm. Thời đại hiện nay, xu hướng đó đã không còn phù hợp. Trong công nghệ

hướng đối tượng [3] các lợi ích về năng suất đã xếp vị trí thứ yếu, phần lớn các nhà

phát triển đã chuyển sang lợi ích về chất lượng sản phẩm.

Một phần chính trong chất lượng sản phẩm là tính đúng đắn, tính tin cậy của phần mềm: đó là khả năng của một hệ thống có thể thực hiện các công việc của mình

theo các đặc tả có sẵn và có thể xử lý được các tình huống bất thường. Nói một cách

đơn giản, tính tin cậy tức là không có lỗi.

Có nhiều cách xây dựng nên tính tin cậy cho phần mềm. Chúng ta có thể sử dụng

lại các phương thức có sẵn. Có nghĩa là dùng lại những thành phần của các phần mềm

thông dụng mà đúng đắn, nó làm cho phần mềm mà chúng ta xây dựng đạt được tính

tin cậy hơn là xây dựng mới các phần mềm. Một cách khác, việc bẫy những mâu thuẫn

của chương trình trước khi chúng trở thành lỗi cũng góp phần củng cố thêm tính đúng

đắn của phần mềm. Hoặc là “kỹ thuật thu gom rác” – kỹ thuật thu gọn các mảnh vụn

bộ nhỡ không còn được sử dụng nữa – cũng làm cho phần mềm được tin cậy hơn.

Nhưng như thế vẫn chưa đủ, để chắc chắn rằng phần mềm hướng đối tượng sẽ thi

hành một cách đúng đắn, chúng ta vẫn cần một hệ thống các phương pháp để xác định

và triển khai các thành phần của phần mềm hướng đối tượng và các mối quan hệ của

chúng trong hệ thống phần mềm. Một phương pháp mới mẻ đã xuất hiện, nó được gọi

là “Design by Contract”, được tạm dịch là “Thiết kế theo hợp đồng”. Theo thuyết Design by Contract, một hệ thống phần mềm được xem như là tập hợp các thành phần có các giao tiếp tương tác với nhau dựa trên định nghĩa chính xác của các giao ước trong hợp đồng.

Lợi ích của “Design by Contract” bao gồm:

 Giúp cho việc hiểu biết rõ hơn về các phương pháp hướng đối tượng và

9

tổng quát hơn là của cấu trúc của phần mềm.

 Tiếp cận một cách có hệ thống đến việc xây dựng hệ thống hướng đối

tượng có ít hoặc hoàn toàn không có lỗi.

 Xây dựng được các framework hiệu quả hơn cho việc gỡ lỗi, kiểm thử.

 Dễ dàng viết tài liệu cho phần mềm.

 Hiểu và kiểm soát được kỹ thuật thừa kế.

 Một kỹ thuật cho mối quan hệ với các trường hợp dị thường, dẫn đến sự an toàn và hiệu quả cho việc xây dựng các ngôn ngữ xử lý các trường hợp ngoại lệ.

2.2. Khái niệm về hợp đồng

Trong công việc thường ngày, một hợp đồng được viết bởi hai bên khi một bên

(bên cung cấp) trình bày các công việc với bên kia (bên khách hàng). Mỗi bên mong

chờ các lợi ích từ hợp đồng và chấp nhận các giao ước có trong hợp đồng đó. Thông

thường, mỗi giao ước của bên này sẽ là lợi ích cho bên kia và ngược lại. Mục tiêu của

bản hợp đồng là giải thích rõ ràng các lợi ích và các giao ước.

Một ví dụ đơn giản sau đây minh họa cho một hợp đồng giữa một hãng hàng

không và khách hàng.

Bảng 1: Hợp đồng giữa một hãng hàng không và khành hàng

Giao ước Lợi ích

Bên khách hàng - Đến được địa điểm

- Phải có mặt ở sân bay ít nhất 5 phút trước khi mong muốn. (khách hàng)

khởi hành.

- Chỉ mang theo hành lý đã được kiểm định.

- Thanh toán tiền vé máy

bay.

Bên cung cấp - Đưa khách hàng điến địa - Không cần quan

điểm cần đến hàng (Hãng

tâm khách hàng đến trễ hay không. không)

- Có mang hành lý cấm

hay không.

10

- Đã trả tiền vé chưa.

Hợp đồng đảm bảo cho cả bên khách bởi sự chỉ rõ nên thực hiện những gì và cho bên cung cấp bằng cách chỉ ra bên cung cấp không phải chịu trách nhiệm về những gì

bên thực hiện không thực hiện đúng những quy định trong phạm vi hợp đồng.

Cùng chung một ý tưởng áp dụng cho phần mềm. Xem xét một yếu tố phần mềm

E. Để đạt được mục đích (thực hiện hợp đồng riêng của mình). E sử dụng một chiến lược nhất định, bao gồm những công việc con t1, t2,…, tn. Nếu một công việc con ti nào đó bất thường, nó sẽ được thực hiện bằng cách gọi một thủ tục R. Nói cách khác, E

hợp đồng ra công việc con cho R. Tình trạng như vậy cần phải được quản lý bằng bảng

phân công nghĩa vụ và lợi ích một cách rõ ràng.

Ví dụ như ti là công việc chèn một từ vào từ điển (một bảng mà mỗi phần tử

được xác định bởi một chuỗi ký tự sử dụng như là một khóa). Hợp đồng sẽ là:

Bảng 2: Hợp đồng chèn một từ vào từ điển

Giao ước Lợi ích

Bên thực hiện

- Chắc chắn rằng bảng không đầy dữ liệu và - Cập nhật bảng chứa các yếu tố xuất hiện, liên kết

khóa không phải là với các khóa.

chuỗi rỗng

Bên cung cấp

- Bản ghi đưa các yếu tố vào bảng, liên kết với - Không cần phải làm gì nếu bảng đầy hoặc khóa

các khóa. là một chuỗi rỗng..

Thiết kế theo hợp đồng được sử dụng ở đây để cung cấp đặc tả chính xác cho các

chức năng của các thành phần và nâng cao tính tin cậy của chúng. Theo Meyer [1992],

một hợp đồng là một tập hợp các xác nhận mô tả chính xác mỗi đặc điểm của thành

phần phải làm gì và không phải làm gì. Xác nhận chính trong công nghệ thiết kế theo hợp đồng có 3 kiểu: Tính bất biến, tiền điều kiện và hậu điều kiện.

2.3. Tiền điều kiện, hậu điều kiện và tính bất biến

2.3.1. Tiền điều kiện và hậu điều kiện.

11

Tiền điều kiện và hậu điều kiện được sử dụng để định nghĩa ngữ nghĩa các phương thức. Chúng chỉ rõ nhiệm vụ được thi hành bởi một phương thức. Việc định nghĩa tiền điều kiện và hậu điều kiện cho một phương thức là cách để định nghĩa một hợp đồng, hợp đồng này ràng buộc phương thức và các lời gọi đến nó.

Tiền điều kiện mô tả sự ràng buộc mà với sự ràng buộc này, phương thức sẽ thực

hiện một cách đúng đắn. Đó là nghĩa vụ của bên thực hiện và là quyền lợi của bên cung cấp.

Hậu điều kiện diễn tả các thuộc tính từ kết quả thực hiện một phương thức. Đó là

nghĩa vụ của bên cung cấp và là quyền lợi của bên thực hiện

Ví dụ một hành động xóa bản ghi từ tập hợp cần có tiền điều kiện yêu cầu bản ghi với khóa chính phải tồn tại và hậu điều kiện yêu cầu bản ghi đó không được nhiều

hơn các yếu tố trong tập hợp đó

2.3.2. Tính bất biến

Tính bất biến ràng buộc gán các kiểu cần giúp cho đúng với các trường hợp của

kiểu mà hành động bắt đầu được biểu diễn trong trường hợp đó. Trong trường hợp của

các phương thức thành phần, chúng ta có thể gắn tính bất biến vào giao diện để xác

định thuộc tính của đối tượng thành phần thực thi giao diện. Ví dụ, tính bất biến có thể

nói rõ được giá trị của một vài thuộc tính luôn phải lớn hơn 0.

Điều kiện bất biến của lớp mô tả các ràng buộc toàn vẹn của lớp. Khái niệm này

quan trọng cho việc quản lý cấu hình và kiếm thử hồi quy vì nó mô tả xâu hơn đặc tính

của một lớp. Điều kiện bất biến của lớp được thêm vào với tiền điều kiện và hậu điều

kiện của mỗi phương thức của lớp:

{INV & P} A {INV & Q}

Công thức 4: Điều kiện bất biến trong công thức tính đúng đắn

INV là điều kiện bất biến được thêm vào. Điều này thể hiện rằng bất biến INV là

không thay đổi trước và sau khi thực hiện A.

2.4. Design By Contract trong Eiffel

Eiffel [4] hỗ trợ rất nhiều tính năng: tiếp cận hướng đối tượng hoàn thiện, khả

năng giao tiếp bên ngoài (có thể giao tiếp với các ngôn ngữ C, C++, Java,…), hỗ trợvòng đời phần mềm bao gồm việc phân tích, thiết kế, thực thi và bảo trì, hỗ trợ Design By Contract, viết xác nhận, quản lý ngoại lệ…

12

Design By Contract hầu như là vấn đề luôn được nhắc đến khi đề cập về Eiffel. Trong Eiffel, mỗi thành phần của hệ thống đều có thể được thực hiện theo một đặc tả tiên quyết về các thuộc tính trừu tượng của nó, liên quan đến những thao tác nội tại và những giao tác của nó với các thành phần khác.

Eiffel thực thi một cách trực tiếp ý tưởng Design By Contract, một phương pháp

làm nâng cao tính đáng tin cậy của phần mềm, cung cấp một nền tảng cho việc đặc tả, làm tài liệu và kiểm nghiệm phần mềm, cũng như việc quản lý các ngoại lệ và cách sử

dụng kế thừa thích hợp.

2.4.1. Biểu diễn Design by Contract trong Eiffel

 Precondition: Được thể hiện bằng từ khóa require

Ví dụ:

require

boolean expressions

Cần phải thỏa mãn biểu thức lô-gic boolean expressions trong mệnh đề require

trước mới có thể thực hiện tiếp thủ tục r ở sau đó.

 Postcondition: Được thể hiện bằng từ khóa ensure

Ví dụ:

ensure

boolean expressions

Sau khi thực hiện thủ tục r, kết quả trả về phải thỏa mãn biểu thức lô-gic boolean

expressions trong mệnh đề ensure

 Class invariant: Được thể hiện bằng từ khóa invariant

Ví dụ:

invariant

boolean expressions

Trong suốt quá trình thực hiện thủ tục r cần phải thỏa mãn biểu thức lô-gic

boolean expressions trong mệnh đề invariant

 Chỉ thị Check: Được thể hiện bằng cặp từ khóa check…end

Ví dụ:

check

assertion_clause1

13

assertion_clause2

assertion_clausen

end

 Loop invariant, loop variant

from

initialization

until

exit

invariant

inv

variant

var

loop

body

end

2.4.2. Ví dụ minh họa

Lấy ví dụ cho thuật toán put với công việc chèn một phần tử x vào từ điển với x

chứa một chuỗi các kí tự được coi như là khóa.

Put (x: ELEMENT; key: STRING)is

require

count <= capacity

notkey.empty

do

… Thuật toàn chèn…

ensure

has (x) item (key) = x count = old count + 1

14

end

Mệnh đề requie giới thiệu về điều kiện input, hoặc là tiền điều kiện; mệnh đề

ensure giới thiệu về điều kiện output hay còn gọi là hậu điều kiện. Cả hai điều kiện là ví dụ về sự xác nhận, hoặc điều kiện logic (mệnh đề hợp đồng) liên kết với thành phần

của phần mềm. Trong tiền điều kiện, biến count là số phần tử hiện thời và capacity là

số lượng lớn nhất có thể đưa vào; trong hậu điều kiện, has là hàm boolean để xem từ

đó có không, và item trả lại từ liên kết với khóa. Kí hiệu old count là giá trị count cũ.

Một ví dụ khác về cơ chế gửi tin.

send (m: MESSAGE)is

-- Gửi một tin nhắn m theo chế độ gửi nhanh nếu có thể,

nếu không sẽ chuyển sang chế độ gửi chậm.

local

tried_fast, tried_slow:BOOLEAN

do

if tried_fast then

tried_slow := True

send_slow (m)

else

tried_fast := True

send_fast (m)

end

rescue

if not tried_slow then

retry

end

end

15

Trong ví dụ này các giá trị logic ban đầu sẽ được khởi tạo là False. Nếu send_fast không thành công, phần thân của mệnh đề do sẽ được thực hiện lại. Còn nếu việc thực thi send_slow không thành công, mệnh đề rescue sẽ được thự hiện.

CHƯƠNG 3. Mô hình thành phần CORBA

3.1. Khái niệm cơ bản về công nghệ phần mềm hướng thành

phần

3.1.1. Giới thiệu

Có rất nhiều khái niệm cơ bản thường gặp về công nghệ phần mềm hướng thành

phần (CBSE) [8]. Các định nghĩa khác nhau có thể gây ra các nhầm lẫn vì CBSE là

một khái niệm mới mẻ. Nhiều khái niệm vẫn chưa hoàn toàn giải thích hoặc thử

nghiệm trong thực tế, và như một kệ quả, các định nghĩa của chúng vẫn còn rất mơ hồ.

CBSE cơ bản dựa vào khái niệm của thành phần. Các từ ngữ khác như giao diện,

hợp đồng, framework, và khuôn mẫu có liên quan chặt chẽ đến việc phát triển thành

phần phần mềm.

Một thành phần là một đơn vị có thể sử dụng lại của việc triển khai và cấu tạo

nên phần mềm. Một điểm chung ở đây là thành phần có mối quan hệ chặt chẽ với đối

tượng, vì thế, nó là một phần mở rộng của việc phát triển công nghệ hướng đối tượng.

Tuy nhiên, có nhiều nhân tố như chi tiết, khái niệm về cấu tạo và triển khai, thậm chí

cả quá trình phát triển, cũng phải phân biệt rõ thành phần và đối tượng.

Một giao diện quy định cụ thể các điểm truy cập đến thành phần một, và do đó

giúp khách hàng hiểu được chức năng và cách sử dụng của thành phần một. Giao diện

rõ ràng là tách ra từ việc thực hiện các thành phần một. Thực hiện đúng quy định, giao

diện một quy định cụ thể các thuộc tính chức năng của thành phần một. Một mô tả

hoàn toàn chức năng của thành phần là không đủ.

Một giao diện quy định cụ thể các điểm truy cập đến một thành phần, và do đó

giúp khách hàng hiểu dược chức năng và cách sử dụng của thành phần đó. Giao diện được tách hẳn ra từ việc thực hiện các thành phần. Theo như định nghĩa, một giao diện quy định cụ thể các thuộc tính, chức năng của một thành phần. Do đó, một mô tả về chức năng của một thành phần là không đủ.

Các đặc tả thành phần có thể thực hiện được thông qua một hợp đồng, trong đó tập trung vào việc đặc tả các điều kiện mà thành phần tương tác với môi trường của

nó. Mặc dù các component có thể có các kích cỡ khác nhau và các thành phần lớn

16

được chú trọng hơn cả. Một tập hợp các thành phần đóng một vai trò cụ thể sẽ được

chú trọng hơn là một thành phần đơn lẻ. Điều này dẫn đến khái niệm framework. Một

framework mô tả một đơn vị lớn của thiết kế và xác định mối quan hệ trong một nhóm nhất định của các yếu tố. Các yếu tố này có thể là những thành phần.

Khuôn mẫu xác định các giải pháp cho các vấn đề ở mức độ trừu tượng cao và

các cách sử dụng lại chúng. Khuôn mẫu thường bắt những đơn vị thiết kế nhỏ khi

được so sánh với framework, bởi vì framework bao gồm các khuôn mẫu thiết kế khác nhau.

3.1.2. Thành phần

Thành phần là trung tâm của CBSE và cần phải định nghĩa chính xác về thành phần để hiểu được cơ sở của CBSE. Chúng ta có thể tìm được vài định nghĩa của thành

phần trong nhiều tài liệu, phần lớn trong số chúng không có định nghĩa trực quan về

thành phần. Ví dụ trong công nghệ Component Object Model (COM) của Microsoft,

một thành phần được định nghĩa là: một bộ phận biên soạn nên phần mềm, cung cấp

nên một dịch vụ. Mọi người đều đồng ý rằngthành phần là một bộ phận của phần mềm

và nó rõ ràng là cung cấp một dịch vụ nhưng định nghĩa này còn quá rộng. Ví dụ như

biên dịch các thư viện (các file có đuôi .o và .dll) cũng có thể được định nghĩa theo

cách này.

Một đặc điểm quan trong nhất của thành phần là sự tách biệt giao diện của nó

trong sự thực thi. Sự tách biệt này khác với những gì chúng ta có thể tìm thấy ở nhiều

ngôn ngữ lập trình khác hoặc trong ngôn ngữ lập trình hướng đối tượng mà việc định

nghĩa lớp được tách biệtvới những lớp thực thi. Trong CBSE, các thành phần được yêu

cầu kết hợp lại trong phần mềm. Các thành phần kết hợp và triển khai phải tồn tại độc

lập và không cần phải biên dịch lại hoặc phải liên kết lại với phần mềm khi mà thêm

mới hoặc chỉnh sửa các thành phần khác. Một đặc điểm quan trọng nữa của thành phần

là khả năng thể hiện chức năng thông qua giao diện của nó. Ý nghĩa của nó là cần thiết

cho việc hoàn thiện các đặc tả của thành phần bao gồm các giao diện chức năng, đặc tính phi chức năng (hiệu suất, tài nguyên,…), ca sử dụng, kiểm thử…

3.1.3. Đối tượng và thành phần

Đối tượng và thành phần thường được nghĩ đến là đồng nghĩa hoặc tương tự nhau. Tác giả Szyperski và Pfister [8] đã xem thành phần như là tập hợp các đối tượng, mà các đối tượng này hợp tác chặt chẽ với nhau. Ranh giới giữa một thành phần với

các thành phần hoặc đối tượng khác được chỉ rõ và sự tương tác của thành phần được

17

thực thi qua các giao diện của thành phần trong khi các tính chất bên trong các thành

phần (ví dụ như các đối tượng của nó) được ẩn đi. Đối tượng trong một thành phầnđơn

lẻ có thể truy cập đến việc thực thi của thành phần khác. Tuy nhiên, sự truy cập đến việc thực thi của một đối tượng từ bên ngoài thành phần cần phải được ngăn chặn.

Thay vì chứa các lớp hoặc đối tượng, một component có thể chứa các thủ tục cổ

điển, các biến global (static), và do đó không những có thể thực hiện bằng cách tiếp

cận hướng đối tượng mà còn có thể tiếp cận theo hướng chức hoặc cách tiếp cận ngôn ngữ assembly. Tương tự như quan hệ thừa kế giữa các đối tượng, một component có

thể có một mối quan hệ với các thành phần khác. Một lớp cha của một lớp không cần

thiết phải ở trong component chứa lớp đó. Nếu một lớp trong component có lớp cha

trong một component khác, quan hệ thừa kế giữa các lớp xuất hiện tại ranh giới giữa các component.

D.Souza and Wills [8] thảo luận về sự khác biệt và giống nhau của đối tượng và

thành phần. Một câu hỏi quan trọng đặt ra là có khi nào một lớp trở thành một thành

phần hay không. Nếu một lớp được đóng gói cùng với các định nghĩa về giao giện rõ

ràng mà nó yêu cầu và thực hiện, thì lớp này sẽ được gọi là một thành phần. Giao diện

lập trình ứng dụng (API) là một đặc tả các thuộc tính của mô đun mà client phụ thuộc

vào. API của thành phần có sẵn ở dạng một hay nhiều cấu trúc giao diện (ví dụ: java

interfaces hoặc abstract virtual classes trong C++). Cũng tương tự như thế với lớp,

component có thể liên kết với các lớp khác. Nếu các lớp này tự chúng có đầy đủ các

định nghĩa API, tập hợp kết của của các lớp được thiết kế cấu tạo thành một

component.

Có 3 sự khác biệt quan trọng nhất dưới đây giữa component và đối tượng:

 Component thường sử dụng việc lưu trữ liên tục trong khi đối tượng lưu trữ

ở từng nơi từng vùng.

 Component có một bộ các cơ chế liên thông với nhau rộng hơn so với đối

tượng, trong đó thường sử dụng cơ chế gửi tin.

 Component thường là những đơn vị có tính chất lớn hơn các đối tượng và

có hành động phức tạp hơn ở những giao diện của chúng.

3.1.4. Giao diện

18

Một giao diện của component có thể được định nghĩa dưới dạng đặc tả của các điểm truy cập của nó. Các máy khách truy cập các dịch vụ cung cấp bởi thành phần sử dụng các điểm truy cập đó. Nếu thành phần có nhiều điểm truy cập, mỗi điểm sẽ tương

ứng với với các dịch vụ khác nhau được cung cấp bởi component, sau đó component

dự kiến sẽ có nhiều giao diện.

Điều chú ý quan trọng là một giao diện không cung cấp một sự thực thi của bất

kỳ hoạt động nào của nó. Thay vào đó, nó chỉ đơn thuần là tên của tập hợp các hành

động và cung cấp các mô vả và giao thức các hoạt động của nó. Đặc điểm này làm cho

nó có thể thay thế một phần thực hiện mà không phải thay đổi giao diện, và cách làm này cải thiện được hiệu năng hệ thống mà không phải xây dựng lại hệ thống; và thêm

một giao diện (và những sự thực thi) mà không phải thay đổi những sự thực thi đã có

và trong cách này cải thiện được khả năng tương thích của component.

Khách hàng tùy chỉnh các component bởi các phương tiện giao diện vì giao diện chỉ nhìn thấy được một phần. Lý tưởng nhất, trong giao diện, ngữ nghĩa của mỗi hành

động phải được xác định vởi bì đây là điều quan trọng cho cả sự thi hành của giao diện

và máy khách sử dụng giao diện. Trong phần lớn các mô hình component hiện tại,

giao diện định chỉ định nghĩa một cú pháp (ví dụ: kiểu đầu vào đầu ra) và đưa ra rất ít

thông tin về các component.

Giao diện được định nghĩa trong công nghệ component có thể diễn đạt các

functional properties. Function properties bao gồm một phần signature mà hành động

được cung cấp bởi một component đã được miêu tả, và một phần trạng thái mà trạng

thái của component được xác định.

Chúng ta có thể phân biệt hai loại giao diện. Các component có thể xuất và nhập

các giao diện cho và từ môi trường mà có thể bao gồm các component khác. Một giao

diện xuất ra ngoài miêu tả dịch vụ cung cấp bởi component ra môi trường, trong khi

một giao diện nhập vào xác định một dịch vụ yêu cầu bởi component từ môi trường.

Các phương pháp tiếp cận chung của các giao diện là cú pháp truyền thống. Tuy nhiên,

việc thực hiện các vấn đề ngữ cảnh liên quan đến ngữ cảnh phụ thuộc (tức là đặc tả

của môi trường triển khai và môi trường chạy) và sự tương tác cho biết sự cần thiết

của một hợp đồng rõ ràng xác định các hành vi của một component.

3.1.5. Hợp đồng

Hầu hết các kỹ thuật dùng để mô tả giao diện như IDL chỉ có quan tâm đến phần chữ ký, trong đó hành động được cung cấp bởi một thành phần được miêu tả và do đó không giải quyết các hành vi chung của các thành phần. Một đặc tả chính xác của các

hành vi của một thành phần có thể thực hiện một hợp đồng. Meyer đã đề cập, một hợp

19

đồng danh sách cácràng buộc chung mà thành phần sẽ duy trì gọi là tính bất biến. Mỗi

hành vi trong thành phần, hợp đồng đưa ra danh sách các điều kiện mà cần phải gắn

với bên thực hiện (tiền điều kiện) và các kết quả thành phần cần phải trả lại (hậu điều kiện). Tiền điều kiện, hậu điều kiện và tính bất biến hợp thành đặc tả những hành vi

của thành phần. Mở rộng hơn việc đặc tả cách hành vi của thành phần đơn lẻ, hợp

đồng có thể được dùng để quy định các tương tác giữa một nhóm các thành phần. Tuy

nhiên, chúng được sử dụng một cách khác nhau. Một hợp đồng quy định tương tác giữa các thành phần có những điều kiện sau:

 Có một tập những thành phần tham gia.

 Vai trò của mỗi thành phần thông qua các nghĩa vụ của hợp đồng, ví dụ như loại nghĩa vụ đòi hỏi các thành phần hỗ trợ các biến nhất định và giao diện, và

nghĩa vụ hệ quả đòi hỏi các thành phần thực hiện một chuỗi lệnh của hành

động, bao gồm việc gửi tin đến các thành phần khác.

 Tính biết biến được duy trì bởi các thành phần.

 Đặc tả các phương thức thuyết minh cho một hợp đồng.

Chú ý rằng các thành phần không chỉ cung cấp các dịch vụ cho các thành phần

khác mà còn đòi hỏi chúng từ các thành phần khác. Nó đúng cho cả yêu cầu chức năng

và yêu cầu phi chức năng. Đo đó, các nghĩa vụ hợp đồng có sự khác biệt đáng kể so với tiền điều kiện, hậu điều kiện của các phương thức được cung cấp bởi một thành

phần.

Tất cả hành vi của thành phần có thể khá phức tạp bởi vì nó tham gia trong nhiều

hợp đồng. Hơn nữa, hợp đồng chỉ rõ điều kiện mà trong đó tương tác giữa các thành

phần trong điều khoản của tiền điều kiện và hậu điều kiện về hoạt động. Tiền điều kiện

chỉ rõ các đặc điểm môi trường phải đáp ứng để hoạt động của hợp đồng có thể đáp

ứng hậu điềukiện. Đơn giản tiền điều kiện/hậu điều kiện về hoạt động thiết lập sự đúng

đắn cục bộ, trong khi để hoàn thiện sự đúng đắn tổng thể, sự chấm dứt là cần thiết. Bởi

vì hợp đồng được thiết kế để đại diện cho các tin nhắn, qua giao thức giữa các thành phần, chúng là bắt buộc trong tự nhiên và do đó khó diễn tả trong một hình thức khai báo

20

Cũng lưu ý rằng hợp đồng và giao diện là những khái niệm khác nhau. Giao diện là tập hợp các hoạt động chỉ rõ các dịch vụ được cung cấp bởi thành phần, hợp đồng chỉ rõ các hành vi bên ngoài của thành phần hoặc là tương tác giữa các thành phần khác nhau.

3.1.6. Khuôn mẫu

Kiến trúc sư Christopher Alexander [8] đã lần đầu tiên giới thiệu khái niệm về

khuôn mẫu vào cuối năm 1970. Trong khái niệm này, khuôn mẫu định nghĩa giải pháp

tuần hoàn cho các vấn đề tuần hoàn. Khuôn mẫu bắt những giải pháp không rõ ràng,

không chỉ là những nguyên tắc và chiến lược trừu tượng, một cách gián tiếp, với tính chất khác biệt với nhiều kỹ thuật giải quyết vấn đề khác (như là mẫu hoặc phương thức thiết kế phần mềm) mà giải pháp bắt nguồn từ nguyên tắc. Các giải pháp cần được

chứng minh để giải quyết vấn đề chứ không phải là lý thuyết hoặc suy đoán. Khuôn

mẫu mô tả mối quan hệ giữa cấu trúc hệ thống và cơ chế và không những là các mô đun độc lập. Cuối cùng, yếu tố con người là một phần của khuôn mẫu. Một khuôn mẫu

thiết kế có thể được dùng để miêu tả trong thiết kế và tài liệu của một thành phần. Một

thành phần, như một thực thể tái sử dụng, có thể được xem như một sự thi hành một số

khuôn mẫu thiết kế. Các khuôn mẫu thiết kế có thể được sử dụng để mô tả mức độ

thấp chi tiết sự thi hành của hành vi và cấu trúc của những thành phần, hoặc là mối

quan hệ giữa các thành phần trong bối cảnh của một ngôn ngữ lập trình cụ thể.

Khuôn mẫu đã được áp dụng cho các thiết kế của nhiều hệ thống hướng đối

tượng, và được coi là tái sử dụng những kiến trúc nhỏ góp phần vào một kiến trúc tổng

thể.

Mối quan hệ giữa các thành phần và khuôn mẫu thiết kế có thể được xem như

sau. Khuôn mẫu thiết kế được sử dụng rộng rãi trong quá trình thiết kế hệ thống dựa

thành phần, trong đó các đơn vị tái sử dụng phải được xác định. Việc sử dụng các

khuôn mẫu thiết kế làm cho nó dễ dàng hơn cho chúng ta công nhận những phần tái sử

dụng hoặc tìm chúng trong các thành phần từ trước hoặc phát triển chúng như là các

đơn vị tái sử dụng. Khuôn mẫu thiết kế có thể được sử dụng để mô tả hành vi của các

bộ phận bên trong thành phần và do đó được sử dụng để phát triển thành phần. Hơn

nữa, khuôn mẫu thiết kế không những được sử dụng để mô tả cấu tạo thành phần khi thiết kế một hợp đồng hoặc framework mà các liên kết các thành phần riêng biệt.

3.1.7. Frameworks

Nghĩa của CBSE khi xây dựng một phần mềm là: “đặt các phần lại với nhau”. Trong đó một môi trường là điều cần thiết để các phần đó có thể ghép lại với nhau. Framework là một phương tiện cung cấp một môi trường như vậy.

Framework có liên quan chặt chẽ đến khuôn mẫu. Chúng xác định một nhóm

21

những bên tham gia và các mối quan hệ giữa chúng mà có thể tái sử dụng trong bất kỳ

trạng thái nào. Szyperski [8] thấy rằng: so với khuôn mẫu, việc mô tả đơn vị của thiết

kế và chuyên biệt hơn khuôn mẫu. Một điển hình và thường được sử dụng là mô hình Model-View-Controller (MVC) trong đó xác định một thiết lập mà Model được trình

bày bởi View, và Controller quản lý các thao tác của người dùng. Framework cũng là

các đơn vị kiến trúc phù hợp để chia sẻ và tái sử dụng.

Framework cung cấp một giải pháp mạnh mẽ trong bối cảnh các thành phần tham gia có thể nối ghép một cách hiệu quả. Framework sử dụng ở đây là framework hướng

đối tượng và có hơi khác so với framework thành phần. Framework hướng đối tượng

trừu tượng hơn. Chúng là một phần của thiết kế và triển khai cho các ứng dụng trong

một miền cụ thể. Framework có trách nhiệm xử lý các tương tác phức tạp và các thành phần chỉ cần thực hiện đầy đủ vai trò của chúng trong framework.

3.1.8. Frameworks và thành phần

Theo như các định nghĩa framework trước đó, một framework được xem như là

một bảng mạch (framework thành phần) mà trong đó các vị trí trống đang chờ chèn

các thành phần. Framework được thuyết minh bằng cách lấp đầy những chỗ trống. Yêu

cầu được chỉ ra để cho biết những gì mà thành phần cần làm cho phù hợp với các chức

năng như những gì đã được quy định ở bảng mạch. Trong khái niệm về framework

chuẩn, chúng ta thấy rằng hành vi của framework có thể được đặc tả trong các điểu

khoản của tiền điều kiện và hậu điền kiện của framework, tính bất biến và sự thuyết

minh cũng như là các thành phần được tham gia và mỗi quan hệ tĩnh giữa chúng. Hai

vấn đề nữa là chuẩn hóa kết nối giữa các thành phần và xác định cụ thể hơn giao diện

các hành phần cần phải có để các framework bao quanh.

Các chỗ trống có thể được lập đầy bằng các thành phần hoặc các framework

khác. Các giao diện và các mối quan hệ giữa các thành phần được miêu tả. Các chi tiết

trong đặc tả vẫn còn được che dấu trong thành phần và cần tiếp thục như thế. Các

framework thành phần cần phải được lấp đầy bởi các thành phần và được thuyết minh theo cách này. Như framework được thuyết minh bởi thành phần, chính nó sẽ trở thành một thành phần mới để sử dụng trong các framework mới.

3.2. Khái niệm CORBA

3.2.1. Giới thiệu

Các ngôn ngữ lập trình đều có các điểm chung là các lời gọi hàm, thủ tục, tham

số truyền, trị trả về… Trong khi đó các đối tượng trong ngôn ngữ lập trình hướng đối

22

tượng thiết kế bằng ngôn ngữ nào thì chỉ có mã lệnh tương ứng của ngôn ngữ đó mới

truy xuất được chúng. Vậy làm sao các đối tượng được thiết kế bằng các ngôn ngữ lập

trình khác nhau có thể triệu gọi và sử dụng lẫn nhau? Các điểm chung của các ngôn ngữ lập trình được tập hợp lại trong ngôn ngữ đặc tả. Và CORBA là một ngôn ngữ đặc

tả.

CORBA là từ viết tắt của Common Object Request Broker Architecture và tạm

dịch là kiến trúc môi giới gọi các đối tượng phân tán.

CORBA còn được gọi là ngôn ngữ đặc tả giao tiếp (IDL – Interface Description

Language)

3.2.2. Ngôn ngữ đặc tả giao tiếp IDL

IDL [10] được sử dụng để mô tả các giao diện giữa các đối tượng CORBA. Ngôn

ngữ IDL là trung lập đối với ngôn ngữ thực hiện, nói cách khác, giao diện IDL có thể

được thực hiện trong bất kỳ ngôn ngữ nào chẳng hạn như Java, C, C + +, và một số

ngôn ngữ khác.

Ta lấy một ví dụ về đặc tả đối tượng Calculator bằng ngôn ngữ IDL của

CORBA:

 Tạo file Calculator.idl

interface Calculator {

long addNumber ( in long x, in long y );

};

 Để chuyển file đặc tả này sang các ngôn ngữ lập trình khác chúng ta có thể

dùng như sau:

idl2cpp Calculator.idl // chuyển sang C++

idlj Calculator.idl // chuyển sang java

 Kết quả là chúng ta có được tập tin CalculatorOperations.java như sau:

publicinterface CalculatorOperations{

int addNumber(int x, int y);

} //interface CalculatorOperations

23

Ánh xạ từ IDL sang java:

Bảng 3: Bảng ánh xạ từ IDL sang java

IDL Java

module package

interface interface

string java.lang.String

long int

long long long

float float

double double

exception class

operation Method

 CORBA IDL:

module {

interface MathLibrary {

long add( in long x, in long y );

string About( in string version );

}

};

 Java :

package Math;

publicinterface MathLibrary {

int add (int x, int y);

String About(String version);

24

}

Ngôn ngữ đặc tả trong mô hình CORBA gần giống với ngôn ngữ C.

CORBA đưa ra từ khóa in cho các biến truyền vào theo trị và từ khóa out để lấy

trị trả về.

3.3. Mô hình thành phần CORBA

Mô hình thành phần CORBA (CCM) là đặc tả thành phần gần đây nhất và được

hoàn thiện từ đặc tả OMG (Object Management Group). Nó được thiết kế dựa trên cơ sở tích lũy kinh nghiệm sử dụng dịch vụ CORBA, JavaBeans, và EJB [12]

Giống như nhiều mô hình thành phần khác, CCM tập trung vào các nhà phát triển

ứng dụng bằng cách ghép các mô-đun có sẵn, mà còn rõ ràng với việc thiết kế thành

phần, lắp ráp và triển khai. Mục đích chính đằng sao đặc tả CCM là cung cấp giải pháp

cho sự phức tạp của CORBA và những dịch vụ của nó. Trọng tâm của CCM là “một

mô hình thành phần phía máy chủ cho việc xây dựng và phát triển ứng dụng CORBA”

Một trong những lợi ích của CCM là sự cố gắng “hợp nhất” các mặt được bao

gồm trong kĩ nghệ phần mềm. Kết quả là một ứng dụng phần mềm được mô tả trong

các hình thức khác nhau theo 2 chiều: chiều thời gian (vòng đời, từ thiết kế đến triển

khai) và chiều trừu tượng (từ khái niệm trừu tượng đến thi hành). Nhìn chung, điều

này đã làm cho các đặc tả khá phức tạp.

Với CCM, một thành phần là “một đơn vị mã phần mềm độc lập bao gồm dữ liệu

và sự logic của nó, cùng với định nghĩa về kết nối được xác định rõ ràng hoặc giao

diện tiếp xúc về liên lạc. Nó được thiết kế để có thể sử dụng lặp lại trong phát triển

ứng dụng, có thể có hoặc không có các tùy biến”

3.3.1. Giao diện và sự nối ghép

Cái nhìn từ bên ngoài của một thành phần là một phần mở rộng của ngôn ngữ

25

CORBA IDL truyền thống. Một giao diện thành phần được tạo bởi các cổng được chia thành từng phần một [12]

Hình 1: Giao diện thành phần CORBA và các cổng

Thành phần được coi như là một hộp đen. Giao diện chỉ là các điểm truy cập đến

thành phần và đặc tả của thành phần trở thành đặc tả của giao diện thành phần.

Thành phần hỗ trợ nhiều tính năng bên ngoài mà khách hàng và các thành phần khác của môi trường ứng dụng có thể tương tác với thành phần. Các đặc tính bên

ngoài đó được gọi là các cổng. Mô hình thành phần hỗ trợ 4 loại cổng chính là:

 Facets: được đặt tên cho giao diện được cung cấp bởi thành phần cho các

tương tác của bên khách hàng.

 Receptacles: được đặt tên cho điểm kết nối miêu tả khả năng của thành phần sử dụng sự tham khảo được hỗ trợ bởi một vài tác nhân bên ngoài.

 Event sources: được đặt tên cho điểm kết nối mà phát ra các sự kiện của một kiểu lý thuyết tới một hoặc nhiều sự kiện người dùng quan tâm hoặc tới

một kênh sự kiện.

 Event sinks: được đặt tên cho điểm kết nối vào mà sự kiện của một kiểu lý

thuyết có thể được đẩy vào.

CCM xem các cổng như là các biến được đặt tên và đặt kiểu, do đó các facets

26

khác nhau của cùng một thành phần có thể có các kiểu giống nhau. Các thành phần được đặt kiểu và có thể kế thừa từ các thành phần khác.

3.3.2. Đặc tả CCM bằng ngôn ngữ IDL 3.3.2.1. Thành phần

Thành phần được dùng với từ khóa component.

Giao diện tương đương được hỗ trợ bởi các thành phần có thể kế thừa từ một số

giao diện người dùng tự định nghĩa. Mối quan hệ này được thể hiện bằng cách sử dụng từ khóa supports.

Ví dụ:

interface Clock {

Time getTime ();

void ResetTime (in Time t);

};

component Car supports Clock {};

3.3.2.2. Facets

Facets tương ứng với giao diện được cung cấp bởi một thành phần. Facets được

dùng với từ khóa provides.

component XXX {

provides ;

};

Ví dụ:

module motors {

interface Engine{};

interface Panel {};

component Car supports Clock{

provides Engine _engine;

provides Panel_panel;

};

27

};

3.3.2.3. Receptacles

Tương ứng với giao diện được yêu cầu bởi thành phần chức năng trong một môi

trường nhất định.

Receptacle được dùng với từ khóa uses

 Receptacle đơn

Có thể kết nối đến một đối tượng,

component XXX {

uses ;

};

Ví dụ:

interface Customer {};

component Account {

uses Customer owner;

};

 Nhiều receptacle

Có thể kết nối với nhiều đối tượng.

component XXX {

usesmultiple ;

};

Ví dụ:

component Account {

usesmultiple Customer owner;

};

3.3.2.4. Event Sources

Từ khóa publishes được sử dụng để định nghĩa event sources. Từ khóa này chấp

28

nhận kết nối 1 – n

component XXX {

publishes ;

};

Ví dụ:

module stockbroker {

eventtype AlertSignal{

public string reason;

};

component Broker {

publishes AlertSignal alert_source;

};

};

Từ khóa emits chấp nhận kết nối 1- 1

component XXX {

emits ;

};

Ví dụ:

module stockbrocker {

eventtype StockLimit {

public long stock_value;

};

component Broker {

emits StockLimit limitAlert;

};

29

};

3.3.2.5. Event Sinks

Event sink được dùng với từ khóa consumes.

component XXX {

consumes ;

};

Ví dụ:

module stockbrocker {

eventtype AlertSignal {

public string reason;

};

component Trader {

consumes AlertSignal alert_sink;

};

};

3.3.3. Điều kiện kết nối

Để các thành phần trong CCM có thể kết nối được với nhau nếu các cổng của

chúng thỏa mãn một số điều kiện chính sau:

 Facet có thể chỉ kết nối với receptacles (cổng provideschỉ kết nối với

cổng uses)

 Event source chỉ có thể kết nối với event sinks (nói cách khác: cổng

publishes và cổng emitschỉ có thể kết nối với cổng consumes).

 Mỗi cổng provides(facet) có

thể kết nối với nhiều cổng uses(receptacles), mỗi cổng publishes có thể kết nối với nhiều cổng consumesnhưng không thể ngược lại.

 Mỗi cổng emitschỉ có thể kết nối với một cổng consumes.

30

 Với mỗi một cặp cổng đã được kết nối, kiểu của cổng cung cấp (facets, event sources) là kiểu con của một trong những cổng yêu cầu (receptacles, event sinks)

CHƯƠNG 4.

Xây dựng công cụ đặc tả và kiểm chứng thành phần

4.1. Mô tả công cụ

Công cụ về đặc tả và kiểm chứng hỗ trợ người dùng kiểm tra sự phù hợp của các

thành phần khi kết nối với nhau.

Đặc điểm nổi bật của ứng dụng bao gồm:

- Môi trường giao diện trực quan sinh động giúp cho người dùng có khả năng tạo ra các thành phần, các cổng mà không cần thiết phải có hiểu biết sâu về

các ngôn ngữ đặc tả như Eiffel hay IDL.

- Ứng dụng được phát triển trên nền Java nên có thể chạy độc lập trên các môi

trường khác.

4.2. Ngôn ngữ phát triển công cụ

Ngôn ngữ được lựa chọn để phát triển ứng dụng là ngôn ngữ Java. So với một số

ngôn ngữ khác, nó có cách ưu điểm:

- Hiệu suất cao. - Có tính hướng đối tượng cao. - Dễ học, dễ sử dụng nên những người sử dụng sau có thể tiếp tục phát triển ứng

dụng một cách dễ dàng.

- Môi trường làm việc thân thiện. - Có thể chạy độc lập trên mọi môi trường.

4.3. Phân tích công cụ đặc tả và kiểm chứng thành phần 4.3.1. Mô tả công cụ

Công cụ phải có các chức năng sau:

 Vẽ được các thành phần và các cổng trên thành phần đó.

 Điền thông tin chi tiết cho các thành phần và các công mỗi khi tạo mới.

 Kiểm tra được sự kết nối của các cổng trong các thành phần. Phát hiện

lỗi kết nối khi không thỏa mãn điều kiện.

 Chức năng vào ra dữ liệu: người dùng có thể lưu lại phần mình đã làm và

31

tạm dừng để có thể làm tiếp vào phiên làm việc sau.

4.3.2. Mô hình hoạt động

Ứng dụng được thiết kế theo mô hình Model - View - Controller (MVC)

Hình 2: Mô hình MVC

Một đối tượng đồ họa (GUI Component) bao gồm 3 thành phần cơ bản: Model,

View, và Controller. Model có trách nhiệm đối với toàn bộ dữ liệu cũng như trạng thái

của đối tượng đồ họa. View chính là thể hiện trực quan của Model, hay nói cách khác

chính là giao diện của đối tượng đồ họa. Và Controller điều khiển việc tương tác giữa

đối tượng đồ họa với người sử dụng cũng như những đối tượng khác.

Khi người sử dụng hoặc những đối tượng khác cần thay đổi trạng thái của đối tượng đồ họa, nó sẽ tương tác thông qua Controller của đối tượng đồ họa. Controller sẽ

thực hiện việc thay đổi trên Model. Khi có bất kỳ sự thay đổi nào ở xảy ra ở Model, nó

sẽ phát thông điệp (broadcast message) thông báo cho View và Controller biết. Nhận

được thông điệp từ Model, View sẽ cập nhật lại thể hiện của mình, đảm bảo rằng nó

luôn là thể hiện trực quan chính xác của Model. Còn Controller, khi nhận được thông

điệp từ Model, sẽ có những tương tác cần thiết phản hồi lại người sử dụng hoặc các

đối tượng khác.

Trong ứng dụng này, các tệp chứa class về các cổng nằm trong Model. Các tệp

chứa class giao diện nằm trong View, tệp Contract.java được nằm trong Controller. Model quản lý trạng thái thông tin của các thành phần và các cổng. Viewer thể hiện các thành phần và cổng đó ra ngoài khung hiển thị của ứng dụng. Còn Controller kiểm tra việc liên kết các cổng của các thành phần đó.

4.3.3. Thiết kế các lớp và đối tượng

Căn cứ vào các đối tượng tham gia vào quá trình kiểm chứng, chúng tôi đưa ra

32

các lớp đối tượng như sau:

Bảng 4: Các lớp đối tượng trong ứng dụng

STT Tên lớp Mô tả

01 canvaspanel Lớp đối tượng dùng để vẽ đối tượng

02 component Lớp chứa các thành phần

03 port Lớp cha chứa các thông tin chung của các cổng

04 attribute Lớp chứa thông tin cổng attribute

05 facets Lớp chưa thông tin cổng facets

06 receptacles Lớp chưa thông tin cổng receptacles

07 eventsources Lớp chứa thông tin cổng event source

08 eventsinks Lớp chứa thông tin cổng event sinks

09 inout Lớp vào ra dữ liệu

10 contract Lớp xử lý kết nối của các cổng

4.3.3.1. Sơ đồ tương tác giữa các đối tượng

33

Tương tác giữa các đối tượng đó được thể hiện trong sơ đồ lớp dưới đây:

Hình 3: Sơ đồ lớp thể hiện mối liên hệ giữa các đối tượng trong ứng dụng

Các cổng được thừa kế từ lớp port được thể hiện trong sơ đồ dưới đây:

34

Hình 4: Sơ đồ lớp thể hiện mối quan hệ kế thừa của các cổng

4.3.3.2. Mô tả chi tiết các lớp đối tượng

 Lớp component:

Hình 5: Lớp Component

Bảng 5: Chi tiết lớp component

STT Thuộc tính Kiểu dữ liệu Phạm vi Mô tả

01 id private Mã thành phần int

02 name string private Tên của thành phần

int 03 x private Tọa độ x của thành phần khi vẽ

int 04 y private Tọa độ y của thành phần khi vẽ

 Lớp port:

35

Hình 6: Lớp port

Bảng 6: Chi tiết lớp port

STT Thuộc tính Kiểu dữ liệu Phạm vi Mô tả

Mã thành phần mà cổng nằm 01 idComponent int private trên đó

02 name string private Tên cổng

Loại cổng. Có thể là facets, receptacles, event sinks hoặc 03 type int private

event sources

 Lớp canvaspanel

Hình 7: Lớp canvaspanel

Bảng 7: Chi tiết lớp canvaspanel

STT Thuộc tính Kiểu dữ liệu Phạm vi Mô tả

01 label JLabel private Dùng để vẽ ảnh các thành phần, và các cổng

02 images images private Load ảnh các thành phần và các cổng

36

Kiểm tra điều kiện kết nối giữa 03 contract Contract private các cổng của các thành phần

 Lớp Contract

Hình 8: Lớp Contract

Bảng 8: Chi tiết lớp Contract

STT Thuộc tính Kiểu dữ liệu Phạm vi Mô tả

01 namePort1 String private Tên cổng thứ 1

02 namePort2 String private Tên cổng thứ 2

4.4. Triển khai

Ứng dụng được phát triển bằng ngôn ngữ Java nên cần phải cài đặt JDK trước khi

chạy chương trình.

- Tải jdk tại địa chỉ: http://java.sun.com/javase/downloads/widget/jdk6.jsp - Chọn hệ điều hành tương ứng rồi click vào nút download. - Bắt đầu chạy ứng dụng.

4.5. Thử nghiệm 4.5.1. Bài toán

Giả sử chúng ta có một hệ thống Stock Quoter (Hình 9) [5] Đây là một hệ thống

37

phức tạp với nhiều thành phần kết nối với nhau.

Hình 9: Kiến trúc CCM của hệ thống Stock Quoter.

Để có thể giới thiệu công cụ một cách dễ hiểu với người đọc, chúng ta sẽ tiếp cận

với hệ thống đơn giản trước. Hệ thống Stock Quoter đơn giản gồm 2 thành phần với

các cổng notifier_out, notifier_in, quoter_info_out, quoter_info_in (Hình 10) [12]

Hình 10: Giao diện thành phần CORBA và các cổng.

Hình vẽ minh họa hệ thống Stock Quoter bằng cách sử dụng mô hình thành phần

CORBA. Thành phần Stock Distributor biểu diễn hệ cơ sở dữ liệu chứng khoán thời gian thực. Khi các giá trị của cổ phiếu thay đổi, nó đẩy một eventype có chứa tên cổ phiếu thông qua một cổng event source (notifier_out) đến cổng event sink (notifier_in) tương ứng của một hoặc nhiều thành phần Stock Broker khác. Nếu các thành phần

38

StockBroker này cần những thông tin khác của cổ phiếu, chúng có thể yêu cầu một hành động thông qua cổng receptacle (quoter_info_in) của thành phần StockBroker đến cổng facets (quoter_info_out) của thành phần StockDistributor.

Dưới đây là sự thực thi của thành phần StockBroker và StockDistributor. Các

cổng được định nghĩa như sau:

component StockBroker {

consumesStockName notifier_in;

usesStockQuoter quoter_info_in;

};

component StockDistributor supports Trigger {

publishesStockName notifier_out;

providesStockQuoter quoter_info_out;

attributelong notification_rate;

};

Thành phần StockBroker chứa hai cổng tương ứng với hai chức năng mà nó thực

hiện. Một eventtype gọi là notifier_in sẽ tiếp nhận thông tin từ thành phần

StockDistributor khi giá trị cổ phiếu thay đổi. Ở hình trên, cổng notifier_in được kết

nối với cổng notifier_out của thành phần StockDistributor khi kiến trúc CCM được

triển khai và cấu hình công cụ khi ứng dụng được thực hiện. Nó sử dụng giao diện

StockQuoter được cung cấp bởi thành phần StockDistributor mà báo cáo thông tin về

cổ phiếu như giá cổ phiếu tăng hay giảm hay giá trị giao dịch của cổ phiếu trong ngày.

Thành phần StockDistributor xuất một eventtype được gọi là notifier_out để đẩy

thông tin về thành phần StockBroker khi mà giá trị cổ phiếu thay đổi. Ngoài ra, nó

còng định nghĩa một cổng facet được gọi là quoter_info_out trong đó chứa các thông

tin thêm về một cổ phiếu cụ thể. Tiếp theo, thành phần này còn định nghĩa một thuộc

tính attribute có tên là notification_rate mà quản trị hệ thống có thể sử dụng để kiểm

soát tốc độ của thành phần StockDistributor, cơ sở dữ liệu bảng giá cổ phiếu và đẩy

những thay đổi cho thành phần StockBroker để người dùng có thể theo dõi trực tiếp.

39

Sau quá trình phân tích, thiết kế, lập trình và kiểm thử chúng tôi đã xây dựng (mặc dù chưa hoàn thiện) ứng dụng đặc tả và kiểm chứng. Dưới đây là một số giao diện của ứng dụng

4.5.2. Giao diện khởi động chương trình

Hình 11: Giao diện khởi động ứng dụng

Giao diện khởi động chương trình bao gồm thanh menu File, Edit, View…

Thanh công cụ dùng để thêm các thành phần và các cổng ở bên trái chương trình. Bên

phải là panel thể hiện những hình vẽ mà người dùng vẽ ra. Ở dưới là khung hiển thị

các bước làm của người dùng. Thông báo kết quả các cổng của thành phần có kết nối

40

được hay không.

4.5.3. Giao diện khi làm việc với các thành phần

Hình 12: Giao diện điền thông tin khi thêm mới 1 thành phần

Khi chọn nút vẽ thành phần, giao diện để điền thông tin cho component được

khởi tạo. Người dùng điền tên thành phần vào khung Name, sau đó chọn OK để hoàn

thành. Nếu không cần tạo thành phần nữa thì click vào nút Cancel để bỏ qua.

Sau khi tạo thành công, mô hình thành phần sẽ được thể hiện như hình vẽ 13.

41

Dưới đây là 3 thành phần được đặt tên là Stock Distributor, Stock Broker.

Hình 13: Giao diện kết quả sau khi thêm một thành phần thành công

4.5.4. Giao diện làm việc với các cổng

Sau khi tạo thành công các thành phần, người dùng có thể tạo các cổng cho từng

thành phần bằng cách click vào nút khởi tạo cổng ở thanh công cụ bên tay trái cửa sổ.

Sau khi chọn vị trí cho cổng trên thành phần, giao diện điền thông tin cho cổng hiện

42

lên, bao gồm tên cổng, tên kiểu, tên kiểu cha nếu có kế thừa. (Hình 14)

43

Hình 14: Giao diện điền thông tin khi thêm một cổng mới

Hình 15: Giao diện kết quả khi thêm mới cổng thành công

Sau khi tạo cổng thành công, màn hình sẽ hiện lên như sau (Hình 15).

Ở đây, cổng có tên là: notifier_out, quoter_info_out… được tạo trên Stock

Distributor.

44

Các cổng notifier_in và quoter_info_in được tạo trên Stock Broker.

4.5.5. Giao diện sau khi kiểm chứng kết nối giữa các thành phần

Hình 16: Giao diện khi kết nối thành công các cổng

Sau khi tạo các thành phần và các cổng thành công. Người dùng có thể kết nối

các cổng của các thành phần với nhau để kiểm tra bằng cách click vào biểu tượng kết

nối trên thanh công cụ, click chuột vào cổng thứ nhất và di đến cổng thứ hai là cổng

cần kết nối.

45

Sau khi kết nối, chương trình sẽ kiểm tra đặc tả của các cổng mà người dùng đã điền ở trên và kiểm tra với các điều kiện kết nối. Nếu thỏa mãn, kết nối thành công và được thể hiện ở hình 16. Trái lại, nếu không thành công, chương trình sẽ hiện lên bảng thông báo như hình 17 (Xem lại các điều kiện kết nối phần 3.3.3 trang 30).

46

Hình 17: Giao diện khi kết nối không thành công các cổng

Kết luận

Qua quá trình nghiên cứu và thực hiện khoá luận, chúng tôi nhận thấy đã đạt

được một số kết quả chính sau:

- Nắm bắt được khá rõ các nền tảng cần thiết để có thể nhìn gần hơn về một hệ thống phần mềm đúng đắn và bền vững. Nói một cách dễ hiểu, phần mềm

đúng đắn là phần mềm có ít lỗi và xử lý được những lỗi bất thường xảy ra

trong phần mềm trong lúc làm việc. Như thế, phần mềm mới có khả năng tồn

tại lâu dài với thời gian và được người dùng ưa chuộng.

- Hiểu khá rõ về công nghệ Design ByContract và khả năng ứng dụng của nó trong lập trình hướng đối tượng. Một hệ thống phần mềm được xem như là tập

hợp các thành phần có các giao tiếp tương tác với nhau dựa trên định nghĩa

chính xác của các giao ước trong hợp đồng. Phải thỏa mãn những giao ước đó

thì các thành phần mới có thể liên kết với nhau để tạo nên sự chính xác, tính

đúng đắn cho phần mềm. Ngoài ra, công nghê này còn cung cấp một công cụ

rất tốt cho việc viết tài liệu phát triển cho phần mềm, dễ dàng phát hiện và gỡ

lỗi.

- Xây dựng một công cụ đặc tả và kiếm chứng cho sự liên kết của các thành phần bằng ngôn ngữ Java. Khi sử dụng ứng dụng này, một cách trực quan,

người dùng nhanh chóng vẽ ra các thành phần cùng với các cổng.

- Ngoài ra chúng tôi đã trình bày một số khía cạnh của đặc tả thành phần, vạch ra phương pháp tiếp cận với cách giao tiếp của thành phần dựa trên các loại

cổng được kết nối. Chúng tôi đã xác định các ràng buộc về cổng, nhờ đó,

chúng ta có thể biết được các thành phần có thể kết nối được với nhau nếu

chúng đáp ứng được những yêu cầu mà chúng tôi đã nêu ở trên. Ở mức độ

47

này, chúng tôi mới chỉ nghiên cứu đến các loại cổng (facet, receptacle, event source, event sink) và các ràng buộc về loại cổng. Chúng tôi đã xác minh điều kiện kết nối của các loại cổng và tích hợp chúng với nhau để hỗ trợ cho phương pháp tiếp cận của chúng tôi. Điều này sẽ ủng hộ chúng tôi trong việc xác minh tính tương thích giữa các thành phần bởi các đặc tả hành vi ở mức độ ngữ nghĩa.

Hướng phát triển

Trong thời gian tới, chúng tôi sẽ tiến hành kiểm tra thành phần cấu tạo giữa các

hành vi của các cổng khi kết nối thành công giữa các loại cổng.

Sau đó chúng tôi sẽ nâng cấp ứng dụng hiện tại để có thể hỗ trợ tốt hơn việc đặc tả và kiểm chứng cho công đoạn kết nối các thành phần của phần mềm hướng thành

48

phần này.

Tài liệu tham khảo

Tài liệu tham khảo tiếng Việt

[1] Nguyễn Thanh Bình - Đặng Thị Lệ Thu. Giải pháp nâng cao chất lượng phần mềm

hướng đối tượng. Tạp chí khoa học và công nghệ, Đại học Đà Nẵng. Số 5(28).2008.

Tài liệu tham khảo tiếng Anh

[2] A. M. Zaremski and J. M. Wing. Specification matching of software components.

333–369, 1997.

[3] B. Meyer. Design By Contract, in Advances in Object-Oriented Software Engineering. Prentice Hall. 1991.

[4] B. Meyer. Eiffel: The Language. Prentice Hall. 1992.

[5] Bala Natarajan, Douglas C. Schmidt, and Steve Vinoski. The CORBA Component

Model. http://www.drdobbs.com/cpp/184403888. September 01, 2004

[6] Boodhoo, Jean-Paul. Design Patterns: Model View Controller. Retrieved 2009-07-

07.

[7] C.A.R Hoare. An axiomatic basis for computer programming. Communications of

the ACM. 1969.

[8] Ivica Crnkovic - Magnus Larsson. Building Reliable Component-Based Software

Systems. Artech house, Inc. 2002. tr.3-18 và tr.73-76.

[9] Frank Pilhofer. Writing and Using CORBA Components. Technology report, FPX.

04/2002.

[10] Jeremy Rosenberger. Teach Yourself CORBA In 14 Days

[11] Jonas Bergström. Design By Contract for Java. http://c4j.sourceforge.net/.

[12] Tran Thi Mai Thuong - Vo Van Thanh - Truong Ninh Thuan. Checking the conformability in CORBA component model specifications. Journal of Science, Natural Sciences and Technology. 2008.

49

[13] Yi Liu - H. Conrad Cunningham. Software Component Specification Using Design by Contract. National Defense Industry Association. 04/2002.

Phụ lục (Hướng dẫn sử dụng chương trình)

Sau khi cài đặt môi trường jre cho java. Người dùng có thể click vào file chạy

chương trình để chạy công cụ (Hình 11)

Đầu tiên để vẽ một thành phần, người dùng có thể click vào nút có biểu tượng sau đó di chuột sang màn hình bên phải để vẽ. Chương trình sẽ hiện lên bảng đòi

người dùng phải điền đầy đủ thông tin cho thành phần. Sau khi hoàn thành thao tác,

click vào nút ok để vẽ hoặc click vào nút cancel để bỏ qua không vẽ nữa.

Để có thể vẽ các cổng cho thành phần, người dùng click vào nút có các biểu

, , , ,

tượng tương ứng với các cổng attribute, facet, receptacle, event source, event sinks. Chú ý, các cổng nằm trên thành phần nên khi vẽ, người dùng phải

click vào phạm vi bên trong thành phần, nếu không sẽ có thông báo lỗi hiện ra ngăn

cấm việc vẽ các cổng. Chương trình sẽ hiện lên khung bắt buộc người dùng điền thông

tin cho các cổng đó. Khung thông tin bao gồm ô điển tên cổng, kiểu của cổng, và tủy

chọn xem kiểu của cổng đó có kế thừa kiểu nào khác của một cổng nào đó khác hay

không. Sau khi hoàn thành thao tác, người dùng click vào ok để vẽ cổng hoặc click

vào cancel để bỏ qua không vẽ cổng nữa.

Sau khi vẽ xong các thành phần và các cổng, người dùng có thể click vào nút có

để tiến hành kết nối các cổng của các thành phần. Người dùng click biểu tượng chuột vào 1 cổng bất kỳ và giữ lỳ chuột, di đến cổng thứ 2 cần kết nối, sau đó thả

chuột ra. Chương trình sẽ kiểm tra các điều kiện kết nối (xem lại mục 3.3.3). Nếu

không thỏa mãi một trong 5 điều kiện đã nên ở trên, sẽ có một bảng thông báo kết nối

không thành công kèm theo lỗi xảy ra ở điều kiện nào. Sau khi người dùng xác nhận,

phần kết nối sẽ tự động được xóa đi.

Ngoài ra người dùng có thể dùng thêm một số chức năng phụ như tạo mới một

bản đặc tả mới bằng cách vào menu File → New.

50

Nếu người dùng kết nối sai cổng (nhưng vẫn thỏa mãn điều kiện) thì có thể sử dụng chức năng undo hoặc redo bằng cách vào menu Edit → Undo hoặc Edit → Redo.