Đăng ký Đăng nhập

Tài liệu Lập trình hệ thống

.PDF
371
329
55

Mô tả:

LẬP TRÌNH HỆ THỐNG Biên tập bởi: Khoa CNTT ĐHSP KT Hưng Yên LẬP TRÌNH HỆ THỐNG Biên tập bởi: Khoa CNTT ĐHSP KT Hưng Yên Các tác giả: Khoa CNTT ĐHSP KT Hưng Yên Phiên bản trực tuyến: http://voer.edu.vn/c/92c88426 MỤC LỤC 1. Bài 1: TỔNG QUAN VỀ LẬP TRÌNH HỆ THỐNG 1.1. Khái niệm về lập trình hệ thống 1.2. Tổng quan về lập trình hệ thống 1.3. Lịch sử về lập trình hệ thống 1.4. Cấu trúc tổng quan lập trình hệ thống 2. Bài 2: CÔNG CỤ LẬP TRÌNH HỆ THỐNG 2.1. Các ngôn ngữ lập trình 2.2. Giới thiệu về C++ 2.3. Giới thiệu về Visual C++ 3. Bài 3: THỰC HÀNH MỘT SỐ BÀI TẬP CƠ BẢN TRÊN C++ 3.1. Thực hành một số bài tập cơ bản trên C++ 4. Bài 4: CƠ BẢN VÀ CẤU TRÚC VỀ DRIVER 4.1. Tóm lược lịch sử các bộ điều khiển thiết bị 4.2. Tổng quan về các Hệ điều hành (An Overview of the Operating Systems) 4.3. Các kiểu Driver 4.4. Tổng quan về quản lý và kiểm tra danh sách 5. Bài 5: THỰC HÀNH MỘT SỐ BÀI TẬP CƠ BẢN TRÊN VC++ 5.1. Thực hành một số bài tập cơ bản trên VC++ 6. Bài 6: CÁC KỸ THUẬT LẬP TRÌNH CƠ BẢN 6.1. Môi trường lập trình kiểu Kernel – Mode 6.2. Trình bày lỗi (Lỗi xử lý) 6.3. Quản lý bộ nhớ (Memory Management ) 6.4. Trình bày chuỗi (String Handling) 6.5. Kỹ thuật lập trình hỗn hợp (Miscellaneous Programming Techniques ) 7. Bài 7: THỰC HÀNH MỘT SỐ BÀI TẬP TRÊN VC++ 7.1. Thực hành một số bài tập cơ bản trên Visual C++ 8. Bài 8: LẬP TRÌNH GIAO TIẾP QUA CỔNG LPT 8.1. Giới thiệu cổng LPT 8.2. Cấu trúc cổng LPT 9. Bài 9: THỰC HÀNH VỚI CÁC CHƯƠNG TRÌNH GIAO TIẾP QUA CỔNG LPT 9.1. Thực hành với các chương trình giao tiếp qua cổng LPT 10. Bài 10: THỰC HÀNH VỚI CÁC CHƯƠNG TRÌNH GIAO TIẾP QUA CỔNG COM 10.1. Giới thiệu cổng COM 1/369 10.2. Cấu trúc cổng COM 11. Bài 11: THỰC HÀNH VỚI CÁC CHƯƠNG TRÌNH GIAO TIẾP QUA CỔNG COM 11.1. Thực hành với các chương trình giao tiếp qua cổng COM 12. Bài 12: VẤN ĐỀ ĐỒNG BỘ 12.1. Vấn đề đồng bộ hóa nguyên mẫu (An Archetypal Synchronization Problem ) 12.2. Mức yêu cầu Ngắt (Interrupt Request Level ) 12.3. Khóa xoay vòng (Spin Locks ) 12.4. Các đối tượng Kernel Dispatcher (Kernel Dispatcher Objects ) 12.5. Một số phương pháp đồng bộ khác (Other Kernel-Mode Synchronization Primitives ) 13. Bài 13: THỰC HÀNH LẬP TRÌNH DRIVER CƠ BẢN 13.1. Thực hành lập trình driver cơ bản 14. Bài 14: GÓI DỮ LIỆU VÀO RA 14.1. Các cấu trúc dữ liệu (Data Structures ) 14.2. Hàng đợi yêu cầu Vàora (Queuing IO Requests) 14.3. Hủy bỏ yêu cầu vàora (Cancelling IO Requests ) 14.4. Tóm lược các kịch bản xử lý (Summary—Eight IRP-Handling Scenarios) 15. Bài 15: THỰC HÀNH LẬP TRÌNH DRIVER CHO XỬ LÝ IRP 15.1. Thực hành một số bài lập trình driver cơ bản 16. Bài 16: ĐỌC VÀ GHI DỮ LIỆU 16.1. Cấu hình thiết bị của bạn (Configuring Your Device ) 16.2. Địa chỉ một Bộ đệm dữ liệu (Addressing a Data Buffer ) 16.3. Các cổng và các thanh ghi (Ports and Registers ) 16.4. Phục vụ ngắt (Servicing an Interrupt ) 16.5. Truy nhập bộ nhớ trực tiếp (Direct Memory Access ) 17. Bài 17: ĐIỀU KHIỂN VÀO/RA VÀ HÀM ĐIỀU KHIỂN PLUG AND PLAY 17.1. Hàm DeviceIoControl API (The DeviceIoControl API) 17.2. Điều khiển IRP MJ DEVICE CONTROL 17.3. Những thao tác bên trong điều khiển IO (Internal IO Control Operations) 18. Bài 18: THỰC HÀNH LẬP TRÌNH DRIVER CHO ĐIỂU KHIỂN VÀO/ RA 18.1. Thực hành lập trình driver cho điều khiển Vàora 19. Bài 19: TRÌNH ĐIỀU KHIỂN CHO USB 19.1. Giới thiệu cổng USB 20. Bài 20: THỰC HÀNH ĐIỀU KHIỂN QUA CỔNG USB 20.1. Thực hành với các chương trình ví dụ điều khiển qua cổng USB 2/369 21. Bài 21: TRÌNH ĐIỀU KHIỂN CHO HID 21.1. Những bộ điều khiển cho thiết bị HID (Drivers for HID Devices ) 21.2. Những mô tả báo cáo và những báo cáo (Reports and Report Descriptors ) 21.3. Những điều khiển nhỏ HIDCLASS (HIDCLASS Minidrivers) 22. Bài 22: THỰC HÀNH LẬP TRÌNH HID 22.1. Thực hành với các chương trình ví dụ điều khiển cho HID 23. Bài 23: THỰC HÀNH LẬP TRÌNH DRIVER GIAO TIẾP CÁC CỔNG 23.1. Thực hành một số bài tập tổng hợp 24. TÀI LIỆU THAM KHẢO 24.1. Lập trình hệ thống: Tài liệu tham khảo 25. MỤC LỤC 25.1. Lập trình hệ thống: Mục lục Tham gia đóng góp 3/369 Bài 1: TỔNG QUAN VỀ LẬP TRÌNH HỆ THỐNG Khái niệm về lập trình hệ thống Lập trình hệ thống (hoặc chương trình hệ thống) là hoạt động của các phần mềm hệ thống. Đầu tiên chỉ ra sự khác biệt tiêu biểu của các chương trình hệ thống khi đã so sánh tới lập trình ứng dụng là ở đó nhắm vào lập trình ứng dụng để sản sinh phần mềm mà cung cấp những dịch vụ tới người dùng (ví du: bộ xử lý văn bản), trong khi những nhà lập trình hệ thống nhắm vào việc sản xuất phần mềm mà cung cấp những dịch vụ tới phần cứng máy tính (ví dụ: phần mềm chống phân mảnh đĩa). Nó cũng yêu cầu một độ lớn hơn của sự ý thức phần cứng. 4/369 Tổng quan về lập trình hệ thống Những điểm đặc biệt hơn trong lập trình hệ thống: • Những nhà lập trình sẽ tạo những gánh vác về phần cứng và một số thuộc tính khác của những chương trình chạy trên hệ thống đó, và sẽ thường khai thác những thuộc tính đó (cho ví dụ bởi việc sử dụng một giải thuật mà được biết mà hiệu quả khi nào được sử dụng với phần cứng đặc biệt). • Thông thường một ngôn ngữ lập trình cấp thấp hoặc tiếng địa phương ngôn ngữ lập trình sử dụng đó là: ◦ có thể hoạt động trong những môi trường tài nguyên bắt buộc ◦ là rất hiệu quả và có thể thực hiện một ít ở trên đầu ◦ có một thư viện thực hiện nhỏ, hoặc không ở mọi thứ ◦ cho phép trực tiếp và “thô” mà điều khiển qua truy cập bộ nhớ và điều khiển chảy tràn ◦ để cho người lập trình viết những phần của chương trình ngay tức khắc trên ngôn ngữ assembly. • Gỡ rối có thể là khó nếu nó là thật không có thể để chạy chương trình trong một chương trình gỡ rối vì những sự ràng buộc tài nguyên. Chạy chương trình bên trong một môi trường giả có thể sử dụng để giảm bớt vấn đề này. Những nhà lập trình hệ thống một cách đầy đủ thì khác với lập trình ứng dụng mà những người lập trình hướng tới chuyên về một hoặc cái khác. Trong lập trình hệ thống, những phương tiện lập trình có hạn thường sẵn có. Sự sử dụng của tập hợp rác tự động thì không phải là phổ biến và gỡ rối là không đổi đôi khi để làm. Thư viện thực hiện, nếu sẵn có ở mọi nơi, thì ít mạnh hơn nhiều thông thường, và làm ít sợ kiểm tra lỗi hơn. Bởi vì những sự hạn chế đó, màn hình và sự đăng ký thường được sử dụng; những hệ điều hành có thể có vô cùng chi tiết hóa những hệ thống con đăng ký. Thực hiện những phần nhất định trong Hệ điều hành và những quy định hoạt động mạng những nhà lập trình hệ thống (cho ví dụ thi hành phân trang (bộ nhớ ảo) hoặc một trình điều khiển thiết bị cho một hệ điều hành). 5/369 Lịch sử về lập trình hệ thống Trước đây những nhà lập trình hệ thống không thay đổi điền thêm ngôn ngữ assembly. Những cuộc thử nghiệm với việc hỗ trợ phần cứng ở những ngôn ngữ bậc cao vào cuối những năm 1960 dẫn dắt với những ngôn ngữ như BLISS và BCPL, trừ C, giúp đỡ bởi sư tăng của UNIX, trở thành là ở khắp nơi vào những năm 1980. C++ nhúng mới đây hơn đã nhìn thấy sự sử dụng nào đó, cho thể hiện trong bộ dụng cụ các trình điều khiển Vào/ra của Mac OS X. 6/369 Cấu trúc tổng quan lập trình hệ thống Hình 1-1 là biểu đồ thu gọn của hệ điều hành Windows XP, nó rất quan trọng đối với người lập trình driver. Các hoạt động của Windows XP đều được hỗ trợ bởi hai chế độ. Đó là User Mode và Kernel mode. Ví dụ : Một User Mode muốn tới, đọc dữ liệu từ thiết bị thì phải gọi đến chương trình giao tiếp ứng dụng (API) qua ReadFile. 7/369 Bài 2: CÔNG CỤ LẬP TRÌNH HỆ THỐNG Các ngôn ngữ lập trình Lập trình hệ thống không nhất thiết phải sử dụng ngôn ngữ assembly. Thật vậy, tuyệt đại đa số các module chức năng cấu thành hệ điều hành Windows, Unix, Linux... đều được viết bằng ngôn ngữ C. Ưu điểm của các ngôn ngữ cấp cao là rõ ràng, dễ đọc, dễ diễn đạt giải thuật, diễn đạt giải thuật cô đọng... Như vậy, nếu chưa thật cần thiết phải dùng assembly hay ngôn ngữ máy, bạn nên dùng 1 ngôn ngữ cấp cao như C, C++ để viết các ứng dụng của bạn. Ngược lại, ngôn ngữ Assembly hay ngôn ngữ máy không nhất thiết chỉ để dùng cho lập trình hệ thống mà có thể được dùng để viết ứng dụng bất kỳ. Tuy nhiên do nhược điểm của assembly và ngôn ngữ máy là quá yếu để diễn đạt giải thuật nên rất ít người dùng chúng trực tiếp. Như trên đã nói, ngay cả khi viết hệ điều hành hay các hệ thống nhúng (chương trình điều khiển thiết bị và được ghi trên ROM của thiết bị đó), người ta cũng cố gắng dùng ngôn ngữ cấp cao như C, trừ những đoạn code đặc biệt mới dùng assembly hay mã máy. Trong trường hợp buộc phải dùng assembly hay mã máy, bạn phải lưu ý rằng các ngôn ngữ này phụ thuộc hoàn toàn vào CPU được dùng. Bạn không thể viết đoạn code assembly hay mã máy mà có thể chạy trên nhiều loại CPU được. Riêng đối với CPU Intel từ 80386 trở lên, nó có thể hoạt động ở 1 trong 3 chế độ quản lý bộ nhớ khác nhau như: Real-mode (chế độ mặc định khi bị reset ban đầu), protected-mode (quản lý theo segment) và 386-enchanced mode (quản lý vừa theo segment, vừa theo page, đây là chế độ quản lý bộ nhớ hoàn hảo nhất). Thí dụ khi mới boot máy hay khi máy được boot và chạy MSDOS, CPU Intel sẽ chạy ở chế độ Real-mode, còn khi máy đang chạy Linux, Windows XP... thì CPU Intel chạy ở chế độ 386-enchanced mode. Nếu bạn lập trình bằng ngôn ngữ cấp cao, bạn không cần biết chế độ quản lý bộ nhớ nào sẽ được dùng để chạy ứng dụng. Còn nếu lập trình bằng assembly hay mã máy, bạn cần phải nắm vững các chế độ quản lý bộ nhớ của CPU, phải quyết định chế độ quản lý nào sẽ dùng để chạy ứng dụng, từ đó mới bắt đầu viết lệnh tương thích với chế độ quản lý bộ nhớ mong muốn. Thí dụ nếu bạn lập trình ở chế độ real-mode (1 trong những chế độ 16-bit), bạn chỉ có thể dùng các thanh ghi 16-bit của CPU như ax, bx, cx, dx, ds, cs, es, ss). Còn nếu bạn lập trình ở chế độ 386-enchanced mode, bạn có thể dùng các thanh ghi 32 bit của CPU, trong đó có 2 thanh ghi fs, gs như bạn đề cập. Lưu ý rằng các ứng dụng viết ở chế độ 32bit chỉ có thể chạy trên môi trường Windows (hay Linux), chứ không thể chạy trên MSDOS được. Chi tiết về các chế độ quản lý bộ nhớ cũng như tập lệnh CPU ở từng chế độ quản lý bộ nhớ được trình bày trong tài liệu kỹ thuật giới thiệu CPU tương ứng. Bạn có thể tìm tài liệu kỹ thuật trên Internet hay liên hệ trực tiếp với các đại lý của Intel. 8/369 Giới thiệu về C++ C++ là một ngôn ngữ lập trình tiến tiến, mạnh trong các ngôn ngữ lập trình hiện nay, nó được sử dụng bởi hàng triệu lập trình viên trên thế giới. Nó là một trong những ngôn ngữ phổ biến để viết các ứng dụng máy tính – và ngôn ngữ thông dụng nhất để lập trình games. Được sáng tạo bởi Bjarne Stroustrup, C++ là thế hệ sau của ngôn ngữ C. Thực tế, C++ giữ lại hầu hết các đặc điểm của C. Như thế nào đi nữa, C++ đem đến cho chúng ta những thuận lợi hơn trong việc lập trình. Dùng C++ cho Games: C++ là ngôn ngữ được các lập trình viên games lựa chọn. Hầu hết các games được giới thiệu hiện nay đều được viết bởi C++. Có nhiều lí do khác nhau để giải thích vì sao những người lập trình games sử dụng C++. Đây là một vài lí do: Nhanh: Nếu bạn rành C++ thì bạn có thể lập trình nhanh. Một trong những mục tiêu của C++ là khả năng thực thi. Và nếu bạn cần thêm các tính năng cho chương trình, C++ cho phép bạn dùng ngôn ngữ Assembly (Hợp ngữ) – Ngôn ngữ lập trình bậc thấp nhất – để giao tiếp trực tiếp với phần cứng của máy tính. Dễ điều khiển: C++ là một ngôn ngữ biến hóa, nó hỗ trợ các phong cách lập trình khác nhau, bao gồm lập trình hướng đối tượng. Không giống các ngôn ngữ khác, C++ không ép buộc lập trình viên phải đi theo một phong cách nào cả. Hỗ trợ nhiều: Vì nó là ngôn ngữ vượt trội các ngôn ngữ khác, có rất nhiều tài nguyên cho người lập trình bằng C++, bao gồm đồ họa API và 2D, 3D, vật lý, các thiết bị âm thanh chính vì điều này đã giúp cho lập trình viên tăng tốc độ lập trình games. 9/369 Tạo File thực thi: (.exe) File mà bạn dùng để chạy chương trình – dù bạn đang nói đến game hay các ứng dụng windows – gọi là file thực thi (Executable File). Có rất nhiều bước để tạo một file thực thi từ mã nguồn của C++ (tập hợp các lệnh trong ngôn ngữ C++). Quá trình này được mô tả ở hình 1.1. 1. Đầu tiên, người lập trình dùng editor (trình soạn thảo) để viết mã nguồn C++, file đó thường có đuôi .cpp. Trình soạn thảo giống như bộ xử lý ngôn ngữ cho chương trình, nó cho phép lập trình viên tạo, chỉnh sửa, và lưu trữ mã nguồn. 2. Sau khi lập trình viên lưu lại mã nguồn, anh (chị) ta sẽ gọi compiler (trình biên dịch) – một ứng dụng có chức năng đọc mã nguồn và dịch nó sang file đối tượng (object file). Object files thường có đuôi mở rộng là .obj. 10/369 3. Tiếp theo, bộ phận kết nối (Linker) sẽ kết nối file object đến những file ngoài nếu cần thiết, sau đó tạo file thực thi (executable file), thường có đuôi mở rộng là .exe. Đến lúc này, người dùng có thể chạy chương trình bằng cách chạy file thực thi. Lưu ý: Quá trình tôi miêu tả ở trên chỉ là một trường hợp đơn giản. Để tạo nên một ứng dụng phức tạp trong C++ thường liên quan đến rất nhiều file mã nguồn được viết bởi lập trình viên (hay một nhóm lập trình viên). Để tự động hóa quá trình này, lập trình viên dùng một công cụ tổng hợp, đó là IDE (Integrated Development Environment – môi trường tương thích khai triển). IDE thường bao gồm editor, compiler, linker và một số công cụ khác. Phiên bản thương mại IDE cho Windows bao gồm Visual Studio.NET và C++ Builder Studio. Dev-C++ là một ngôn ngữ mà nguồn mở miễn phí cho Windows (hyutar: strong CD ROM kèm quyển sách gốc có cái Dev-C++, nhưng sách này là đồ lậu nên hổng có, mọi người có thể tải cái này từ trên net về, hoặc dùng C++ 6.0 hay Visual C++ cũng được, mình nghĩ hầu hết mọi người đều có bản thương mại của C rồi). Xử lý lỗi: (error) Khi miêu tả quá trình tạo file thực thi từ mã nguồn C++, tôi đã bỏ qua một chi tiết nhỏ: đó là lỗi. Lỗi là một chuyện hay gặp của các chương trình máy tính. Lập trình viên chính là người thường xuyên mắc lỗi nhất. Ngay cả lập trình viên giỏi nhất đều có thể mắc lỗi ở lần thứ 1 (hoặc nhiều hơn) chạy chương trình. Lập trình viên phải sửa lỗi và chạy lại quá trình tạo file thực thi. Sau đây là một vài loại lỗi cơ bản bạn thường mắc phải khi chạy chương trình: Lỗi biên dịch (Compile Errors): Nó xảy ra trong quá trình biên dịch. Kết quả, file object không được tạo ra. Lỗi này thường do lỗi cú pháp, có nghĩa là trình biên dịch không hiểu cái gì đó. Nó có thể đơn giản như gõ sai lệnh chẳng hạn, hay thiếu dấu “;”. Trình biên dịch còn đưa ra những cảnh báo (warning). Mặc dù bạn thường không cần phải chú ý đến warning, nhưng bạn nên giải quyết nó như là lỗi, sữa chửa, sau đó biên dịch lại, đây là một thói quen tốt đấy ^^. Lỗi liên kết (Link Errors): Nó xảy ra trong quá trình kết nối và có thể cho biết có vài thứ mà chương trình liên kết đến không thể tìm thấy. Lỗi này thường được giải quyết bằng cách đặt đúng vị trí các liên kết và bắt đầu quá trình biên dịch/kết nối lần nữa. Lỗi Run-time (Run-time errors): Nó xảy ra khi đang chạy file thực thi. Nếu chương trình làm một cái gì đó không hợp lý, nó có thể phá hủy hệ thống. Nhưng một dạng lỗi tinh vi, khó phát hiện hơn của lỗi run-time: logical error (lỗi logic), có thể làm chương trình làm những việc mà ta không định trước. Nếu bạn đã từng chơi game mà trong đó nhân vật có thể bước trên không khí (trong kịch bản nhân vật không thể bước trên không khí), khi đó bạn đã thấy lỗi logical trong hành động. 11/369 Trong thực tế: Như các nhà tạo phần mềm, công ty game thường gặp rắc rối với các sản phẩm bị lỗi. Biện pháp khắc phục của họ là trước khi đem ra ngoài thị trường, họ thuê những người chơi game thử (game testers). Những người này chỉ chơi games, nhưng công việc của họ không thú vị như bạn tưởng đâu. Họ phải chơi đi chơi lại một phần nào đó của game – có thể lên đến hàng trăm – cố gắng tìm xem có lỗi nào không. Và với công việc buồn tẻ này, lương của họ cũng bèo nhèo. Nhưng trở thành game testers là một nấc thang để bạn có thể vào làm việc tại công ty làm games. Ví dụ: #include #include void main() { printf(“chao cac ban”); getch(); } 12/369 Giới thiệu về Visual C++ Visual C++ là môt phần mềm lập trình hướng đối tượng được phát triển trên cơ sở là ngôn ngữ lập trình C và C++. Phương pháp thiết kế hướng đối tượng vừa mới phát triển nhằm giúp nhà phát triển khai thác được sức mạnh của đối tượng và ngôn ngữ lập trình hướng đối tượng, dùng các lớp và đối tượng như là khối xây dựng cơ sở. OOP (ngôn ngữ lập trình hướng đối tượng ) là ngôn ngữ hiện thực trong đó chương trình được tổ chức như tập hợp những đối tượng hợp tác với nhau, mỗi đối tượng đại diện cho một instance của một vài lớp và những lớp mà chúng là thành viên của một lớp phân cấp thông qua quan hệ thừa kế. 1. Abstraction ( tính trừu tượng) : Sự trừu tượng thể hiện những đặc tính cốt yếu của một đối tượng mà những đặc tính này dùng để phân biệt đối tượng này với tất cả các loại đối tượng khác và do vậy cung cấp một cách rõ ràng giới hạn ý niệm được ý nghĩa, liên quan đến viễn tượng của người nhìn. Trừu tượng tập trung vào cái nhìn bề ngoài của đối tượng và do đó thỏa mãn được các hành vi chủ yếu của đối tượng riêng biệt từ hiện thực của nó. Ta có thể có các loại trừu tượng sau: - Thực thể trừu tượng : một đối tượng mà nó đại diện cho một mô hình hữu dụng của một miền vấn đề hay thực thể miền giải quyết. - Operation abstraction (hoạt động trừu tượng ) : một đối tượng mà nó cung cấp một tập tổng quát của các operation, tất cả các operation thực thi cùng một loại chức năng. - Máy ảo trừu tượng : một đối tượng mà nó nhóm các hoạt động với nhau, và tất cả các hoạt động này được sử dụng bởi mức điều khiển cao hơn. Hoặc các hoạt động mà chúng sử dụng tập hợp các hoạt động của mức thấp hơn. - Trừu tượng ngẫu nhiên : một đối tượng mà nó đóng gói một tập hợp các hoạt động mà chúng không có quan hệ lẫn nhau. Một client là bất kì đối tượng nào sử dụng nguồn tài nguyên của đối tượng khác ( gọi là server). Chúng ta có thể biểu thị đặc điểm hành vi của đối tượngbằng cách xem xét những dịch vụ mà nó cung cấp cho những đối tương khác, cũng như những hoạt động 13/369 mà nó có thể thực thi cho đối tượng khác. Quan điểm này buộc chúng ta phải tập trung vào cái nhìn bề ngoài của đối tượng. Chúng ta gọi toàn bộ tập hợp của các hoạt động mà một client có thể thi hành cho một đối tượng, cùng với những câu lệnh hợp lệ mà chúng có thể được gọi là protocol. Một protocol biểu thị những cách thức mà một đối tượng có thể hành động và phản ứng, và do vậy có thể cấu thành tổng thể bề ngoài tĩnh và động của trừu tượng. 2. Encap sulation (sự đóng kín) : Tính đóng kín là quá trình phân chia các phần tử của một trừu tượng để cấu thành nên cấu trúc và hành vi của chính nó, đóng kín cho phép hoạt động giao tiếp của một trừu tượng và hiện thực của nó. Sự đóng kín là cơ chế liên kết mã và dữ liệu mà nó thao tác, và giữ cho cả 2 được an toàn khỏi sự can thiệp từ bên ngoài và do sử dụng sai. Trong ngôn ngữ hướng đối tượng, mã và dữ liệu liên kết với nhau để tạo thành một “hộp đen” độc lập. Trong hộp này là tất cả mã và data cần thiết. Khi mã và data liên kết với nhau như thế một đối tượng sẽ được tạo ra. Nói cách khác, đối tượng là một dụng cụ hỗ trợ cho sự đóng kín. Trong một đối tượng , mã, data, hoặc cả 2 có thể là private (riêng) của đối tượng đó hay public (chung). Mã hoặc data riêng là thuộc về đối tượng đó và chỉ được truy cập với bộ phận của đối tượng. Nghĩa là mã hoặc data riêng không thể truy cập bởi các phần khác của chương trình tồn tại ngoài đối tượng. Khi data là chung, các bộ phận khác có thể truy cập đến nó mặc dù nó được định nghĩa trong một đối tượng. Các phần chung của một đối tượng dùng để cung cấp một giao diện có điều khiển cho các phần riêng của đối tượng. Nói chung, một đối tượng là một biến thuộc kiểu do người sử dụng định nghĩa. Mỗi lần ta định nghĩa một đối tượng mới, ta tạo ra một loại data mới. Đặc biệt các thành viên có thể được đặt vào public, private, hay protectedcủa lớp. Thành viên được khai báo là public thì thấy được đối với mọi client, những thành viên khai báo là private thì hoàn toàn đóng kín, và những thành viên khai báo là protected thì chỉ thấy với chính lớp của nó và những lớp con của nó. C++ cũng còn cho phép kí hiệu friend : là lớp cùng hợp tác được phép thấy những phần privated của nhau. 3. Modularity (modun hóa) : Modularity là tính chất của một hệ thống đã được phân tích thành một tập hợp dính kết và ghép lại một cách lỏng lẻo thành những modun. 14/369 Việc phân chia chương trình thành những phần riêng lẻ có thể làm giảm độ phức tạp. Ở ngôn ngữ này lớp, đối tượng hình thành cấu trúc luận lý của hệ thống. Chúng ta đặt những trừu tượng này trong modun để tạo ra những kiến trúc vật lý của hệ thống. Đối với những vấn đề nhỏ, nhà phát triển có thể quyết định vấn đề khai báo tất cả các lớp và đối tượng trong cùng một gói. Ta thường nhóm những lớp vàø đối tượng có quan hệ trong cùng một modun, và chỉ phơi bày những phần tử mà modun khác cần thấy. Trong các hệ thống lớn, thì nó có quá nhiều modun và thật là khó cho người sử dụng tìm thấy những lớp mà họ cần. Hơn nữa , khi quyết định thay đổi hàng trăm modun phải được hiệu chỉnh hoặc biên dịch lại. Như vậy, modun hóa đôi khi cũng không tốt. Modun phục vụ như là những phần tử và những đơn vị không thể phân chia được của phần mềm mà có thể sử dụng lại được qua các ứng dụng. Nhà phát triển sẽ chọn cách đóng gói đối tượng thành các modun sao cho chúng thuận tiện để sử dụng lại. 4. Hierachy (hệ thống phân cấp) : Hệ thống phân cấp là một sự sắp xếp theo thứ bậc hay sắp đặt các trừu tượng. Có hai phân cấp quan trọng nhất trong một hệ thống phức tạp là : cấu trúc lớp của nó(phân cấp “is a”), và cấu trúc đối tượng của nó ( phân cấp “part of “). Thừa kế đơn giản: thừa kế là mối quan hệ “ is a “. thừa kế định nghĩa một mối quan hệ giữa các lớp, trong đó một lớp chia sẻ cấu trúc và hành vi đã được định nghĩa trong một lớp hay nhiều lớp ( tương ứng với thừa kế đơn giản và đa thừa kế ). Do đó thừa kế như là sự phân cấp của các trừu tượng, trong đó một lớp con thừa kế một hay nhiều lớp cha. Đa thừa kế đưa đến một số vấn đề phức tạp cho ngôn ngữ lập trình. Những ngôn ngữ phải đưa ra hai vấn đề: xung đột giữa tên của các lớp cha khác nhau, và thừa kế được lập lại nhiều lần. Sự xung đột xảy ra khi hai hay nhiều lớp cha cùng cấp cùng chia sẻ một lớp cha chung. Và trong trường hợp như vậy, lớp lá có một hoặc nhiều bản sao cấu trúc của lớp cha được dùng chung đó. Một số ngôn ngữ thì không cho phép thừa kế lập lại, một số khác thì chọn hướng khác. C++ cho phép người lập trình quyết định: virtual base class (lớp cơ sở ảo ) được dùng để chỉ ra sự dùng chung của cấu trúc lập lại, trong khi đó nonvirtual base class có kết quả là trùng bản sao ở lớp con. 5. Kiểm tra kiểu ( typing ) : Typing là sự tuân theo bắt buộc của lớp đối tượng, như là những đối tượng của các lớp khác nhau không được thay thế lẫn nhau hoặc chúng có thể thay thế lẫn nhau chỉ theo một cách thức rất hạn chế. C++ có khuynh hướng kiểm tra kiểu chặt chẽ nhưng ta có thể lờ đi hay cấm kiểm tra.Tính đa dạng (polymorphism): 15/369 Là tính chất cho phép một tên được dùng cho hai hoặc nhiều mục đích khác nhau có quan hệ về phương diện kỹ thuật. Mục đích của tính đa dạng khi được áp dụng cho OOP là cho phép một tên được dùng để chỉ rõ một lớp tác động tổng quát, một tác động cụ thể được xác định bởi loại data. Ví dụ, trong C, không có hỗ trợ tính đa dạng nên một tác động giá trị tuyệt đối cần phải có ba hàm khác nhau: abs(), labs(), và fabs(). Các hàm này tính toán và lần lượt trả về một giá trị tuyệt đối của số nguyên, một số nguyên dài, một giá trị dấu phẩy động. Tuy nhiên, trong C++ có đặc tính đa dạng nên có hàm abs(). Loại data được dùng để gọi hàm xác định loại hàm nào thực sự được dùng. Trong C++ có thể sử dụng một tên hàm cho nhiều mục đích khác nhau. Điều này được gọi là quá tải hàm(function overloading). Tổng quan hơn khái niệm tính đa dạng là ý tưởng “một giao diện, nhiều phương pháp”. Điều này có nghĩa là có thể thiết kế một giao diện chung cho một nhóm các tác động có liên quan. Tuy nhiên, tác động cụ thể được thi hành phụ thuộc vào data. Ưu điểm của tính đa dạng là chúng làm giảm tính phức tạp bằng cách cho phép cùng một giao diện được sử dụng để ghi rõ một lớp tác động tổng quát, chính trình biên dịch sẽ lựa chọn tác động cụ thể khi áp dụng cho từng trường hợp. Là người lập trình ta không phải thực hiện sự lựa chọn này bằng tay. Ta chỉ cần nhớ và sử dụng giao diện chung. Liên kết tĩnh và kiên kết động (Static and Dynamic Binding): Khái niệm trong typing và static typing liên kết tĩnh là hoàn toàn khác nhau. Strong typing đề cập tới sự nhất quán của kiểu. Stactic binding có nghĩa là kiểu của mọi biến và biểu thức là cố định vào lúc biên dịch. Dynamic binding nghĩa là các kiểu của mọi biến và biểu thức không cho biết cho tới khi chạy chương trình. Bởi vì Strong typing và Dynamic binding là khái niệm độc lập cho nên một ngôn ngữ có thể vừa Strong và Static typing. 6. Bản chất của đối tượng: Một đối tượng có trạng thái, hành vi, đặc tính nhân dạng; cấu trúc và hành vi của các đối tượng giống nhau được định nghĩa trong một lớp chung của chúng, thuật ngữ instance và đối tượng là có thể thay thế lẫn nhau được. Trạng thái (state) : của một đối tượng bao gồm tất cả các đặc tính (thường là tĩnh) của đối tượng trừ đi giá trị hiện tại ( thường là động ) của mỗi đặc tính đó. Hành vi (behavior ) : là đối tượng hoạt động và phản ứng như thế nào theo điều kiện trạng thái của nó thay đổi và message truyền đến. Operations (hoạt động) : là một dịch vụ mà một lớp cung cấp cho khách hàng của nó. Chúng ta thấy rằng một client thường thực thi năm loại opearation đối tượng. Ba loại operation thông thường nhất là : 16/369 • Modifier : là operation thay đổi trạng thái của đối tượng. Selector: là Operation truy xuất trạng thái của đối tượng nhưng không làm thay đổi trạng thái của nó. • Iterrator : là operation cho phép tất cả các phần của một đối tượng được truy xuất theo một thứ tự đã định nghĩa trước. Hai loại operation thông dụng khác cần thiết để tạo và hủy những instance của một lớp là : • Constructor: là operation tạo đối tượng và (hoặc) khởi động trạng thái của nó. • Destructor là operation giải phóng trạng thái của một đối tượng và (hoặc) hủy chính đối tượng đó. • Indentify: (đặc điểm nhận dạng) : indentify là đặc tính của một đối tượng để phân biệt nó với các đối tượng khác. 7. Mối quan hệ giữa các đối tượng: Links( liên kết) : Link là nối kết vật lý hay ý niệm giữa các đối tượng. Một đối tượng cộng tác với một đối tượng khác thông qua link của nó tới những đối tượng này. Hay nói cách khác, một link vó nghĩa là một hợp tác cụ thể qua đó một đối tượng ( client) áp dụng những dịch vụ của đối tượng khác (nhà cung cấp) hoặc qua đó một đối tượng có thể điều khiển đối tượng khác. Một đối tượng có thể đóng các vai trò sau: • Actor : một đối tượng có thể làm việc trên một đối tượng khác nhưng nó không bao giờ cho một đối tượng khác làm việc trên nó, thuật ngữ actor và active object có thể thay thế lẫn nhau. • Server: một đối tượng không bao giờ làm việc trên một đối tượng khác, nó chỉ cho đối tượng khác làm việc trên nó. • Agent : một đối tượng vừa làm việc trên đối tượng khác vừa cho đối tượng khác làm việc trên nó, một đại lý thường được tạo ra để làm công việc cho một actor hay một agent khác . • Đối tượng được cung cấp là global đối với client. • Đối tượng cung cấp là một tham số cho các operation của client. • Đối tượng cung cấp là một phần của đối tượng client. • Đối tượng cung cấp được khai báo cục bộ trong operation của client. 17/369 Khi có multiple thread control, việc truyền thông tin giữa các đối tượng cần xử lý vấn đề multual exclusion trong hệ thống xử lý đồng thời. Vấn đề đồng bộ hóa cũng phải xem xét. Aggregation: Aggregation có nghĩa là một phân cấp tổng thể / bộ phận, với khả năng điều khiển từ tổng thể ( còn gọi là aggregate ) tới những bộ phận (được hiểu là những thuộc tính của nó). 8. Bản chất của lớp: Class (lớp) : là tập hợp của các đối tượng có cùng cấu trúc chung hay hành vi chung. Một đối tượng đơn giản chỉ là một instance của lớp. Interface: của một lớp cho thấy bên ngoài của đối tượng và do đó nhấn mạnh đến vấn đề trừu tượng trong khi che dấu cấu trúc và hành vi bên trong. Implemention : của môt lớp là cái nhìn bên trong của nó. Implemention của một lớp cơ bản bao gồm tât cả các operation được định nghĩa trong interface. Chúng ta chia interface của lớp thành ba phần: • Public : là khai báo được truy xuất đến mọi client. • Protected : là khai báo được truy xuất chỉ chính lớp đó, lớp con của nó, và lớp friend. • Private: là khai báo được truy xuất chỉ chính lớp đó và lớp friend. 9. Mối quan hệ giữa các lớp: Phần lớn ngôn ngữ hướng đối tượng hỗ trợ trực tiếp một vài kết hợp của những quan hệ sau đây: • Association : gồm có quan hệ một-một, một-nhiều, nhiều-nhiều. • Inheritance (thừa kế) : là một lớp chia sẽ cấu trúc và (hoặc) hành vi được định nghĩa bởi một lớp (đơn thừa kế) hoặc nhiều lớp (đa thừa kế). • Aggregation (kết tập) : quan hệ kết tập giữa các lớp giống như quan hệ kết tập giữa các đối tượng tượng giữa các lớp đó. Đa thừa kế thường bị lẫn lộn với kết tập. Trong C++ thừa kế protected hay private dễ dàng bị thay thế bởi kết tập protected hay private của instace của lớp cha, mà không mất tính ngữ nghĩa của nó. Ví dụ: 18/369
- Xem thêm -

Tài liệu liên quan