Tìm hiểu thiết kế hướng đối tượng trong Rails
Bài đăng này đã không được cập nhật trong 8 năm
Tìm hiểu thiết kế hướng đối tượng trong Ruby on Rails
I. Giới thiệu
Như chúng ta đã biết, thiết kế là một trong những công việc khó nhất của lập trình. Không phải là các kỹ thuật lập trình, các kiến thức về hệ thống, server hay kỹ thuật về rails, ruby mà chính là kỹ năng về thiết kế hệ thống mới là nhân tố quyết định để xây dựng một hệ thống thành công, hay đảm bảo tính mở rộng và hiệu quả của hệ thống đó.
Nó cũng là cơ sở để phân biệt đâu là kỹ sư hay một thợ code. Qua thực tế dự án của tôi, tôi quả thật đã hiểu được tầm quan trọng của việc thiết kế, vì khi yêu cầu khách hàng thay đổi, thì chức năng bổ sung, code sẽ tăng nhanh, nên các model hay các file phình to là điều không tránh khỏi. Đó là cơ duyên đã dẫn tôi đến với cuốn sách "Pratical Object-oriented design in ruby", đây thực sự là cuốn sách giúp tôi mở ra các hướng đi để giải quyết các khó khăn trên quá trình thực hiện project của mình.
Ở bài viết này, tôi sẽ giới thiệu về chương đầu tiên đó là tổng quát về thiết kế hướng đối tượng trong Ruby
II. Chương I: Thiết kế hướng đối tượng
Lợi ích của thiết kế
Các phần mềm được thiết kế với một lý do nào đó. Ví dụ như ứng dụng về một game hay một chương trình để hướng dẫn trị liệu xạ trị. Nếu phải lập trình vất vả là cách tốt nhất để sản xuất các phần mềm thì các lập trình viên bắt buộc phải kiên nhẫn hoặc là đi tìm công việc khác. Thật may mắn, bạn không cần phải chọn giữa niềm vui và hiệu quả. Các kỹ thuật lập trình có thể làm cho viết code như một niềm vui để viết đè lên các sản phẩm phần mềm hiệu quả nhất.
Các kỹ thuật của thiết kế hướng đối tượng giải quyết các tình huống khó trong lập trình, theo đuổi tạo ra các sản phầm hiệu quả, sử dụng code cũng là một niêm vui trong công việc.
Các biện pháp để giải quyết các vấn đề trong thiết kế
Tưởng tượng đang viết một ứng dụng mới, ứng dụng đấy được bao gồm một tập các yêu cầu chính xác và hoàn thiện. Và tưởng tượng nhiều hơn nữa, là ứng dụng này không bao giờ cần thay đổi. Với trường hợp này, việc thiết kế không phải là vấn đề đáng quan tâm. Nhưng thật không may mắn, một vài thứ sẽ thay đổi. Nó luôn luôn là vậy. Khách hàng không biết họ muốn gì, họ không nói ra chúng nghĩa là gì. Bạn không thể hiểu được họ cần gì, để biết được cách giải quyết tốt hơn. Thậm chí các ứng dụng mà hoàn hảo thì cũng không ổn định. Ứng dụng là một thành công rất lớn, và mọi người luôn muốn nhiều hơn. Sự thay đổi là không thể tránh khỏi. Đó là chuyện quá bình thường.
Việc thay đổi các yêu cầu tương đương với ma sát và trọng lực. Chúng xuất hiện bất ngờ và các áp lực không tránh khỏi là các vấn đề chống lại việc lập kế hoạch. Đó là sự cần thiết cho sự thay đổi về vấn đề thiết kế.
Các ứng dụng mà dễ dàng thay đổi là một niềm vui để viết và mở rộng. Chúng mềm dẻo và có khả năng thích nghi. Các ứng dụng chống lại sự thay đổi thì ngược lại, mọi thay đổi là tốn kém và đều làm cho nâng giá sản phẩm. Có ít ứng dụng rất khó để thay đổi đang được thực hiện. Càng ngày chúng càng trở nên như các bộ phim kinh dị mà trong đấy bạn như là một người lập trình thiếu may mắn, phải chạy kiệt sức chán nản từ một vòng xoáy đến vòng kế tiếp, cố gắng ngăn chạn các âm thanh của việc đổ vỡ.
Tạo sao sự thay đổi là rất khó khăn
Các ứng dụng hướng đối tượng được bao gồm từ các phần tương tác để hình thành nên các chức năng. Các thành phần là các đối tương, sự tương tác được thể hiện trong các thông điệp qua lại giữa chúng. Để thông điệp tìm đến đúng đối tượng yêu cầu người gửi thông điệp đấy biết mọi thứ về người nhận. Điều đó tạo nên sự phụ thuộc giữa hai đối tượng và các sự phụ thuộc này được hình thành theo hướng của sự thay đổi.
Thiết kế hướng đối tượng là công việc quản lý các sự phụ thuộc. Nó là một tập các kỹ thuật viết code để sắp xếp các sự phụ thuộc đấy thành các đối tượng đảm bảo ổn định với các thay đổi. Tuy nhiên trong một khía cạnh của thiết kế, các sự phụ thuộc không được quản lý sẽ tạo ra sự tàn phá bởi vì các đối tượng này biết quá nhiều về đối tượng liên quan của nó. Thay đổi một đối tượng sẽ khiến cho thay đổi đối tượng liên quan và ngược lại. Một sự hợp tác không hiệu quả dẫn đến thiệt hại lan tảo dần ra bên ngoài, dần đến toàn bộ quá trình thực hiện, và rồi không có code nào được thực hiện nữa.
Khi các đối tượng biết quá nhiều vị trí của họ trong toàn hệ thống, chúng sẽ trở nên cầu kỳ, và cần các thứ là "chỉ như vậy". Các trông mong này ngược lại với họ. Các đối tượng đảm bảo được tái sử dụng trong các bối cảnh khác nhau, họ khó để test và dễ dàng bị lặp lại.
Trong một ứng dụng nhỏ, thiết kế tồi vấn có thể chập nhận được, vần tồn tại được. Thậm chí nếu mọi thứ được kết nối, nếu bạn có thể giữ tất cả trong đầu thì bạn vẫn có thể cải thiện được chương trình. Vấn đế với các ứng dụng nhỏ mà có thiết kế tồi là nếu chúng thành công, chúng có thể phát triển thành các ứng dụng lớn được thiết kế tồi. Và dần dần trở nên là nỗi kinh hoàng mà bạn muốn vứt bỏ. Sự thay đổi đơn giản có thể được thực hiện trong chương trình, phá bỏ code ở mọi nơi và yêu cầu viết lại. Các test case đều lỗi và bắt đầu cảm thấy giống như một trở ngại hơn là một sự hỗ trợ.
Khái niệm của thiết kế
Mọi chương trình là một tập hợp của code, sự sắp xếp code chính là thiết kế. 2 lập trình viên độc lập, thậm chí khi họ chia sẽ các ý tưởng chung về thiết kế, họ có thể tiến hành giải quyết các vấn đề giống nhau bằng cách sắp xếp code theo các cách khác nhau. Thiết kế không là một sợ dây kết nối các nhân viên được huấn luyện xây dựng các vật dụng giống nhau, nó là một phòng thu nơi các nghệ sĩ tài năng tạo ra các sản phẩm tùy chỉnh. Thiết kế như là một nghệ thuật, nghệ thuật của việc sắp xếp code.
Khó khăn của thiết kế là mọi vấn đề có 2 thành phần. Bạn không chỉ phải viết code theo đặc tả mà bạn lập kế để thực hiện hằng ngày, bạn cũng phải tạo ra code mà có thể được thay đổi về sau. Với từng giai đoạn mở rộng từ phiên bản ban đầu, chi phí về sự thay đổi sẽ xóa bỏ chi phí ban đầu của ứng dụng. Bởi vì thiết kế tuân thủ nguyên tắc chồng chéo và mọi vấn đề bao gồm một biểu đồ thời gian, các chiến lược thiết kế có thể bao gồm một số lượng giải pháp. Công việc của bạn là kết nối tất cả các yêu cầu của ứng dụng với vấn đề chi phí và lợi ích của thiết kế và sau đó là thực hiện sắp xếp code hiệu quả trong hiện nay mà sẽ có thể được tiếp tục trong tương lai.
Theo đuổi tương lai có thể dường như là cần thiết phải có các khả năng về tâm trí để suy xét các hiện thực nằm bên ngoài việc lập trình. Không chỉ vậy, thiết kế cho tương lai không chỉ là bạn khắc phục các yêu cầu chưa biết và chọn trong số chúng để thực hiện ngay bây giờ. Các lập trình viên không phải là nhà siêu linh. Việc thiết kế mà đoán trước được các yêu cầu cụ thể trong tương lai là hầu như luôn luôn có kết cục tồi tệ. Các thiế kế thực tế không thể đoán trước điều gì sẽ xảy ra cho ứng dụng của bạn, nó chỉ có thể chấp nhận một vài thứ và trong hiện tại bạn không thể biết là cái gì. Nó không thể đoán được tương lại, nó giữ lại các vấn đề của bạn cho tương lai về sau. Nó không được chọn và sẽ rời bỏ bạn.
Mục đích của thiết kế là cho phép bạn thiết kế trước và mục tiêu cơ bản là giảm bớt chi phí của thay đổi.
Các công cụ của thiết kế
**Nguyên tắc trong thiết kế
Thuật ngữ SOLID được tạo ra bởi Michael Feathers và được phổ biến bởi Robert Martin, chỉ ra 5 nguyên tắc của thiết kế hướng đối tượng:
- Single Responsibility
- Open-Closed
- Liskov Substitution
- Interface Segregation
- Dependency Inversion
Các nguyên tắc khác là DRY (Don't repeat yourself) và law of demeter (LoD)
Các nguyên tắc này sẽ được diễn tả trong quyển sách này, câu hỏi đặt ra bây giờ là chúng đến từ đâu? Các nguyên tắc này đã được chúng minh hay chỉ là các quan điểm của ai đó?
Tất cả các nguyên tắc này đều bắt đầu như là các lựa chọn của bất cứ khi viết code. Các lập trình viên hướng đối tượng đều thây được đó các cách sắp xếp code mà khiến cho công việc họ dễ dàng hơn. Các kinh nghiệm đó dẫn họ đến các quan điểm phát triển về làm thế nào để viết code đẹp.
Các viện nghiên cứu cuối cùng cũng tham gia, xây dựng nên các luận án về chất lượng tốt. Điều đó thật tuyệt vời. Nếu chúng ta có thể đếm mọi thứ, tính toán theo các thước đo về code của bạn hay dựa vào các tính toán đó cho các ứng dụng chất lượng cao hay thập, chúng ta có thể làm nhiều hơn thế nữa. Bằng các thước đo chất lượng, ta có thể thay đổi thiết kế hướng đối tượng từ không thể đo đếm thành có thể đếm được.
Các mẫu thiết kế
Trong các nguyên tắc thiết kế, thiết kế hướng đối tượng bao gồm các khuôn mẫu. Chúng được gọi là Gang of Four(GoF), nhóm 4 người là Erich Gamma, Richard Helm, Ralph Johnson, and Jon Vlissides, đã thực hiện nguyên cứu về các khuôn mẫu đó vào năm 1995. Cuốn cách Design Patterns mô tả các khuôn mẫu là các giải pháp đơn giản và có thể gọi là tạo nhã với các vấn đề cụ thể của thiết kế phần mềm hướng đối tượng mà bạn có thể sử dụng để tạo ra các thiết kế của chính mình mềm dẻo hơn, dễ tái sử dụng hơn, dễ phân tách hơn và dễ hiểu hơn.
Khái niệm của các mẫu thiết kế là rất lướn lao. Chúng có thể chỉ ra các vấn đề phổ biến và giải quyết các vấn đề đó theo các cách chung, khiến cho các vấn đề chưa rõ ràng thành cụ thể.
Các mẫu thiết kế đưa đến một thế hệ mới các lập trình viên theo hướng cộng tác và hợp tác.
Các mẫu có một vị trí trong các công cụ của người thiết kế. Mỗi mẫu thiết kế được biết là một giải pháp mở hoàn hảo các vấn đề cần được giải quyết. Tuy nhiên, các mẫu phổ biến đều là các kiểu được lạm dụng bởi các lập trình viên mới vào nghề, thực hiện các mẫu hiệu quả nhưng lại đặt sai vị trí. Kết quả thu được là sự phức tạp, lẫn lộn code nhưng đó không phải là do lỗi từ các mẫu thiết kế. Một công cụ không thể chịu lỗi cho cách dùng, mà chính là người sử dụng chúng.
Cuốn sách này không nói về các mẫu thiết kế, tuy nhiên, nó sẽ chuẩn bị cho bạn để hiểu chúng và cung cấp kiến thức cho việc lựa chọn và sử dụng một cách thích hợp.
Nghệ thuật thiết kế
Với khám phá về các nguyên tắc và các khuôn mẫu thiết kế phổ biến, tất các vấn đền thiết kế hướng đối tượng đã được giải quyết. Dựa theo các luật đã được biết tời, khó khăn như thế nào để có thể thiết kế phần mềm hướng đối tượng?
Khó khó khăn. Nếu bạn nghĩ phần mềm như đồ đạc tùy chỉnh, các thiết kế và các mẫu như các công cụ. Biết phần mêm nên được trông như thế nào khi nó hoàn thiện mà không dẫn đến xây dựng lại, các ứng dụng tồn tại bởi vì một vài lập trình viên đã sử dụng các công cụ đấy. Kết quả cuối cùng sẽ là một kệ tủ tuyệt đẹp hay một chiếc ghế sang trọng phản ánh dựa theo kinh nghiệm của lập trình viên với các công cụ thiết kế.
Như thế nào là thiết kế bị lỗ
Cái nhìn đầu tiên, các sự thất bại trong thiết kế là vì thiếu thiết kế. Các nhà lập trình có ít kiến thức về thiết kế. Điều này là bình thường, tuy nhiên, nó có thể tạo ra các chương trình mà không cần biết yếu tố đầu tiên về thiết kế.
Đây là sự thật về ngôn ngữ hướng đối tương nhưng một vài ngôn ngữ khó khăn hơn và một ngôn ngữ dễ tiếp cận như Ruby là đặc biệt đáng kể.
Ruby rất thân thiện, là ngôn ngữ cho phép mọi người tạo ra các đoạn cript tự động thực hiện các công việc lặp đi lặp lại và một nền tảng Ruby on Rails để xây dựng ứng dụng web mà mọi lập trình viên đều đang sử dụng. Cú pháp của ngôn ngữ Ruby là rất dễ dùng mà mọi người đều có thể sử dụng khả năng của xâu vào thứ tự logic để tạo ra các chương trình. Các nhà lập trình mà không biết về thiết kế hướng đối tượng có thể rất thành công với Ruby.
Tuy nhiên, các ứng dụng thành công nhưng không được thiết kế tiềm ẩn nguy cơ thất bại. Chúng dễ dàng để viết nhưng dần sẽ trở nên không thể thay đổi. Một lập trình viên có thiếu kinh nghiệm không thể dự đoán được tương lại. Lời hứa về sự phát triển không có lỗi dần dần không còn hiệu lực và thái độ dần trở thành tuyệt vọng khi người lập trình bắt đầu đồng ý mọi yêu cầu thay đổi bằng cách: "Vâng, tôi có thể thêm chức năng này, nhưng nó sẽ phá bỏ mọi thứ"
Nhiều lập trình viên nhiều kinh nghiệm hơn sẽ mắc phải các thất bại về thiết kế khác nhau. Các lập trình viên này nắm về các kỹ thuật thiết kế hướng đối tương nhưng không hiểu cách áp dụng chúng. Với mong muốn tốt nhất, những lập trình viên này dần rơi vào bẫy của lạm dụng thiết kế. Một chút hiểu biết là rất nguy hiểm, như hiểu biết của họ tăng dần và hi vọng quay trở lại, họ thiết kế không ngừng. Khi vượt qua sự nhiệt huyets, họ sử dụng các nguyên tắc không thích hợp và thấy các khuôn mẫu ở noi chúng không tồn tại. Họ xây dựng nên các lâu đài code phức tạp và xinh đẹp và sau đó chán nản để tìm lại chính chúng nằm trong các bức tường đá. Bạn có thể nhận ra các lập trình viên đấy, bởi vì họ bắt đầu chào đón sự thay đổi với "Không, tôi không thể thêm đặc điểm này, nó không được thiết kế để làm vậy.".
Cuối cùng, phần mềm hướng đối tượng thất bại khi nghệ thuật thiết kế bị tách ra khỏi nghệ thuật lập trình. Thiết kế là một quá trình khám phá có tiến trình mà được ghi lại trên một vòng lặp phản hồi. Vòng phản hôi này nên được tính toàn và tăng dần, các công nghệ lặp lại của sư chuyển động phần mềm theo Agile do đó hiệu quả với các ứng dựng hướng đối tượng được thiết kế tốt. Bản chất lặp lại của phát triển theo Agile cho phép thiết kế điều chỉnh và phát triển dần dần. Khi thiết kế không được gắn với các sự điều chỉnh cần thiết có thể xảy ra thì thất bại là điều dễ hiểu. Các lập trình viên người chịu trách nhiệm viết các chương trình được thiết kế bởi các chuyên gia độc lập có thể nói: "Tuyệt quá, tôi chắc chắn có thể viết được nó, nhưng điều đó không phải là điều bạn thực sự muốn và cuối cùng bạn phải xin lỗi".
III. Summary
Trên đây là tầm quan trọng của thiết kế hướng đối tượng với việc phát triển phần mềm.
Đối với tôi, cuốn sách là có thể ví như phao cứu sinh cho con đường phát triển phần mềm của bản thân, nó đề cập đến các nguyên tắc để xây dựng nên một phần mềm có thiết kế đẹp và code đẹp mà bất cứ lập trình viên nào cũng muốn hướng đến _ art of code
Hẹn gặp lại trong phần tới sẽ đi sâu hơn về các nguyên tắc và vận dụng chúng trong xây dựng phần mềm với Rails.
Tài liệu tham khảo:
All rights reserved