3 nguyên tắc code mà bạn phải biết

Nghành công nghệ thông tin luôn phát triển với những concept, ngôn ngữ và kĩ thuật mới xuất hiện liên tục. Là những lập trình viên, hẳn chúng ta ai cũng đều có suy nghĩ “Làm sao mà mình theo kịp thay đổi và cạnh tranh được với bọn khác?”.

Hãy ngừng lại một chút, hít vào một hơi sâu để thư giãn và nghĩ về câu nói từ bộ phim tôi rất yêu thích, Casablanca:”Điều cơ bản luôn cần thiết bất kể thời đại nào”

Cho dù công nghệ có tiến bộ đến đâu chúng đều dựa trên những nền tảng cơ bản. Nếu bạn nắm vững được những kiến thức nền tảng trong phát triển phần mềm, thì việc học và điều chỉnh để thích hợp với các kĩ thuật mới sẽ trở nên rất dễ dàng. Trong bài viết này, chúng ta sẽ cùng bàn luận về 3 nguyên tắc nền tảng nhằm giúp các bạn trong việc tiếp cận với vô vàn các ứng dụng mời đầy phức tạp. Ngoài ra, tôi cũng sẽ đưa ra ý kiến cá nhân của mình và hi vọng sẽ giúp ích cho bạn khi áp dụng vào coding cũng như là các project khác.

Ngừng việc trùng lặp

Khi bạn bắt đầu một project software lớn, thường là ta sẽ bị “choáng” bởi khối lượng công việc cũng như sự phức tạp của chúng. Con người vốn không bao giờ giỏi với việc quản lí những thứ rối rắm, chúng ta mạnh về tìm ra giải pháp cho một vấn đề riêng lẻ. Một chiến lược thông dụng cho việc giảm bớt sự phức tạp trong quản lí là chia chúng thành những phần nhỏ hơn. Trước tiên, bạn sẽ muốn cắt chúng thành những thành phần đại diện cho hệ thống nhỏ hơn nhưng vẫn có đầy đủ chức năng để tự hoạt động được.

Một ví dụ điển hình, nếu bạn muốn tạo ra một hệ thống quản lí nội dung, thì phần chịu trách nhiệm cho quản lí người dùng sẽ được phân chia ra thành nhiều mảng như quản lí vai trò, quản lí bảo mật. Và những mảng vậy lại có thể chia nhỏ ra nữa cho đến khi level của sự phức tạp đã được giảm xuống chỉ còn một vấn đề duy nhất. Những vấn đề này sẽ được xử lí bởi Class. Class chứa đựng phương pháp và thuộc tính. Những phương pháp đó được thực hiện bằng các thuật toán trong lập trình. Có thể nói chúng tượng trưng cho một chuỗi thông tin nhỏ của sản phẩm.

Hãy là những người đầu tiên đăng ký vé Early Bird từ 01/04 – 15/04 với giá ưu đãi chỉ còn 150k

Tuy vậy theo nguyên tắc trên, những chuỗi thông tin này chỉ xuất hiện đúng một lần và sau đó ta phải sử dụng representation. Lí do là vì khi ta muốn đưa ra thay đổi thì thay vì phải sửa đi sửa lại hàng trăm lần những chuỗi thông tin thì với representation, ta chỉ cần sửa chuỗi đó một lần, những representation sẽ tự động thay đổi theo.

Đối với một ứng dụng hoàn hảo, thì tất cả những chuỗi thông tin đều sử dụng representation, thường là variable hoặc class property. Trong đó ta có thể hiểu chuỗi thông tin chứa class, class property chứa variable. Class đại diện cho một tính năng và variable đại diện cho một responsibility.

Quá trình này sẽ tiếp diễn cho đến khi ta đạt được top level của project với một stack presentation vô cùng phức tạp.

Làm thế nào để đạt được như vậy

Có nhiều cách để tránh việc bị trùng lập, Hunt và Thomas đề xuất sử dụng code generators cũng như là data transforming. Nhưng về cơn bản, là ta sử dụng representation để đại diện cho các chuỗi thông tin.

Và tất cả mọi part của phần mềm ứng dụng đề có thể xem là những representation khác nhau: quản lí người dùng sẽ cho phép xem thông tin về người sử dụng đã đăng kí dịch vụ, user class thể hiện một người dùng và những yếu tố (properties) liên quan như tên họ. Những yếu tố trên được thu thập từ representation của thư viện dữ liệu.

Để thực hiện được những điều trên thì ta phải lên kế hoạch thật tốt. Đặc biệt là khi bạn phải quản lí một project lớn thì việc sắp xếp và phân chia chúng thành nhiều component khác nhau và tiếp tục chia nhỏ chúng là một ý tưởng khá hay. Nhưng nhớ là làm theo những điều sau:

  • Hãy vẽ ra một bảng đồ cấp bật của phần mềm ứng dụng và component của nó. Project càng lớn thì càng cần có một kế hoạch tỉ mỉ.
  • Nếu bạn đã đến được level yêu cầu trách nhiệm để kết nối, thì bạn có thể cần phải đổi qua  UML diagram.
  • Trước khi viết ra một nùi code thì hãy phân cấp bật cho nó trong project phần mềm của bạn. Hãy xác định nó đại diện cho điều gì và vai trò của nó đối với những yếu tố xung quanh.
  • Xác định representation nào thì nên đưa ra cho người khác xem (vd: thông tin người dùng) và cái nào nên giấu đi (thông tin bảo mật)
  • Hãy chắc chắn rằng representation không dựa vào một representation khác (cũng như một component không thể sử dụng và dựa vào 1 class vốn đã nằm trong component khác).

Ngoài ra bạn cần phải lưu ý rằng: Khi bạn nhận ra mình đang viết những dòng code có vẻ “quen quen” hoặc là bị trùng lặp thì hãy tạm ngừng và tự hỏi mình đang làm gì để tránh việc trùng lặp tiếp tục diễn ra.

Việc tạo ra một app mà không hề có một dòng code trùng lập là rất khó và gần như bất khả thi luôn. Tuy vậy, ứng dụng dở với vô số code trùng lập thì nhiều không đếm kể khiến cho việc bảo trì những app như vậy là những cơn ác mộng. Vì thế mà không có gì ngạc nhiên khi tới hơn 50% số lượng project ứng dụng bị fail.

Nhiều người cho rằng code xấu là do coder dở. Thế nhưng theo kinh nghiệm của tôi thì đây lại là một trường hợp ngoại lệ. Bởi code xấu lại thường được tạo ra bởi account manager dở cũng như là việc quản lí tồi tệ của công ty trong quá trình thực hiện project.

Code xấu rất hiếm khi được tạo ra bởi coder dở

An Example

Bạn được thuê làm trong vai trò tư vấn kĩ thuật bởi một công ty đang gặp vấn đề với chất lượng code và việc bảo trì chúng. Bạn đang xem lại source và phát hiện ra một lượng lớn code bị trùng lập. Bạn ngay lập tức nhận ra đây là một sympton của code chất lượng kém. Thế nhưng nó vẫn chưa phải là nguyên nhân thật sự. Vì thế mà bạn quyết định xem lại bản record lịch sử của coding – bạn sẽ rằng chúng được thêm vào ngay gần lúc deadline. Hãy dành thời gian xem lại những thay đổi được đưa ra và bạn sẽ dễ dàng nhận ra những thay đổi tiếp theo cần có.

Như bài viết đã nói, phải viết code sao cho gọn mà không bị trùng lập. Có điều do quản lí kém, để đến gần deadline mới làm thì chỉ khiến developer phải dùng mánh khóe, khi đó thì coding chỉ để đạt được kết quả còn chất lượng thì đã bị bỏ xó rồi.

Không phải là chuyện ngẫu nhiên mà những công ty công nghệ thành công nhất luôn được thành lập bởi những coder thiên tài, có sử hiểu biết sâu rộng về kĩ thuật như Bill Gates, Mark Zuckerberg, Steve Wozniak, Steve Jobs, Larry Page, Sergey Brin và Larry Ellison. Họ đều tin rằng chỉ có nỗ lực mới có thể thành công. Tuy vậy, vẫn có nhiều công ty, tổ chức lại sử dụng những manager và lắng nghe những business consultant vốn chẳng có kinh nghiệm gì với việc IT.

Vì thế mà có rất nhiều ý tưởng chỉ thực hiện được trên giấy, slide powerpoint, trong photoshop hoặc là ở màn hình TV thôi. Có thể chúng thật sự thành công nếu trong thời kì của hưng thịnh của web. Thế nhưng ta đang sống trong thời đại mới với vô số ứng dụng có tương tác thông minh chạy trên đa platform. Bởi vì coder là người đứng ở tuyến cuối nên họ có khả năng sửa những lỗi sai ngay từ trong giai đoạn thai nghén lên ý tưởng. Tuy nhiên, nếu gặp phải người quản lí gàn dở, không chấp nhận được việc phải thay đổi trong những phút cuối thì bắt buộc các developer phải bỏ đi những kế hoạc fix của họ mà thay vào đó thực hiện các mánh khóe khác nhau chỉ để đạt được mục tiêu do manager đề ra. Và thế code trở nên xấu xí.

Tuy là ví dụ này nghe có vẻ hơi quá nhưng tôi tin rằng mình đã phần nào miêu tả được sự quan trong của việc tránh viết code trùng lập. Nếu như bạn đang phải làm việc cho một công ty mà ép buộc bạn phải làm việc như trong ví dụ trên thì việc thay đổi là điều cần thiết. Bạn có thể yêu cầu một vài thay đổi trong quá trình như đưa ra những lời khuyên về mặt kĩ thuật ngay từ lúc mới lên ý tưởng.

Thế nhưng nếu bạn không có tiếng nói thì sao. Đừng lo cứ đọc tiếp đi! Nguyên tắc tiếp theo sẽ cứu bạn.

Hãy giữ cho nó đơn giản !

Lời giải thích đơn giản nhất thường luôn đúng

Cuối thế kỉ 19, các nhà vật lí bị lâm vào ngõ cụt khi tìm cách lí giải cho việc trọng lực, từ tính và quang học hoạt động như thế nào, đặc biệt là ở khoảng cách xa – như là hệ mặt trời của chúng ta. Thế rồi nhiều lý thuyết được đặt ra, nhiều nhà phân tích lại tiếp tục cho thêm vào nhiều từ khó hiểu khiến chúng càng trở nên rối rắm.

Lúc đó, một nhân viên làm việc tại một văn phòng nhỏ chuyên về sáng chế, Albert Einstein, đã gợi ý rằng nên bỏ đi đống lý thuyết phức tap đó và dùng một cách khác đơn giản hơn, và thật sự nó đã tạo ra một cuộc cách mạng thay đổi cho giới khoa học – Mọi tính toán sẽ trở nên không còn chính xác nữa nếu chúng ta chấp nhận rằng thời gian không phải là một hằng không đổi mà nó mang tính tương đối. Có thể nói đó là một cách suy nghĩ sáng tạo bởi nó đưa ra cách giải thích đơn giản nhất.

Trong nghành phát triển ứng dụng phần mềm, chúng ta gọi nó là KISS để ám chỉ việc dù có nhiều thứ luôn thay đổi nhưng cách đơn giản nhất luôn là tốt nhất.

HTTP

Hypertext Transfer Protocol được xem là một ví dụ hoàn hảo của giải pháp đơn giản cho việc chuyển đổi hypertext từ nội dung của document, nó cũng trở thành xương sống của những ứng dụng với tính tương tác cao ngày nay. Có lẽ là HTTP vẫn còn nhiều hạn chế và trong tương lai chúng ta sẽ phải thay thế nó. Thế nhưng điều ta cần hiểu là, HTTP chỉ dựa trên một vài cách thức request (như GET và POST), staus code cũng như dùng những đoạn text đơn giản, thế nhưng HTTP lại hoạt động tốt và linh hoạt một cách đáng ngạc nhiên. Đó là nguyên nhân mà nhiều web developer sử dụng HTTP.

Nhiều người cho rằng đó là điều hiển nhiên rằng các phần mềm đều đơn giản như vậy nhưng thật ra có rất nhiều được tạo ra một cách qua phức tạp với những solution nửa vời. Thậm chí người ta còn có một thuật ngữ riêng cho chúng – Bloatware. Những phần mềm như vậy được miêu tả là “chết ngay vừa mới sinh ra” (DOD – Dead on arrival). Tôi tin rằng sự thành công của internet chính là nhờ vào tránh khỏi vết xe đổ của những bloatware, chúng luôn dùng những solution đơn giản nhất mà lại cực kì hiệu quả.

Vậy thì có những yêu cầu nào để có thể đưa ra được những giải pháp đơn giản nhất? Tất cả đều phụ tuộc vào khả năng bảo trì cũng như sự hiểu biết về phần mềm của developer. Chính vì thế mà khi bạn đang suy nghĩ cách coding theo yêu cầu của client thì hãy xác định trước những điều sau:

  • Những tính năng mà có ratio giữa lợi ích và công sức bỏ ra quá khác biệt
  • Những tính năng nào quá phụ thuộc vào các tính năng khác
  • Những tính năng nào đang có chiều hướng phức tạp hóa

Trong quá trình thai nghén ý tưởng thì thường được thực hiện bởi những người không có chuyên môn về kĩ thuật để có thể đưa ra các phân tích chính xác thiết thực về cost và lợi ích. Tôi từng làm việc với một project mà trong đó client muốn import excel spreadsheets vào trong phần mềm quản lí nhân sự của họ. Rõ ràng Excel là một phần mềm với format khá phức tạp bới có nhiều feature như thêm hình ảnh, âm thanh – những feature mà client không hề cần. Nhưng thế nếu ta cài Excel import vào phần mềm thì cũng có nghĩa ta đang đưa vào nhưng feature không cần thiết. Chưa kể có quá nhiều phiên bản Excel khác nhau được Microsoft đưa ra hàng năm khiến cho việc bảo trì và nâng cấp vô cùng khó khăn và tốn kém.

Chúng tôi quyết định chỉ import một số feature cần thiết, tất cả đều được thực hiện với một vài dòng code đơn giản. Nhờ vậy mà lượng data trở nên rất nhỏ trong khi lại dễ theo dõi và bảo trì. Hơn thế phương pháp này lại tiết kiệm được rất nhiều chi phí nên có thể nói nó là một ví dụ điển hình của việc áp dụng nguyên tắc KISS.

Nói cách khác, hãy cố gắng suy nghĩ “ out-of-the box” khi bạn thấy task quá phức tạp. Nếu mà khi bạn nghe ai đó giải thích về những yêu cầu của họ, bạn nghĩ rằng chúng quá khó thì thật sự là bạn đúng rồi đó.Nhưng nó khó là bởi vì solution đưa ra quá phức tạp. Trong ví dụ trên, có quá nhiều người tham gia vào quá trình lên ý tưởng nhưng lại thiếu chuyên môn kĩ thuật để đưa ra những phân tích thiết thực. Vì thế mà vấn đề thật sự lại không được nhìn thấy. Ta phải luôn check kĩ những yêu cầu của client và tự hỏi rằng liệu mình có thật sự hiểu được client chưa. Hãy dành thời gian để bàn về những điều kết lõi và so sánh những phương pháp khác nhau để tìm ra hướng giải quyết tốt nhất.

Bạn sẽ chẳng cần đến nó đâu –  You “Ain’t Gonna Need It

Khi Google+ launch,  Mark Zuckerberg – ông chủ của Facebook – là một trong những người đầu tiên tạo ra một account trong mạng xã hội vốn được tạo ra để đè bẹp Facebook. Anh viết đúng một dòng trong phần About me: Tôi đang tạo ra nhiều thứ. Tôi thật sự nghĩ rằng đó là một câu khá hay bởi nó miêu tả được cái cốt lõi của coding. Tại sao bạn lại muốn trở thành coder? Vì yêu thích công nghệ? Vì ngưỡng mộ tính hiệu quả? Cho dù câu trả lời của bạn là gì đi nữa thì có lẽ nó không phải là “tạo nên website thứ 1,000,001 với những tính năng thông thường”. Có điều đó lại chính là cách mà phần lớn chúng ta kiếm ra tiền. Dù là nghề gì đi nữa thì bạn sẽ phải làm những công việc buồn chán và lặp đi lặp lại.

80% thời gian làm việc trong một project phần mềm là để làm nên 20% tính năng của phần mềm.

Nguyên tắc bạn sẽ chẳng cần đến nó đâu là để giải quyết những vấn đề như thế này. nó ám chỉ rằng nếu như vấn đề đó không nằm trong ý tưởng thì cũng sẽ không liên quan gì tới code. Nói cách khác so với nguyên tắc đầu tiên tránh trùng lập bắt đầu bằng việc chia tách hệ thống ra nhiều phần nhỏ hơn thì nguyên tắc này lại tìm cách cắt giảm luôn những phần nhỏ đó nhằm đơn giản hóa giải pháp (bởi vấn đề cần giải quyết cũng ít đi). Vì thế nó cũng khác với nguyên tắc thứ 2 – KISS đơn giản hóa bởi thay vì tìm ra giải pháp thì nguyên tắc bạn sẽ chẳng cần đến nó đâu lại bỏ luôn bởi nó tập trung vào việc lờ đi những vấn đề không liên quan tới yêu cầu của client. Theodore Sturgeon, nhà văn người mĩ từng nói rằng “90% của vạn vật đều là thứ nhảm nhí”. Mặc dù đây là suy nghĩ khá cực đoan và không giúp ích được gì nhiều cho bạn khi làm project. Nhưng nên nhớ rằng “những thứ nhảm nhí” làm ta cực tốn thời gian. Điều đáng ngạc nhiên là có đến tới 80% lượng thời gian của ta tập trung chỉ vào 20% tính năng của phần mềm. Hay gọi là 80/20 cho dễ.

Đối với các công ty mà hay đưa ra các kế hoạch với deadline quá ngắn cũng như là ý tưởng project quá mông lung thì 80/20 chính là một chiến lược cực kì hiệu quả và mạnh mẽ cho bạn. Bởi cho dù bạn có làm thêm thì cũng chả được lợi gì mà có khi sếp còn cho là bạn phí thời gian vì thế mà hãy tập trung vào những tính năng quan trọng nhất.

Tuy là nói vậy nhưng việc phân biệt được đâu là phần cần phải làm phần nào có thể bỏ qua lại rất khó. Để làm được điều đó thì ta phải thay đổi góc nhìn về lập trình phần mềm: chúng ta được dạy để viết những dòng code tốt với tính năng bảo trì dễ dàng. Nói cách khác, chúng ta lập trình sẵn để chuẩn bị cho tương lai của sản phẩm. Thế nhưng điều này lại hay bị bỏ qua bởi các công ty nhỏ. Đối với họ thay đổi đồng nghĩa với việc phải làm lại website từ đầu chứ phần mềm quá dở để có thể nâng cấp hoặc bảo trì. Đó là một vấn đề nghiệm trọng bởi ngân sách của những công ty này cũng khá eo hẹp.

Lên kế hoạch cho một Project

Khi bạn chuẩn bị một list to-do cho một project, hãy nghĩ đến những điều sau:

  • Giảm sự rắc rối bằng cách giảm đi số goal đặt ra
  • Tách tính năng ra khỏi features
  • Sẽ luôn có những yêu cầu chả liên quan gì đến tính năng
  • Xác định những task nào quá tốn thời gian và bỏ nó ra

Đi vào chi tiết một chút. Điều đầu tiên đã được tôi đề cập tới trong những ví dụ trên. Hãy bắt đầu nghi ngờ tất cả mọi thứ có dấu hiệu tăng thêm sự phức tạp cho phần mềm của bạn. Đôi khi chúng đến từ những bản patch update bởi chúng ta luôn suy nghĩ đón đầu và đưa ra quá nhiều bản cập nhật không cần thiết.

Đôi khi những concept dở thường là do bởi chúng không đạt những yêu cầu vốn không có liên quan gì tới chức năng của phần mềm. Một ví dụ điển hình là người xem website thông qua điện thoại muốn nó đẹp như khi xem qua desktop. Tuy vậy nó lại chẳng có gì liên quan đến việc cần thay đổi chức năng và với nguyên tắc bạn không đến nó đâu   thì ta sẽ mặc kệ và khỏi lập trình một cái website cho mobile mà cứ để người mobile dùng truy cập vào website thông qua trình duyệt web có sẵn. Vì thế bạn hãy chắc chắn những yêu cầu thay đổi thực sự cần thiết và liên quan.

Cuối cùng, bạn luôn phải nhớ định luật 80:20! Ta phải xác định được số lượng thời gian bỏ ra cho từng giai đoạn. Chỉ với những phần nào thật sự quan trọng thì chúng ta mới làm. Câu hỏi mà bạn nên đặt ra là: làm cách nào để thực hiện nó? nó có cần phải dùng trên framework mới hay không khi mà cái community vẫn còn nhỏ? Có cần phải update thư viện thông tin không khi tài liệu cũng chả có gì mới? Có nên dùng bản CMS mới không khi mà có nhiều tính năng chả cần đến? Cần phải tìm kiếm, nghiên cứu bao lâu mới làm được? -”Đó là cách mà chúng ta luôn làm” – Tuy chả có gì hay ho nhưng nó bảo đảm giúp ta hoàn thành được công việc. Nên nhớ rằng là đây không phải cái cớ để dùng mánh khóe viết ra mấy cai code dở xấu mà là để ta tạo ra những ứng dụng nhẹ và thiết thực. Nguyên tắc thứ ba này rất là thực tiễn bởi bạn phải thực sự tìm mọi cách để cắt bớt những thứ dư thừa để có thể đạt được kết quả tốt dù có thể nó không thật sự hoàn hảo. Ít ra thì nó đúng như client yêu cầu và chạy tốt.

Nếu như bạn muốn trở thành một nhà developer đầy kinh nghiệm và uy tín thì bạn phải thuần thục nguyên tắc bạn không cần đến nó đâu. Thế nhưng nếu bạn muốn giữ lửa đam mê thì nó không dành cho bạn.

Lời kết

Những nguyên tắc về phần mềm vốn chỉ là những cách nhìn khác biệt về chúng. Đối với tôi, một nguyên tắc tốt chỉ khi nó dựa vào một ý tưởng đơn giản nhưng có thể phát triển thành một idea phức tạp khi được dùng với những kĩ thuật và lý thuyết khác nhau.

Techtalk via code.tutsplus