Tại sao code của tôi thường ngắn gọn như vậy

Bài viết được sự cho phép của tác giả Phạm Công Sơn

Cho đến nay tôi đã làm Coder cũng phải được 12, 13 năm. Bắt đầu đi code từ năm 2007 (Trong năm này tôi đã cưới vợ và sinh ngay một đứa con trai). Tuổi đời coder cũng tạm gọi là dài. Năm nay cũng 38 tuổi rồi, nếu so sánh với một cầu thủ bóng đá chuyên nghiệp thì có lẽ nghỉ hưu cũng đã từ lâu. Vậy mà mình vẫn còn miên man code và code, bug và bug.

  "Code dễ đọc" là như thế nào?

  "Mẹo bỏ túi" cho dân coder mới vào nghề

Skill chủ yếu vẫn là C#JqueryAsp.NetSql Server v.v… Và sau nhiều năm coder như vậy tôi có rất nhiều kinh nghiệm. So với những ngày đầu code một cách vô ý thức, bạ đâu code đó thì giờ đây cách code cũng đã thay đổi rất nhiều và với mỗi yêu cầu tôi thường phân tích kỹ, code sử dụng design pattern và code trừu tượng trước khi làm cụ thể một trường hợp nào đó.

Người ta thì sự nghiệp đầy đủ rồi mới lập gia đình. Còn tôi thì hơi ngược, năm 2007 là tôi chính thức bắt đầu đi làm sau khi cưới vợ. Lương tại thời điểm đó là 1 củ rưỡi. Và vào làm vẫn với tâm thế vừa làm vừa học hỏi. Tâm lý chung của các bạn mới ra trường thôi.

Hồi đó chủ yếu có mấy xu hướng, mấy đứa lập trình chỉ có hỏi nhau mày làm php, dotNet hay Java. Tôi từ FPT APTECH ra, cũng có học Java nhưng sau đó theo hẳn dotNet làm winform hoặc web asp.net. Vào công ty đập ngay dự án về winform, thấy cũng may mắn vì được học cái gì và làm luôn cái ấy. Trưởng dự án giao cho làm mấy Form danh mục như quản lý danh mục sản phẩm, loại sản phẩm. Cảm nhận đầu tiên là nó chả khác gì lúc đi học cả. Cũng tạo Form, kéo thả các input, button, viết sự kiện, truy xuất DataBase và lưu trữ. Và mấy Form sau thì copy nội dung của Form trước. Điều khác biệt mà lúc đó thấy “hay dữ” đó là có cái tool gen được ra các Entity có sẵn mấy hàm Insert, Update, Delete, còn sau đó trên Form có thêm xử lý gì thì tự viết hàm truy xuất. Thế thôi nhưng cũng thấy hay vãi đ* ra rồi. Và nghĩ đúng là đi làm nó khác.

Sau khi dự án làm bằng Winform kết thúc, tôi chuyển sang làm một dự án về WebFormfrown Cái này mình cũng được học và làm Project rồi nên cũng rất tự tin. Tuy vậy lúc mới bắt tay vào dự án cũng làm mấy danh mục trước tiên. Điều khác so với dự án trước là ông Leader ông ý có làm sẵn một Form danh mục rồi. Và ông ý bảo anh em nào được giao làm Form nào thì vào copy ra mà làm các form tương tự. smileyThế đấy, và hàng loạt các Form được sao chép nhau, có Form nào logic nó khác hoặc cần chỉnh thì viết thêm. Vậy mà cũng qua được mấy cái dự án.

Sau đó tôi chuyển tới một số công ty khác và đa số các công ty đều có cách làm việc như vậy. Nếu như các Module, Form nào na ná nhau. Mọi người đều copy lại và chỉnh sửa sao cho phù hợp. Không chỉ những Form quản lý mà còn nhiều các Form khác ví dụ như báo cáo. Code của dự án nào cũng khá là nặng. Và có một nhược điểm là nếu Form nào mà có lỗi thì hầu như phải chỉnh sửa lại ở tất cả các Form. Và cần thêm tính năng nào thì cũng phải mở từng đấy Form ra mà thêm.

Chính vì vậy đa số nhiều lập trình viên sau một thời gian đi làm cũng thường kêu là không có gì mới mẻ, làm đi làm lại một việc. Công việc hầu như không có sáng tạo. Đấy là cái tôi thấy, hầu như code không có thiết kế, không sử dụng design pattern và không tận dụng được tính chất OOP để kế thừa, đóng gói. Các hàm, biến static được sử dụng tràn lan vô tội vạ, code thì copy và không được viết thành thư viện.

Hãy thiết kế code, sử dụng design pattern, code trừu tượng trước khi đi vào cụ thể.

Quay trở lại các dự án thường chúng ta hay phải làm các danh mục trong đó có các tính năng như tìm kiếm, thêm, sửa, xóa, xuất excel. Form nào các bạn cũng phải làm một lưới hiển thị, làm sự kiện thêm mới, sửa, validate dữ liệu khi lưu, sự kiện xóa. Form nào cũng từng đấy bước không thể khác được.

Tôi ví dụ như làm một Form quản lý danh mục tin. Đây chỉ là ví dụ mô phỏng thôi nhé. Ta có thể có đoạn code như sau

public class ManageCategory
{
    public void ShowFormEdit(Category category)
    {
        // Hiển thị form cập nhật hoặc thêm mới
    }
    
    public void Save(Category category)
    {
        // Validate trước khi lưu
        // Thực hiện lưu
    }
    
    public void Delete(Category category)
    {
        // Validate xóa
        // Thực hiện xóa
    }
    
    // Lấy dữ liệu hiển thị lên lưới
    public string Keyword { set; get; }
    public List<Category> GetData(int pageIndex, int pageSize, string fieldOrder, string dir)
    {
        // ....
    }
    
    public void ExportExcel(List<Category> categories)
    {
        // Điền vào excel cho client tải xuống
    }
}

Rồi một Form quản lý loại sản phẩm

public class ManageProductType
{
    public void ShowFormEdit(ProductType productType)
    {
        // Hiển thị form cập nhật hoặc thêm mới
    }
    
    public void Save(ProductType productType)
    {
        // Validate trước khi lưu
        // Thực hiện lưu
    }
    
    public void Delete(ProductType productType)
    {
        // Validate xóa
        // Thực hiện xóa
    }
    
    // Lấy dữ liệu hiển thị lên lưới
    public string Keyword { set; get; }
    public List<ProductType> GetData(int pageIndex, int pageSize, string fieldOrder, string dir)
    {
        // ....
    }
    
    public void ExportExcel(List<ProductType> productTypes)
    {
        // Điền vào excel cho client tải xuống
    }
}

Như các bạn thấy thì Form nào chúng ta cũng phải làm từng đấy bước. Mà đấy là code server, chưa kể code javascript cũng vậy. Các Form mà cứ code đi code lại như vậy hoài rất mất công và sinh ra chán. Lúc gặp lỗi hoặc thêm chức năng thì Form nào cũng phải vọc vào mà sửa.

Vậy bây giờ chúng ta hãy nghĩ khác đi. Trừu tượng nó thành như này

public abstract class Manage<T>
{
    public void ShowFormEdit(T t)
    {
        // Hiển thị form cập nhật hoặc thêm mới
    }
    
    public void Save(T t)
    {
        // Validate trước khi lưu

        BeforeSave();
        // Thực hiện lưu
    }

    protected virtual void BeforeSave(T t)
    {
        
    }
    
    public void Delete(T t)
    {
        // Validate xóa
        // Thực hiện xóa
    }
    
    // Lấy dữ liệu hiển thị lên lưới
    public vitural List<T> GetData(int pageIndex, int pageSize, string fieldOrder, string dir)
    {
        // ....
    }
    
    public void ExportExcel(List<T> list)
    {
        // Điền vào excel cho client tải xuống
    }
}

Và nếu là quản lý chuyên mục tin sẽ là như này

public class ManageCategory : Manage<Category>
{
    public string Keyword { set; get; }
}

Nếu là quản lý loại sản phẩm

public class ManageProductType : Manage<ProductType>
{
    public string Keyword { set; get; }

    protected override void BeforeSave(ProductType productType)
    {
        // Mở rộng validate thêm
    }
}

Chúng ta sẽ không phải code một lần mà lại phải code thêm một lần nữa. Bug ít đi, thêm tính năng cũng sẽ nhanh hơn. Để phát triển, tại lớp Generic các bạn có thể đặt sự kiện, phương thức virtualabstract để các lớp cụ thể override lại. Ví dụ như ManageProductType override lại BeforeSave để viết thêm validate

Tuy vậy để code được trừu tượng các bạn sẽ phải có nhiều kỹ năng và các kiến thức cơ bản là cực kỳ cần thiết. Và với tùy theo các Framework các bạn đang theo các bạn có thể viết các mô hinh cho phù hợp. Trên đây chỉ là code ví dụ mà thôi.

Ngoài ra không chỉ làm những Form quản lý danh mục mà chúng ta có thể mở rộng ra nhiều bài toán khác nhau. Với tôi sau nhiều năm kinh nghiệm, tôi đã làm nhiều yêu cầu với nhiều mô hình khác nhau. Tuy nhiên cũng có một vài lần làm trừu tượng với những yêu cầu lớn. Điển hình như tôi tham gia dự án Staxi (Một sản phẩm đặt xe tương tự như Grab, Uber), mô hình trừu tượng một khối kết nối. Từ đó kế thừa tạo ra các khối như tổng đài, server, App Client, mỗi mỗi khối có nhiệm vụ nhận, và truyền tín hiệu. Rồi dự án phân tích dữ liệu từ hộp đen. Cũng trừ tượng mô hình phân tích để kế thừa cho phân tích dữ liệu cho Taxi, Bus và Xe vận tải. Và rất nhiều dự án khác. Tôi sẽ chia sẻ trong những lần tới.

Hiện với cách code này tôi đang áp dụng cho dự án của tôi, chắc chắn sẽ publish dự án trong một ngày sớm nhất vì tôi còn đang hoàn thiện.

Tôi cũng show cho anh em xem một Form tôi đã thực hiện trong dự án: Quản lý tỷ giá ngoại tệ. Form này khá đơn giản

Tại sao code của tôi thường ngắn gọn như vậy

Đây là định nghĩa Entity, có Attribute validate trên mỗi thuộc tính. DataSource để lấy dữ liệu hiển thị trên lưới

Tại sao code của tôi thường ngắn gọn như vậy

Nội dung Html định nghĩa lưới hiển thị dữ liệu. Nút xóa gọi hàm Delete, có confirm khi xóa. Click vào tỷ giá gọi Hàm Edit hiển thị Form cập nhật

Tại sao code của tôi thường ngắn gọn như vậy

Toàn bộ nội dung của Form kế thừa tới ManageModule trong đó đã có toàn bộ các chức năng

Tại sao code của tôi thường ngắn gọn như vậy

Nội dung của Form cập nhật gồm các Input cần thiết

Tại sao code của tôi thường ngắn gọn như vậy

Nội dung file js định nghĩa đã bao gồm toàn bộ thao tác trên lưới.

Trên đây là toàn bộ code cho một Form quản lý. Còn đây là kết quả

Tại sao code của tôi thường ngắn gọn như vậy

Đây là lưới hiển thị dữ liệu.Trên lưới có chức năng tìm kiếm, sắp xếp, xóa, sửa, thêm mới, cấu hình cột, xuất excel

Tại sao code của tôi thường ngắn gọn như vậy

Click vào thêm mới hoặc một dòng sẽ hiển thị Form cập nhật. Trên Form có sẵn các nút lưu

Tại sao code của tôi thường ngắn gọn như vậy

Form có sẵn chức năng giới thiệu tính năng

Tại sao code của tôi thường ngắn gọn như vậy

Có thể cấu hình cột được hiển thị theo ý muốn người dùng

Như vậy với code ngắn gọn như trên tôi đã có một Form nhập liệu đầy đủ mọi tính năng. Và như các bạn thấy. Tôi vừa thêm chức năng phím nóng được giới thiệu ở bài viết Hướng dẫn sử dụng Jquery Plugin Hotkeys – Tạo phím nóng trên trình duyệt web và chức năng giới thiệu ở bài viết Hướng dẫn sử dụng bootstrap tourist để làm trợ giúp cho phần mềm. Tôi thêm vào phần lớp Base nhưng tất cả các Form của tôi đều có luôn. Như vậy sẽ tăng tốc được khi làm các Form và tính năng mới.

Trên đây chỉ là một vài chia sẻ nhỏ. Hy vọng sẽ giúp ích được cho các bạn.

Bài viết gốc được đăng tải tại sonpc20.com

Có thể bạn quan tâm:

Xem thêm các việc làm Developer hấp dẫn tại TopDev