Tiểu luận nghiên cứu các vấn đề về nguyên lý ngôn ngữ lập trình hướng đối tượng và cài đặt thử nghiệm bài toán tự chọn bằng ngôn ngữ lập trình hướng đối tượng c++

21 1 0
Tiểu luận nghiên cứu các vấn đề về nguyên lý ngôn ngữ lập trình hướng đối tượng và cài đặt thử nghiệm bài toán tự chọn bằng ngôn ngữ lập trình hướng đối tượng c++

Đang tải... (xem toàn văn)

Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống

Thông tin tài liệu

Trang 1 TRƯỜNG ĐẠI HỌC KINH TẾ QUỐC DÂNVIỆN CÔNG NGHỆ THÔNG TIN – KINH TẾ-------TIỂU LUẬNSVTH: PHẠM ANH TÚMSV: 11134279MÔN: NGUYÊN LÝ NGƠN NGỮ LẬP TRÌNHĐỀ TÀI: Nghiên cứu các vấn đề v

TRƯỜNG ĐẠI HỌC KINH TẾ QUỐC DÂN VIỆN CÔNG NGHỆ THÔNG TIN – KINH TẾ - TIỂU LUẬN Tiểu luận tài SVTH: PHẠM ANH TÚ MSV: 11134279 MƠN: NGUN LÝ NGƠN NGỮ LẬP TRÌNH ĐỀ TÀI: Nghiên cứu vấn đề nguyên lý ngôn ngữ lập trình hướng đối tượng cài đặt thử nghiệm tốn tự chọn ngơn ngữ lập trình hướng đối tượng C++ HÀ NỘI THÁNG NĂM 2015 MỤC LỤC I, Nguyên lý Open-Closed……………………………………………trang II, Nguyên lý Nghịch đảo phụ thuộc…………………………… .trang III, Nguyên lý Thay Liskov…………………………… .trang 12 IV, Nguyên lý Phân tách interface…………………………… trang 17 Tiểu luận tài Nguyên Lí Của Lập Trình Hướng Đối Tượng Phương pháp lập trình hướng đối tượng nghiên cứu phát triển từ lâu việc vận dụng cho hiệu việc xây dựng phần mềm điều mơ hồ nhiều người Thế phần mềm hướng đối tượng ? Đâu sở tảng để xây dựng phần mềm theo tư tưởng hướng đối tượng nghĩa ? Bài viết trình bày ngun lý lập trình hướng đối tượng Đó quy tắc phân tích thiết kế hướng đối tượng bản, mang tính chất khái quát Do nguyên lý nên có tính trừu tượng cao khơng vào chi tiết cách thức giải vấn đề cụ thể (việc thực hóa ngun lý lập trình hướng đối tượng đòi hỏi phải xem xét đến Design Patterns) I, Nguyên lý Open-Closed (The Open-Closed Principle) Phát biểu Các thực thể phần mềm (hàm, đơn thể, đối tượng, …) nên xây dựng Tiểu luận tài theo hướng mở cho việc mở rộng (be opened for extension) đóng việc sửa đổi (be closed for modification) Nội dung Các thực thể phần mềm khơng đứng riêng lẻ mà có gắn kết chặt chẽ với Chúng phối hợp hoạt động để thực chức phần mềm Do đó, việc nâng cấp, mở rộng thực thể ảnh hưởng đến thực thể liên quan Điều dẫn đến việc phải nâng cấp, mở rộng thực thể liên quan Và thời đại đầy biến động nay, việc phải thường xuyên nâng cấp, mở rộng thực thể phần mềm điều khó tránh khỏi Để làm cho trình bảo trì, nâng cấp, mở rộng phần mềm diễn dễ dàng hiệu hơn, thực thể phần mềm nên xây dựng tuân theo nguyên lý Open-Closed Điều có nghĩa thực thể phần mềm nên xây dựng cho việc nâng cấp, mở rộng đồng nghĩa với việc thêm vào thay đổi có, từ tránh việc phải thay đổi thực thể liên quan Xét ví dụ đoạn chương trình vẽ đường thẳng hình chữ nhật C# public enum ShapeType { LINE, RECTANGLE } public abstract class Shape { public abstract ShapeType getType(); Tiểu luận tài } public class Line: Shape { public override ShapeType getType() { return ShapeType.LINE; } public void drawLine() { // Draws the line } } public class Rectangle: Shape { public override ShapeType getType() { return ShapeType.RECTANGLE; } public void drawRectangle() { // Draws the rectangle } } Tiểu luận tài public void draw(ArrayList shapeList) { Line line; Rectangle rectangle; foreach (Shape s in shapeList) switch (s.getType()) { case ShapeType.LINE: line = (Line)s; line.drawLine(); break; case ShapeType.RECTANGLE: rectangle = (Rectangle)s; rectangle.drawRectangle(); break; } } Đoạn chương trình hoạt động tốt có nâng cấp, mở rộng Giả sử cần nâng cấp, mở rộng đoạn chương trình để vẽ thêm hình trịn Lúc ta phải chỉnh sửa lại hàm “draw”, thêm vào trường hợp vẽ hình trịn Và nhiều tình huống, việc chỉnh sửa hàm “draw” dẫn đến việc chỉnh sửa hàm khác liên quan Hàm “draw” viết theo cách nói khơng tn thủ ngun lý Open-Closed Để đoạn chương trình tuân thủ nguyên lý Open-Closed, sử dụng tính đa Tiểu luận tài hình lập trình hướng đối tượng public abstract class Shape { public abstract void draw(); } public class Line: Shape { public override void draw() { // Draws the line } } public class Rectangle: Shape { public override void draw() { // Draws the rectangle } } class Circle: Shape { public override void draw() { // Draws the circle } } public void draw(ArrayList shapeList) { foreach (Shape s in shapeList) s.draw(); } Với đoạn chương trình trên, thêm hình vào, việc thêm lớp Tiểu luận tài đối tượng cho hình (kế thừa từ Shape) mà khơng cần phải chỉnh sửa lại hàm “draw” Nó hoạt động tốt với hình thêm vào Ghi i) Không phải lúc tất thực thể phần mềm tuân thủ nguyên lý Open-Closed Nhưng mục tiêu phân tích thiết kế hướng đối tượng phải cho số lượng thực thể tuân thủ nguyên lý lớn nhất, ưu tiên thực thể thường xuyên phải nâng cấp, mở rộng thỏa nguyên lý ii) Việc tuân thủ nguyên lý Open-Closed thực thể phần mềm mang tính tương đối, phụ thuộc vào ngữ cảnh Có thể ngữ cảnh này, thực thể thỏa nguyên lý, ngữ cảnh khác, thực thể không tuân thủ nguyên lý Mục tiêu phân tích thiết kế hướng đối tượng phải cho có nhiều thực thể phần mềm tuân thủ nguyên lý ngữ cảnh thường xảy phần mềm, ưu tiên thực thể thường xuyên phải nâng cấp, mở rộng thỏa nguyên lý Ví dụ trường hợp hàm “draw” đoạn chương trình vẽ hình public void draw(ArrayList shapeList) { foreach (Shape s in shapeList) s.draw(); } Hàm “draw” thỏa nguyên lý ngữ cảnh nâng cấp mở rộng “thêm hình mới” Nếu cần nâng cấp, mở rộng theo hướng thay đổi thứ tự vẽ hình hàm “draw” khơng thể đáp ứng Khi khơng cịn tn thủ ngun lý iii) Một tính chất quan trọng lập trình hướng đối tượng giúp cho thực thể phần mềm tăng khả tuân thủ nguyên lý Open-Closed tính đóng gói (encapsulation) Đối tượng nắm giữ thơng tin chịu trách nhiệm thơng tin nắm giữ Điều giúp hạn chế kết dính (coupling) lớp đối tượng Tiểu luận tài với Trường hợp lý tưởng tất thuộc tính đối tượng đặt tầm vực private việc thay đổi thuộc tính thực hiên thơng qua xử lý phương thức Những phương thức đối tượng khác, kể đối tượng kế thừa truy xuất đến thuộc tính iv) Việc hạn chế sử dụng ép kiểu động (runtime type-casting) thực thể phần mềm giúp làm tăng khả tuân thủ nguyên lý Open-Closed chúng Vì chất việc ép kiểu động làm việc với kiểu liệu cụ thể Khi muốn nâng cấp, mở rộng thực thể để làm việc với kiểu liệu khác, đoạn chương trình sử dụng ép kiểu động phải thay đổi để làm việc với kiểu liệu khác public void doSomething(Vehicle vehicle) { Car car = (Car)vehicle; car.run(); car.stop(); } Khi cần nâng cấp, mở rộng để đoạn chương trình làm việc với lớp đối tượng khác kế thừa từ “Vehicle”, phải chỉnh sửa lại Ý nghĩa: Nguyên lý Open-Closed nguyên lý cốt lõi bốn nguyên lý làm tảng cho phân tích thiết kế hướng đối tượng Nó giúp cho phần mềm dễ bảo trì, nâng cấp mở rộng II, Nguyên lý Nghịch đảo phụ thuộc (The Dependency Inversion Principle) Phát biểu: Các thành phần phần mềm không nên phụ thuộc vào riêng, cụ thể (details) mà ngược lại nên phụ thuộc vào chung, tổng quát (abstractions) riêng, cụ thể Những chung, tổng qt (abstractions) khơng nên phụ vào riêng, cụ thể (details) Sự phụ thuộc nên đảo ngược lại Nội dung Tiểu luận tài Những chung, tổng quát tập hợp đặc tính chung từ riêng, cụ thể Những riêng, cụ thể dù khác tuân theo quy tắc chung mà chung, tổng quát định nghĩa Những chung, tổng quát thay đổi biến động Trong đó, thay đổi lại thường xuyên xảy riêng, cụ thể Việc phụ thuộc vào chung, tổng quát giúp cho thành phần phần mềm trở nên linh động (flexible) thích ứng tốt với thay đổi thường xuyên diễn riêng, cụ thể Khi phụ thuộc vào chung, tổng quát, thành phần phần mềm hoạt động tốt mà không cần phải sửa đổi riêng, cụ thể thay riêng, cụ thể khác loại Lấy ví dụ đoạn chương trình đọc liệu từ bàn phím xuất máy in public void copy() { Keyboard keyboard = new Keyboard(); Printer printer = new Printer(); char c; while ((c = keyboard.read()) != ‘q’) printer.write(c); } Khi nâng cấp, mở rộng đoạn chương trình để xuất liệu máy in tập tin phải chỉnh sửa lại đoạn chương trình sau public void copy(OutputType type) { Keyboard keyboard = new Keyboard(); Printer printer = new Printer(); File file = new File(); char c; while ((c = keyboard.read()) != ‘q’) Tiểu luận tài if (type == OutputType.PRINTER) printer.write(c); else if (type == OutputType.FILE) file.write(c); } Rõ ràng hàm “copy” vi phạm nguyên lý Open-Closed lần cần thêm thiết bị đọc ghi vào, phải chỉnh sửa lại Nguyên nhân làm cho hàm “copy” vi phạm nguyên lý Open-Closed làm việc với thiết bị đọc ghi cụ thể Khi thêm thiết bị đọc ghi mới, phải thêm vào hàm “copy” đoạn lệnh để làm việc với thiết bị đọc ghi Khi nói hàm “copy” vi phạm nguyên lý Nghịch đảo phụ thuộc Để đoạn chương trình tuân thủ Nguyên lý Nghịch đảo phụ thuộc, từ tuân thủ Nguyên lý Open-Closed, phải cho làm việc với thiết bị đọc ghi tổng quát 10 public void copy(Reader reader, Writer writer) { char c; while ((c = reader.read()) != ‘q’) writer.write(c); } Hàm “copy” làm việc tốt với thiết bị đọc ghi tuân thủ interface Reader Writer Khi cần thêm thiết bị đọc ghi mới, việc thêm lớp đối tượng kế thừa từ Reader Writer mà khơng phải chỉnh sửa lại hàm “copy” Trích lời Allen Holub: “The more abstraction you add, the greater the flexibility In today’s business environment, where requirements regularly change as program develops, this flexibility is essential.” Chú ý i) Nguyên lý Nghịch đảo phụ thuộc có mối liên hệ mật thiết với nguyên lý Tiểu luận tài OpenClosed Một nguyên lý Nghịch đảo phụ thuộc bị vi phạm, có nghĩa thành phần phần mềm phụ thuộc vào riêng, cụ thể, việc nâng cấp, mở rộng riêng, cụ thể (điều thường xảy ra) buộc thành phần phụ thuộc vào bị thay đổi theo Điều dẫn đến vi phạm nguyên lý Open-Closed ii) Sự nghịch đảo đề cập đến nhằm nhấn mạnh đến việc cần phải thay đổi quan điểm phân tích thiết kế phần mềm Theo lối suy nghĩ “chia để trị” lập trình hướng cấu trúc, cơng việc lớn, phức tạp, mang tính trừu tượng cao thường phân thành công việc nhỏ, đơn giản cụ thể Khi đó, cấu trúc phần mềm có xu hướng theo dạng thành phần lớn (trừu tượng) gọi đến thành phần nhỏ (cụ thể) để yêu cầu chúng thực công việc Điều thường làm cho thành phần phần mềm phụ thuộc vào riêng, cụ thể Trong phân tích thiết kế hướng đối tượng, phụ thuộc nên đảo ngược lại iii) Một thành phần phần mềm vi phạm ngun lý Nghịch đảo phụ thuộc có tính tái sử dụng (reusability) không cao Việc mang thành phần sử dụng vào 11 ngữ cảnh khác với riêng, cụ thể khác khó thực không thực việc chỉnh sửa chúng iv) Một quy ước lập trình hướng đối tượng giúp cho thành phần phần mềm tăng khả tuân thủ nguyên lý Nghịch đảo phụ thuộc thực việc truy xuất đến đối tượng thông qua interface chúng Điều làm cho thành phần bên phần mềm có tính linh động (flexibility) cao, khơng phải sửa đổi thay đối tượng truy xuất đến đối tượng khác loại public void doSomething(Car car) { car.run(); car.stop(); } public void doSomething(Vehicle vehicle) { vehicle.run(); vehicle.stop(); Tiểu luận tài } Trong hai đoạn chương trình trên, đoạn chương trình thứ hai làm việc tốt thêm vào đối tượng khác loại với “Car” mà kế thừa từ “Vehicle” Ý nghĩa: Nguyên lý Nghịch đảo phụ thuộc có mối liên hệ mật thiết với nguyên lý Open-Closed bốn nguyên lý làm tảng cho phân tích thiết kế hướng đối tượng Nó giúp cho phần mềm có tính tái sử dụng cao, linh động bền vững (robustness) trước thay đổi III, Nguyên lý Thay Liskov (The Liskov Substitution Principle) Phát biểu Lớp B nên kế thừa từ lớp A với hàm F thao tác đối tượng A, cách cư xử (behaviors) F không thay đổi ta thay (substitute) đối tượng A đối tượng B 12 Nội dung: Kế thừa (inheritance) tính chất lập trình hướng đối tượng Đó khả định nghĩa lớp đối tượng dựa lớp đối tượng định nghĩa trước Các đối tượng lớp kế thừa có khả cư xử (behave) đối tượng lớp sở Điều có nghĩa đối tượng lớp kế thừa hoàn toàn thay đối tượng lớp sở hàm thao tác đối tượng lớp sở Chính tính chất mà sử dụng kế thừa cách tùy tiện Giả sử ta có lớp A hàm F thao tác đối tượng A Để nâng cấp, mở rộng phần mềm, ta cần thêm vào lớp B kế thừa từ A Nhưng việc thay đối tượng A đối tượng B lại làm cho F cư xử sai lệch so với trước thực việc thay Lúc này, để F cư xử khơng đổi so với trước, ta phải chỉnh sửa lại F Điều làm cho F vi phạm nguyên lý Open-Closed Tiểu luận tài dụng nguy hiểm Đoạn chương trình sau cho thấy việc kế thừa tùy tiện với mục đích tái sử public class Stack { private ArrayList data; // More data members of stack P ublic virtual void push(int n) { // Pushes n to stack } public virtual int pop() { // Pops value from stack } } public class Queue: Stack { // Data members of Queue public override void push(int n) 13 { // Pushes n to queue } public override int pop() { // Pops value from queue } } public int func(Stack p) { p.push(5); p.push(6); p.push(7); int a = p.pop(); int b = p.pop(); Tiểu luận tài if (a == && b == 6) return a * b; throw new ArgumentException(); } Với mục đích tái sử dụng số thuộc tính phương thức “Stack”, cho “Queue” kế thừa từ Stack Xét hàm “func” thao tác đối tượng “Stack”, “Queue” kế thừa từ “Stack” nên hồn tồn truyền đối tượng “Queue” vào hàm Nhưng cách cư xử hàm “func” thao tác đối tượng “Stack” “Queue” khác Với đối tượng “Stack” hàm func ln trả xác tích hai số Nhưng với đối tượng “Queue” hàm func lại gây exception Để hàm “func” cư xử đối tượng “Stack” “Queue” nhau, phải viết lại Điều làm cho hàm “func” vi phạm nguyên lý Open-Closed Khi ta nói hàm “func” vi phạm nguyên lý Thay Liskov Chú ý i) Nguyên lý Thay Liskov có mối liên hệ mật thiết với Nguyên lý Open-Closed Sự vi phạm nguyên lý Thay Liskov dẫn đến vi phạm nguyên lý Open-Closed 14 Một thực thể phần mềm vi phạm nguyên lý Thay Liskov cư xử khác đối tượng lớp sở lớp kế thừa Để thực thể phần mềm làm việc tốt đối tượng lớp sở lớp kế thừa, phải chỉnh sửa lại Điều dẫn đến vi phạm nguyên lý Open-Closed ii) Không phải lúc tất thực thể phần mềm tuân thủ nguyên lý Thay Liskov Nhưng mục tiêu phân tích thiết kế hướng đối tượng phải cho số lượng thực thể tuân thủ nguyên lý lớn nhất, ưu tiên thực thể thường xuyên phải nâng cấp, mở rộng thỏa nguyên lý iii) Việc tuân thủ nguyên lý Thay Liskov thực thể phần mềm mang tính tương đối, phụ thuộc vào ngữ cảnh Có thể ngữ cảnh này, thực thể thỏa nguyên lý, ngữ cảnh khác, thực thể khơng cịn tn thủ ngun lý Mục tiêu phân tích thiết kế hướng đối tượng phải cho có nhiều thực thể phần mềm tuân thủ nguyên lý ngữ cảnh thường xảy phần mềm, Tiểu luận tài ưu tiên thực thể thường xuyên phải nâng cấp, mở rộng thỏa nguyên lý iv) Quan hệ “IS-A” thường dùng để phát kế thừa Khi lớp đối tượng B mặt ngữ nghĩa trường hợp đặc biệt lớp đối tượng A ta cho B kế thừa từ A Nhưng thực tế cho thấy, số ngữ cảnh phần mềm, lớp đối tượng có quan hệ “IS-A” với lớp đối tượng khác việc để kế thừa lớp đối tượng dẫn đến việc vi phạm nguyên lý Thay Liskov Xét đoạn chương trình sau public class Rectangle { // Data members of rectangle // Member functions of rectangle } public class Square: Rectangle { 15 // Data members of square // Member functions of square } public double doSomething(Rectangle obj) { obj.setWidth(5); obj.setHeight(6); if (obj.Area == 30) return obj.Area; throw new ArgumentException(); } Ở đoạn chương trình trên, mặt ngữ nghĩa, hình vng trường hợp hình chữ nhật Điều hoàn toàn đúng!!! Nhưng ngữ cảnh này, việc để “Square” kế thừa “Rectangle” không phù hợp Lúc hàm “doSomething” cư xử khác đối tượng “Rectangle” “Square” Như hàm “doSomething” vi phạm nguyên lý Thay Liskov Để hàm “doSomething” làm việc Tiểu luận tài “Rectangle” “Square” phải chỉnh sửa lại Như việc vi phạm nguyên lý Thay Liskov làm cho hàm “doSomething” vi phạm nguyên lý Open-Closed v) Nguyên lý Thay Liskov có mối liên hệ mật thiết với kỹ thuật “Design by Contract” đề cập Bertrand Meyers Kỹ thuật rằng: phương thức lớp đối tượng, định nghĩa, hàm chứa tiền điều kiện (precondition) hậu điều kiện (post-condition) Tiền điều kiện điều kiện cần để phương thức thực Hậu điều kiện ràng buộc phát sinh sau thực phương thức Khi thực việc kế thừa, phương thức định nghĩa lại lớp kế thừa phải có tiền điều kiện lỏng lẻo (weaker) hậu điều kiện chặt chẽ (stronger) Điều có nghĩa trước thực hiện, phương thức định nghĩa lại lớp kế thừa không địi hỏi nhiều định nghĩa lớp sở Và sau thực hiện, phương thức định nghĩa lại lớp kế thừa phải đảm bảo tất ràng buộc phát sinh định nghĩa lớp sở Chỉ điều đáp ứng cho phương thức lớp kế thừa lớp kế thừa 16 xem cư xử lớp sở Và đó, việc để kế thừa từ lớp sở đắn ngữ cảnh phần mềm xét vi) Nguyên lý Thay Liskov kỹ thuật “Design by Contract” vơ tình làm cho việc kế thừa trở nên khó thực Khi cần thêm vào lớp kế thừa, phải xem xét kỹ lưỡng lại tất hàm có thao tác lớp sở xem chúng có vi phạm nguyên lý Thay Liskov hay không Chúng ta cần phải xem xét tất phương thức lớp kế thừa xem chúng có vi phạm quy định kỹ thuật “Design by Contract” hay không Tất điều lớp kế thừa có mối liên hệ mật thiết với lớp sở Lớp kế thừa bị kết dính (coupling) chặt chẽ với lớp sở Sự kết dính rõ ràng làm cho phần mềm linh động (flexibility) có thay đổi xảy Do đó, để hạn chế kết dính mà đảm bảo tính tái sử dụng, nên kế thừa interface sử dụng composition thay cho việc kế thừa Ý nghĩa: Nguyên lý Thay Liskov có mối liên hệ mật thiết với nguyên lý Open- Tiểu luận tài Closed bốn nguyên lý làm tảng cho phân tích thiết kế hướng đối tượng Nó giúp nâng cao tính tái sử dụng bền vững phần mềm trước thay đổi IV, Nguyên lý Phân tách interface (The Interface Segregation) Phát biểu Không nên buộc thực thể phần mềm phụ thuộc vào interface mà chúng không sử dụng đến Nội dung Khi xây dựng lớp đối tượng, đặc biệt lớp trừu tượng (abstract class), nhiều người thường có xu hướng lớp đối tượng thực nghiều chức tốt, đưa thật nhiều thuộc tính phương thức vào lớp đối tượng Những lớp đối tượng gọi lớp đối tượng có interface bị “ô nhiễm” (fat interface or polluted interface) Khi lớp đối tượng có interface bị “ơ nhiễm”, trở nên cồng kềnh Một thực thể phần mềm cần thực công việc đơn giản mà 17 lớp đối tượng hỗ trợ buộc phải làm việc với tồn interface lớp đối tượng Việc phải truyền truyền lại nhiều lần đối tượng có interface bị “ơ nhiễm” làm giảm hiệu phần mềm Đặc biệt lớp trừu tượng có interface bị “ơ nhiễm”, số lớp kế thừa quan tâm đến phần interface lớp sở bị buộc phải thực việc cài đặt cho phần interface khơng có ý nghĩa chúng Điều dẫn đến dư thừa không cần thiết thực thể phần mềm Quan trọng nữa, việc buộc lớp kế thừa phụ thuộc vào phần interface mà chúng không sử dụng đến làm tăng kết dính (coupling) thực thể phần mềm Một nâng cấp, mở rộng diễn ra, địi hỏi phần interface phải thay đổi, lớp kế thừa bị buộc phải chỉnh sửa theo Điều làm cho chúng vi phạm nguyên lý Open-Closed Hình bên dươi sơ đồ lớp cho đoạn chương trình tính điện trở mạch điện “Resistor” “Lamp” mạch điện đơn giản với điện trở thuộc Tiểu luận tài điện phức hợp với điện trở mạch tính từ mạch điện Để có tính mạch Trong “SeriesCircuit” “ParallelCircuit” mạch thể cư xử loại mạch điện hay nói cách khác truy xuất đến chúng cách “trong suốt” (transparency), có “Circuit” lớp trừu tượng chung đại diện cho mạch điện khác Lớp “Circuit” thiết kế gọi có interface bị “ơ nhiễm” “Resistor” “Lamp” bị buộc phải thực việc cài đặt cho phương thức “add” “remove” hoàn tồn chẳng có ý nghĩa với chúng Điều gây dư thừa code không cần thiết gây “khó chịu” cho thực thể phần mềm khác sử dụng “Resistor” “Lamp” Nhưng vấn đề thật xảy nâng cấp, mở rộng đoạn chương trình Giả sử cần thêm vào phương thức “removeAt” để hỗ trợ việc xóa mạch điện vị trí mạch điện phức hợp Lúc này, phải thực việc chỉnh sửa tất lớp đối tượng kế thừa từ “Circuit” Việc ch ỉnh sửa “SeriesCircuit” “ParallelCircuit” xem cịn 18 chấp nhận Nhưng việc phải chỉnh sửa “Resistor” “Lamp” khơng thể chấp nhận phương thức “removeAt” chẳng có ý nghĩa chúng Điều rõ ràng làm cho “Resistor” “Lamp” vi phạm ngun lý Open-Closed cách “khơng đáng” Chú ý i) Nguyên lý Phân tách interface có mối liên hệ với nguyên lý Open-Closed Sự vi phạm nguyên lý Phân tách interface có khả dẫn đến vi phạm nguyên lý Open-Closed (xem phân tích trên) ii) Để tránh vi phạm nguyên lý Phân tách Inteface, nên giữ cho interface lớp đối tượng đơn giản gọn nhẹ, nên làm theo tiêu chí “a class should one thing and it well” Chúng ta không nên lớp đối tượng đảm nhận nhiều trách nhiệm điều dễ làm cho interface bị “ơ nhiễm” Tiểu luận tài iii) Interface bị “ô nhiễm” lớp đối tượng nên phân tách để tránh khả dẫn đến vi phạm nguyên lý Open-Closed Việc phân tách interface bị “ô nhiễm” lớp sở thực thơng qua việc tăng thêm mức độ trừu tượng kế thừa Lớp sở ban đầu nên có interface đơn giản mà lớp kế thừa cần phải có Sau đó, phần interface chung phận lớp kế thừa tổng hợp lại lớp sở Và lớp sở lại kế thừa từ lớp sở ban đầu Như lớp kế thừa thuộc nhánh khác không bị phụ thuộc vào phần interface mà chúng không sử dụng đến phận lớp kế thừa Với trường hợp đoạn chương trình tính điện trở mạch điện, để giải vấn đề interface “Circuit” bị “ô nhiễm”, tăng thêm mức độ trừu tượng kế thừa Khi đó, “Circuit” đóng vai trị lớp trừu tượng cho mạch điện khác Nó chứa phần interface chung tất mạch điện Và ngữ cảnh tốn tính điện trở đơn giản chứa phương thức “calcResistance” 19 Chúng ta có lớp “SingleCircuit” đại diện cho mạch điện đơn giản “ComplexCircuit” đại diện cho cách mạch điện phức hợp “SingleCircuit” chứa phần interface chung mạch điện đơn giản “Resistor” “Lamp” “ComplexCircuit” chứa phần interface chung mạch điện phức hợp Chúng ta có kế thừa hình bên Lúc này, cần thêm vào phương thức “removeAt” việc nâng cấp phần interface “ComplexCircuit”, nhánh kế thừa bên “SingleCircuit” không bị ảnh hưởng iv) Trong số trường hợp, sau phân tách interface, số lớp kế thừa thêm vào muốn sử dụng phần interface phân tách, chúng thực việc đa kế thừa từ lớp đối tượng hỗ trợ phần interface kế thừa từ lớp đối tượng hỗ trợ phần interface chúng cần thực composition đối tượng hỗ trợ phần interface lại Ý nghĩa Tiểu luận tài bốn nguyên lý làm tảng cho phân tích thiết kế hướng đối Nguyên lý Phân tách interface có mối liên hệ với nguyên lý Open-Closed tượng Nó giúp giảm cồng kềnh, dư thừa không cần thiết cho phần mềm quan trọng giảm kết dính (copuling) làm hạn chế tính linh động (flexibility) phần mềm 20

Ngày đăng: 30/01/2024, 10:02

Tài liệu cùng người dùng

  • Đang cập nhật ...