Tôi tái cấu trúc code như thế nào?

HaDu Đặng
LecleVietnam
Published in
5 min readApr 23, 2019

Tái cấu trúc code là một phần việc hết sức cơ bản của mọi developer. Tuy nhiên, tôi đã tìm thấy tương đối ít resource nói sâu về vấn đề này.

Bài post này ra đời sau buổi sáng hôm nay, khi tôi tái cấu trúc code JavaScript của mình. Nó chỉ kéo dài chưa đầy 30 phút, nhưng đã khiến tôi đủ hào hứng để quay lại và viết bài viết này trên Medium của mình.

Hãy bắt đầu câu chuyện về những nhà “tái cấu trúc” vĩ đại

Đầu tiên, tôi có hai functionfetch (tìm nạp) này nằm rải rác ở khắp nơi trong codebase của tôi với các tên hơi khác nhau mà tôi muốn cấu trúc lại thành một module duy nhất của các function có thể sử dụng lại nhiều lần. Đây chỉ là hai trong số chúng:

Tôi không phải là một người ủng hộ nguyên tắc DRY một cách cực đoan, nhưng điều tạo cho tôi cảm giác khá cồng kềnh. Mỗi function chỉ làm được rất ít những gì chúng có thể đạt được chỉ với tìm nạp những thứ nó bao hàm. Ngoại trừ việc đóng gói các URL endpoint và thuộc tính của method, hai function này trông giống hệt nhau và nên điều chỉnh để có thể sử dụng lại trong toàn bộ codebase.

Function nên “thuần” khi có thể

Tiêu chí đầu tiên và quan trọng nhất của tôi cho một function là nó nên được tái cấu trúc để trở nên thuần khi có thể. Sự “thuần” này có nghĩa là tính có thể tái sử dụng. Khi cần thay đổi bất kỳ shared state (trạng thái dùng chung, nó có thể là một sự lựa chọn cho một method. Điều này khiến cho function dễ test và có thể sử dụng lại được. Một số function có tên nhưpostLoginData đã vi phạm điều này. Dưới đây là một số các để tái cấu trúc nó mà không cần phải suy nghĩ vềsự hoàn thiện của đoạn code:

  • user.login()
  • login(user)
  • post(loginUrl, user)

Danh sách trên đã được sắp xếp từ theo thứ tự từ ít khái quát nhất đến có khả năng sử dụng lại cao nhất. Trên thực tế, hai function đầu tiên có mức độ khái quát giống nhau. Chỉ có cái cuối là có thể tái sử dụng, và đó là những gì tôi sẽ làm.

Bây giờ, bạn có thể thấy những điểm vi phạm ở 2 function đầu tiên của tôi. Đôi khi, bạn đội những chiếc mũ khác nhau và ưu tiên những thứ khác nhau. Nó vẫn ổn nếu đôi khi bạn đi hơi nhanh để khiến code hoạt động, miễn là thỉnh thoảng bạn dừng lại và dọn dẹp mọi thứ một chút.

Điều chỉnh tái cấu trúc

Để quyết định xem một thứ có nên được tái cấu trúc hay không, tôi thường nghĩ về mục đích và sự xứng đáng của việc tạo ra 1 function cho nó.

Ví dụ, một function dùng để “đăng” (post) và một function dùng để nhận (get) data có sự khác biệt cơ bản về ý định, bất chấp việc chỉ có 1 sự khác biệt nhỏ trong cách thực hiện. Các ý định được phân biệt rõ ràng đủ để giải thích cho việc tại sao lại tạo ra 2 function.

Tuy nhiên, việc gói một URL tùy ý vào một function, ví dụ như một login API endpoint, sau đó đặt tên cho function là postLoginData không thêm nhiều giá trị vào một function xét về việc làm giảm mức độ tổng quát của nó. URL, ngoài việc là một chuỗi lót, còn nên là một “câu chuyện” của caller. Hãy xem một nghệ sĩ với sơn dầu, bảng màu và cọ. Những gì họa sĩ muốn vẽ nên là câu chuyện của họa sĩ. Bảng màu, bộ sưu tập sơn và cọ chỉ nên cung cấp các biến thể để hỗ trợ cho đối tượng đó. Bạn có thể tưởng tượng một bộ sơn để vẽ cảnh đại dương không? Đó là điều hợp lý. Bây giờ làm thế nào về một để vẽ một con tàu. Hoàn toàn không dễ phải không? Các chủ để là quá cụ thể để được gói gọn.

Nếu không có thêm rắc rối nào khác, đây là bộ tái cấu trúc thứ hai:

Bây giờ code của chúng ta đã trông gọn gàng hơn với các thuộc tính đối tượng cấu hình lặp đi lặp lại được tái cấu trúc thành một hằng sốbaseConfig . Ngoài ra, tôi đã thêm một tham số tùy chọn config đến từng function để khiến chúng có thể cấu hình từ bên ngoài. Object.assign được dùng để hợp nhất cấu hình tùy chỉnh config vớibaseConfig .

Ta có thể thấy mọi thứ đã có vẻ hiệu quả. Tại thời điểm này, tôi khá hài lòng, nhưng với thời gian rảnh rỗi, tôi quyết định xem liệu tôi có thể rút ra được điều gì nữa không. Đây là bản tái cấu trúc cuối cùng:

Cá nhân tôi thích phiên bản này nhất vì functiongetpost là các hàm bao rất mỏng lên function send vừa mới được tạo. Từ nay về sau, khi có bug, ta chỉ cần debug ở điểm trên.

Tái cấu trúc là một công việc khá khó để vận dụng, không phải vì nó khó mà vì nó cần tư duy thiết kế sâu hơn. Và đừng lầm tưởng, bạn đã sẽ không thể nào khiến nó phù hợp cho tất cả mọi người. Việc tái cấu trúc để code có thể sử dụng lại được có thể khiến cho ai đó cảm thấy mất hứng thú một cách bất ngờ, đặt biệt là khi sự đánh đổi nhiều hơn những gì bạn nhận lại được. Do đó, sự cân bằng là cái mà ta cần hướng đến. Có các yếu tố khác như quy ước đặt tên và các tham số function đều có thể trợ giúp cho khả năng truy cập và chúng luôn luôn cần bàn phải suy nghĩ kỹ.

Nguồn: Joe Chasinga

Dịch: Lecle Vietnam

ABOUT LECLE VIETNAM

LECLE is a global software — blockchain technology house headquartered in South Korea with offices in the USA, Singapore, and Vietnam.

Founded in 2014, we received an initial investment from The Ventures and went through Plug and Play’s accelerating program. Up to now, we have offered innovative solutions that are best suited to various customers in Korea. Since 2018, we have decided to shift our focus onto blockchain business while continuing to develop our outsourcing projects. Now we have been creating a blockchain platform for communities based EOS.

Please follow Lecle VietNam Blog for more information

--

--