Bài giảng Design Pattern
Bạn đang xem 20 trang mẫu của tài liệu "Bài giảng Design Pattern", để tải tài liệu gốc về máy bạn click vào nút DOWNLOAD ở trên
Tài liệu đính kèm:
- bai_giang_design_pattern.ppt
Nội dung text: Bài giảng Design Pattern
- CHƯƠNG 8: Design Pattern 1
- Nôị dung Coupling là gi?̀ Cohesion là gi?̀ Pattern là gi?̀ GRASP là gi?̀ 2
- Coupling là gì? Coupling là 1 cách để đo lừơng xem 1 phần tử khi được kết nối thì nó có khả năng “hiểu biết” đến mức nào hay hoàn toàn phụ thuộc vào các phần tử khác. Phần tử có thể là class, subsystem, system Một phần tử có coupling thấp (low coupling) nghĩa là nó không phụ thuộc nhiêù vào các phần tử khác. 3
- Coupling là gì? Một lớp có coupling cao sẽ phụ thuộc vào nhiều lớp khác. Các lớp này là không nên dùng vì: ◦ Những thay đổi trong các lớp có liên quan sẽ làm cho lớp naỳ cũng bị thay đổi theo ◦ Khó hiểu khi chúng bị cô lập ◦ Khó dùng lại vì nó đòi hỏi sự hiện diện cuả 1 số lớp mà nó phụ thuộc vào 4
- Cohesion là gì? Coupling đề cập đến sự tương tác giữa các đối tượng thì cohesion đề cập đến sự tương tác bên trong 1 đối tượng. Cohesion là 1 cách đo lường để xem các nhiêṃ vụ của 1 phần tử có quan hệ chặt chẽ với nhau như thế nào? Một phần tử có trách nhiệm tương đối cao, và không phải làm quá nhiều việc được xem là có cohesion cao (high cohesion) 5
- Cohesion là gì? Một lớp có low cohesion khi nó làm nhiều việc không liên quan nhau hay làm quá nhiều việc. Những lớp này là không nên dùng vì: ◦ Khó hiểu ◦ Khó dùng lại ◦ Khó bảo trì ◦ Dễ bị ảnh hưởng bởi các thay đổi Các lớp có cohesion thấp thường biểu diễn cho việc trừu tượng ở mức quá lớn, hay nhận những nhiệm vụ mà lẽ ra phải giao lại cho các đôí tượng khác thực hiện. 6
- Cohesion là gì? Method cohesion: là method chỉ đảm nhiệm 1 chức năng hay 1 nhiệm vụ. Thông thường cách đặt tên của nó cũng ngầm nói lên chức năng, ví dụ method chon_nha_cung_cap(), Tinh_tong() Class cohesion: các thuộc tính và method của lớp phải có mức độ cohesion cao, nghĩa là chúng phải được dùng bởi chính các method trong class hay chỉ chứa các method phục vụ cho mục đích chính của class 7
- Các mức độ cohesion 1. Very low cohesion: một class phải tự mình làm nhiều việc trong những miền chức năng hoàn toàn khác nhau. Ví dụ: môṭ lớp vừa có có nhiệm vụ tương tác với database quan hệ vừa quản lý các lệnh gọi thủ tục từ xa. Những nhiệm vụ này thuộc 2 vùng chức năng khác nhau, nên lớp naỳ có very low cohesion. 8
- Các mức độ cohesion 2. Low cohesion: class có nhiệm vụ phải tự mình thực hiện 1 công việc phức tạp trong 1 vùng chức năng. Ví dụ: môṭ lớp có nhiệm vụ tương tác với database quan hệ. Các method của lớp đều có liên quan với nhau nhưng lớp này có quá nhiều method để đảm đương nhiệm vụ→ Nên chia lớp naỳ thành 1 họ các lớp cùng chia xẻ nhau công việc truy xuất database. 9
- Các mức độ cohesion High cohesion: lớp có nhiệm vụ vừa phải (moderate responsibilities) trong cùng 1 vùng chức năng và hợp tác với các lớp khác để hoàn thành nhiệm vụ. Ví dụ: lớp RDBInterface chỉ có 1 phần nhiệm vụ trong việc tương tác với database. Nó tương tác với hàng tá các lớp khác để khôi phục và lưu trữ dữ liệu. 10
- Quy luật Cohesion và Coupling Cohesion kém thì thường sinh ra coupling kém và ngược lại. Cohesion và couling được ví như âm và duơng (yin and yang) của software engineering 11
- Các lợi ích của high cohesion Làm cho việc thiết kế rõ ràng và dễ hiểu hơn. Việc bảo trì và mở rộng cũng đơn giản hơn. Low coupling thường đuợc hỗ trợ. 12
- Pattern là gi?̀ Trong thực tế có rât́ nhiêù lược đồ class có câú truć giônǵ nhau. Pattern được xem như là giaỉ phaṕ hay cach́ thức để giaỉ quyêt́ baì toan.́ Khaí niêṃ về pattern trong thiêt́ kế phâǹ mêm̀ đuợc vay mượn từ nganh̀ kiêń truć xây dựng nơi mà cać pattern trợ giuṕ rât́ nhiêù cho cać kiêń truć sư khi lam̀ viêc̣ với cać câú truć phức tap̣ 13
- Pattern là gi?̀ Môṭ pattern khi được aṕ dung̣ vaò 1 ngữ canh̉ mới sẽ đưa ra cać khuyêń caó (recommendation) lam̀ thế naò để aṕ dung̣ và hoà hợp nó vaò tinh̀ huônǵ mới “A pattern is a named problem/ solution pair that can be applied in new context, with advice on how to apply it in novel situations and discussion of its trade-offs” 14
- GRASP GRASP (General Responsibility Assignment Software Patterns) bao gôm̀ nhiêù pattern mô tả cać nguyên tăć cơ ban̉ trong viêc̣ thiêt́ kế đôí tượng và gań nhiêṃ vụ cho đôí tượng. Hiêủ và aṕ dung̣ cać nguyên tăć GRASP trong quá trinh̀ taọ lược đồ tương tać là rât́ quan trong̣ giuṕ thiêt́ kế thanh̀ công phâǹ mêm̀ hướng đôí tượng. 15
- GRASP Mô hinh̀ thiêt́ kế có thể chứa hang̀ trăm hay hang̀ ngaǹ cać lớp phâǹ mêm̀ , và 1 ứng dung̣ có thể yêu câù hang̀ trăm hay hang̀ ngaǹ cać nhiêṃ vụ câǹ phaỉ hoaǹ thanh.̀ Khi thiêt́ kế đôí tượng, câǹ choṇ lựa xem nhiêṃ vụ nên gań cho đôí tượng naò là phù hợp hơn. Nêú gań hợp ly,́ hệ thônǵ sẽ trở nên dễ hiêủ , dễ baỏ trì và mở rông.̣ 16
- GRASP Có rât́ nhiêù pattern thuôc̣ loaị naỳ nhưng 5 pattern cơ ban̉ nhât́ : 1. Information Expert 2. Creator 3. High Cohesion 4. Low Coupling 5. Controller 17
- Information Expert (or Expert) Solution: Assign a responsibility to the information expert - the class that has the information necessary to fulfill the responsibility. Problem: What is a general principle of assigning responsibilities to objects? Goị tăt́ pattern naỳ là IE 18
- Case study 1: Lớp naò biêt́ tông̉ trị giá Nêú có môṭ số lớp câǹ biêt́ tông̉ trị giá cuả 1 lâǹ bań . Câu hoỉ đăṭ ra là lớp naò có nhiêṃ vụ cho biêt́ tông̉ trị giá môṭ lâǹ ban.́ Theo IE câǹ tim̀ xem có lớp naò chứa thông tin câǹ thiêt́ để xać đinḥ tông̉ số hay không? Chunǵ ta nên tim̀ cać lớp trong mô hinh̀ domain hay mô hinh̀ thiêt́ kê.́ 19
- Case study 1: Lớp naò biêt́ tông̉ trị giá 1. Trước hêt́ tim̀ cać lớp thich́ hợp trong mô hinh̀ thiêt́ kê.́ 2. Nêú không tim̀ thâý , thì tim̀ cać lớp trong mô hinh̀ domain và cố sử dung̣ cać lớp trong mô hinh̀ domain để taọ lâp̣ cać lớp tương ứng trong mô hinh̀ thiêt́ kê.́ 20
- Case study 1: Lớp naò biêt́ tông̉ trị giá Giả sử chunǵ ta chỉ vừa mới băt́ đâù viêc̣ thiêt́ kế và chưa có gì nhiêù trong mô hinh̀ thiêt́ kê.́ Chunǵ ta sẽ tim̀ kiêḿ trong mô hinh̀ domain để tim̀ ra lớp IE và lớp đó chinh́ là Sale. Chunǵ ta thêm vaò mô hinh̀ thiêt́ kế lớp phâǹ mêm̀ mới cung̃ có tên goị là Sale và gań cho nó nhiêṃ vụ biêt́ “knowing total” thông qua method getTotal. 21
- Case study 1: Lớp naò biêt́ tông̉ trị giá 22
- Case study 1: Lớp naò biêt́ tông̉ trị giá Thông tin gì câǹ biêt́ để xać đinḥ thanh̀ tiêǹ (subtotal) cuả môĩ măṭ hang̀ (line item)? → câǹ phaỉ biêt́ số lượng (quantity) và đơn giá (price). Theo mô hinh̀ nghiêp̣ vu,̣ thì lớp SalesLineItem biêt́ số lượng (quantity) và thông tin hang̀ (ProductSpecification) tương ứng. Vì vâỵ , SalesLineItem xać đinḥ được thanh̀ tiêǹ (subtotal) nên nó cung̃ là IE. 23
- Case study 1: Lớp naò biêt́ tông̉ trị giá Trong lược đồ tương tać ,để nhâṇ thanh̀ tiêǹ cuả môĩ măṭ hang̀ thì lớp Sale câǹ gửi thông điêp̣ get-Subtotal cho môĩ lớp SalesLineItem và tính tổng trên kết quả mà nó nhận được 24
- Case study 1: Lớp naò biêt́ tông̉ trị giá Để hoaǹ thanh̀ nhiêṃ vụ biêt́ và trả lời thanh̀ tiêǹ (subtotal), lớp LineItem câǹ biêt́ đơn giá san̉ phâm.̉ Lớp ProductSpecification là IE sẽ giuṕ trả lời về đơn gia.́ Và lớp naỳ câǹ môṭ thông baó được gửi đêń để hoỉ gia.́ 25
- Case study 1: Lớp naò biêt́ tông̉ trị giá 26
- Case study 1: Lớp naò biêt́ tông̉ trị giá Toḿ laị để hoaǹ tât́ nhiêṃ vụ biêt́ và trả lời tông̉ trị giá bań , ba nhiêṃ vụ được gań vaò ba lớp thiêt́ kế như sau: Lớp thiết kế Nhiệm vụ (Design class) Sale Biết tổng trị giá (sale total) Biết thành tiền một mặt hàng SaleLineItem (subtotal) ProductSpecification Biết đơn giá (unit price) sản phẩm 27
- Information Expert IE thường được dùng trong việc gán nhiêṃ vụ (responsibilitiy); Nó là 1 nguyên tắc hướng dẫn cơ bản được dùng liên tục trong thiết kế object. Nó diễn đạt nhận thức ("intuition“) chung rằng object làm các việc có liên quan đến thông tin chúng có. Việc hoàn thành nhiêṃ vụ thường yêu cầu thông tin ngang qua các class khác nhau, có nghĩa là có nhiều IE bộ phận (partial) cộng tác nhau để làm nhiệm vụ 28
- Creator Solution: Assign class B the responsibility to create an instance of class A if one or more of the following is true: ◦ B aggregates A objects. ◦ B contains A objects. ◦ B records instances of A objects. ◦ B closely uses A objects. ◦ B has the initializing data that will be passed to A when it is created B is a creator of A objects. If more than one option applies, prefer a class B which aggregates or contains class A. 29
- Creator Problem: Who should be responsible for creating a new instance of some class? The creation of objects is one of the most common activities in an object- oriented system. Consequently, it is useful to have a general principle for the assignment of creation responsibilities. Assigned well, the design can support low coupling, increased clarity, encapsulation, and reusability. 30
- Creator Solution: gán cho class B trách nhiệm phải tạo 1 instance của class A nếu 1 trong các điều kiện sau đúng: ◦ B kết hợp các đối tượng A (B aggregates A objects). ◦ B chứa các đối tượng A. ◦ B sử dụng thường xuyên các đối tượng A. ◦ B có các dữ liệu khởi tạo cần được chuyển cho A khi A được khởi tạo ➔ B là 1 creator của A Problem : Ai nên có trách nhiệm tạo 1 instance mới cho 1 số class? ◦ Việc tạo đối tương là 1 trong những hoạt động thông dụng nhất trong hẹ thống OO. Cần có các nguyên tắc chung để gán trách nhiệm này. ◦ Nêú gań đunǵ , thiêt́ kế có thể hỗ trợ low coupling, tăng độ rõ rang̀ , khả năng sử dung̣ laị 31
- Case Study: Lớp naò taọ điên̉ hinh̀ cuả SalesLineItem Trong ứng dụng POS, ai có trách nhiệm tạo instance của lớp SalesLineltem ? ➔Theo Creator, câǹ tìm 1 lớp mà nó kết hợp và chứa các instance của SalesLineltem. 32
- Case Study: Lớp naò taọ điên̉ hinh̀ cuả SalesLineItem 33
- Case Study: Lớp naò taọ điên̉ hinh̀ cuả SalesLineItem Từ mô hinh̀ domain, cho thâý lớp Sale chứa nhiều đối tượng SalesLineltem, do đó Creator đề nghị Sale là 1 ứng viên tốt cho nhiệm vụ tạo các instance của SalesLineltem. → Dẫn đến việc vẽ lược đồ tương tác như sau 34
- Lược đồ tuâǹ tự 35
- Creator Viêc̣ gań nhiêṃ vụ naỳ dâñ đêń viêc̣ là phaỉ có method makeLineItem() trong lơp Sale Viêc̣ xem xet́ và gań nhiêṃ vụ đã được lam̀ trong luć vẽ lược đồ tương tac.́ 36
- Creator Creator hướng dẫn việc gán responsibility có liên quan đến việc tạo các object. Mục đích cơ bản của Creator là tìm 1 class cần kết nối tới object được tạo trong bất kỳ sự kiện nào. Các container, hay class dạng ghi chép lưu trữ đều là ứng viên tốt để làm creator. 37
- Creator Đôi khi lớp creator được tìm thấy trong luć tim̀ kiêḿ lớp chứa dữ liêụ ban đâù câǹ được chuyên̉ cho lớp sẽ được tao.̣ Ví dụ: giả sử instance của Payment cần có giá trị khởi đầu (initial value) là tổng số tiền bán khi nó được tạo. Vì Sale biết tổng số này nên Sale là ứng viên tốt để trở thành creator của Payment. 38
- Low Coupling Solution gán responsibility sao cho coupling vẫn giữ được ở mức thấp. Problem Làm thế nào để làm cho sự phụ thuộc thấp, những ảnh hưởng khi thay đổi thấp, và khả năng sử dụng lại tăng. (How to support low dependency, low change impact, and increased reuse?) 39
- Ví dụ Trong lược đồ lớp có 3 lớp sau: register, Sale và Payment. Giả sử ta có nhu cầu tạo 1 instance của Payment và kết nối nó với Sale. Lớp nào có thể làm điều này? Vì Register phải ghi chép lại ("records“) các thanh toán (Payment) trong thế giới thực nên Creator đề cử Register là ứng viên tạo Payment. ➔Tiêṕ đó Register cung̃ câǹ gửi message “addPayment” cho Sale, kèm theo tham số là “new payment”. Khi đó lược đồ tương tác sẽ được vẽ như sau: 40
- Cach́ 1: gań trach́ nhiêṃ cho Register Việc gán responsibility này đã làm cho lớp Register phải biết (knowledge) đếnl ớp Payment. Điển hình Payment này được đặt tên tường minh là p vì vậy trong message số 2 nó được tham chiếu như 1 tham số 41
- Cach́ 2: gań trach́ nhiêṃ cho Sale Để Sale tạo lớp Payment 42
- Chọn lựa thiết kế Thiết kế nào hỗ trợ Low Coupling? Trong cả 2 trường hợp, ta đều giả sử là Sale cuối cùng đều phải biết đến Payment. Cách 1: Register tạo Payment, thêm 1 kêt́ nôí từ Register tới Payment Cách 2: Sale tạo Payment, không thêm bất kỳ coupling nào ➔ Thiết kế cách 2 tốt hơn 43
- Chọn lựa thiết kế Trường hợp đặc biệt của Low Coupling là khi không có 1 coupling nào giữa các class. Điều này cũng không tốt vì theo hướng đối tượng thì các đối tượng cần giao tiếp với nhau thông qua các message. Nếu Low Coupling được thực hiện quá triệt để thì sẽ tạo ra 1 thiết kế nghèo nàn, các đối tương không couple sẽ làm việc như 1 kho dữ liệu đơn thuần hoặc chúng phải tự làm hết mọi việc. 44
- High Cohesion Solution: gán nhiêṃ vụ (responsibility) sao cho cohesion vẫn giữ ở mức cao. Problem Làm thế nào vâñ quan̉ lý được độ phức tạp (complexity)? 45
- Ví dụ Trong ví dụ trước để tạo 1 instance của Payment và kết hợp nó với Sale. Class gì nên làm việc này? Vì Register ghi chép lại Payment nên creator đề nghị Register là 1 ứng viên cho việc tạo Payment. Sau đó Register gửi message addPayment cho Sale cùng với tham số là payment mới vừa tạo. 46
- Ví dụ Register đang nhận trách nhiệm hoàn thành thao tác hệ thống makePayment. Nếu chỉ xét trong phạm vi ví dụ này thì nhiệm vụ này có thể chấp nhận được, nhưng nếu tiếp tục gán cho Register nhiều việc hơn, nó sẽ trở nên quá tải và không còn cohesion nữa. 47
- Controller Solution: gán nhiệm vụ nhận và quản lý một thông báo sự kiện hệ thống cho môṭ lớp có môṭ trong hai dang̣ sau: ◦ Đại diện cho cả hệ thống, thiết bị hay hệ thống con (boundary class). ◦ Đại diện cho môṭ kicḥ ban̉ use case mà trong đó có sự kiện hệ thống xảy ra, lớp naỳ thường được đặt tên là Handler, Coordinator, hay Session. 48
- Controller Problem: Ai có trách nhiệm quản lý một sự kiện hệ thống đầu vào (input system event)? Sự kiện hệ thống đầu vào (input system event) là 1 sự kiện được phát ra bởi actor bên ngoài. Chúng kết hợp với các thao tać hệ thống (system operation) giônǵ như vai trò cuả messgase và method 49
- Controller Ví dụ: khi thâu ngân sử dụng phần mềm POS nhấn nút "End Sale“, anh ta đã phát ra 1 sự kiện hệ thống chỉ ra “việc bán hàng đã kết thúc”. Tương tự, khi người dùng phần mềm xử lý văn bản nhấn nút "spell check“, anh ta đã phát ra 1 sự kiện hệ thống chỉ ra “nhiệm vụ kiểm tra chính tả”. Controller là 1 đối tượng giao diện không dành cho người dùng (non-user interface object) có trách nhiệm nhận và quản lý sự kiện hệ thống. Controller sẽ định nghĩa các method cho hoạt động của hệ thống. 50
- Thao tać hệ thônǵ (System operation) Trong quá trinh̀ phân tich́ , cać thao tać hệ thônǵ có thể được gań taṃ cho lớp phân tich́ System. Điêù naỳ không có nghiã là lớp phâǹ mêm̀ System phaì thực hiêṇ hêt́ cać thao tać naỳ . Trong luć thiêt́ kế cać lơp controller sẽ lâǹ lượt được gań nhiêṃ vụ thực thi cać thao tać hệ thônǵ nay.̀ Trong ứng dụng POS có rất nhiều thao tác hệ thống như sau: ◦ endSale() ◦ enterItem() ◦ makeNewSale() ◦ makePayment() 51 ◦ . .
- Case study : hệ thônǵ POS Lớp naò sẽ là controller cho cać sự kiêṇ hệ thônǵ chăng̉ haṇ như enterltem và endSale Theo mẫu Controller, có thể có 1 số chọn lựa sau khi taọ lớp thiêt́ kế : ◦ Biểu diễn thành 1 hệ thống chung đặt tên là Register hay POSSystem ◦ Biểu diễn thành receiver hay handler để quản lý tất cả các sự kiện hệ thống theo kicḥ ban̉ cuả UC như ProcessSaleHandler, ProcessSaleSession 52
- Case study : hệ thônǵ POS 53
- Lớp controller cho enterItem Lớp controller cho sự kiện hệ thống enterItem có thể là 1 trong 2 dạng trên 54
- Bloated Controllers Nêú thiêt́ kế không tôt́ môṭ lớp controller sẽ bị low cohesion và sẽ được goị là bloated controller. Dâú hiêụ để nhâṇ biêt́ 1 lớp bị bloated: ◦ Chỉ có 1 lớp controller duy nhât́ để nhâṇ moị sự kiêṇ hệ thônǵ và có khá nhiêù sự kiêṇ hệ thông.́ ◦ Chinh́ controller phaỉ thực thi nhiêù nhiêṃ vụ mà không uỷ thać công viêc̣ cho lớp khac.́ ◦ Controller có nhiêù thuôc̣ tinh́ và chứa nhiêù thông tin về hệ thônǵ và nghiêp̣ vu.̣ 56
- Biêṇ phaṕ tranh́ Bloated Controllers 1. Bổ sung thêm cać controllers. Môṭ hệ thônǵ không nên chỉ có 1 controller. Ví dụ hệ thônǵ đăṭ chỗ vé maý bay, có thể chứa cać controller sau: 57
- Biêṇ phaṕ tranh́ Bloated Controllers Thiêt́ kế môṭ controller chuyên trach́ lam̀ nhiêṃ vụ giao phó viêc̣ hoaǹ thanh̀ từng thao tać hệ thônǵ cho cać đôí tượng khac.́ 58
- Hệ quả cuả mâũ Controller Cać đôí tượng interface (như cać đôí tượng window) và interface layer không nên có nhiêṃ vụ quan̉ lý sự kiêṇ hệ thông.́ Giả sử hệ thônǵ POS có 1 cửa sổ hiên̉ thị thông tin bań hang̀ (dung̀ lớp JFrame cuả Java) và thu nhâṇ cać thao tać cuả thâu ngân. Haỹ xet́ 2 trường hợp interface layer naỳ có và không can thiêp̣ vaò nhiêṃ vụ quan̉ lý sự kiêṇ hệ thông.́ 59
- Interface không quan̉ lý sự kiêṇ hệ thônǵ 60
- Interface không quan̉ lý sự kiêṇ hệ thônǵ Lớp SaleJFrame – môṭ phâǹ cuả interface layer – truyêǹ thông điêp̣ enterItem cho đôí tượng Register. Nó không liên quan gì đêń viêc̣ xử lý thao tać naỳ , mà chuyên̉ giao cho layer khac.́ Gań nhiêṃ vụ liên quan đêń thao tać hệ thônǵ cho controller (Register) sẽ lam̀ tăng cơ hôị sử dung̣ laị logic xử lý nghiêp̣ vụ naỳ cho cać ứng dung̣ tương lai. 61
- Interface quan̉ lý sự kiêṇ hệ thônǵ 62
- Interface quan̉ lý sự kiêṇ hệ thônǵ Nêú SaleJFrame ( thuôc̣ interface layer) quan̉ lý luôn thao tać hệ thônǵ enterItem, có nghiã là nó chứa luôn logic xử lý nghiêp̣ vu,̣ lam̀ mât́ đi cơ hôị sử dung̣ laị logic naỳ vì nó bi kêt́ nôí (coupling) vaò giao diêṇ đăc̣ biêt.̣ 63