Anti-IF pattern

Lập trình không dùng if-else, có được không?

If-else thật xấu xí

Đối diện với một bài toán, lập trình viên (LTV) thường phải trả lời câu hỏi: Đây là bài toán đặc thù hay phổ quát? Bài toán “số ít” hay “số nhiều”?  Và thông thường, câu trả lời sẽ quyết định thành quả tiếp theo. Ví dụ, con chó kêu gâu gâu?” là bài toán số ít. Ta có thể viết thế này:

if (dog.startTalking())
    return "gâu gâu";</pre>
Thật đơn giản. "<em>Con chó kêu gâu gâu, con mèo kêu meo meo"</em> thì sao? Vẫn là bài toán số ít thôi.
<pre class="lang:c# decode:true" title="#2 ">if (animal.startTalking()) { 
    if (animal == DOG)
        return "gâu gâu";
    else
        return "meo meo"; 
}

Thật đơn giản. “Con chó kêu gâu gâu, con mèo kêu meo meo, con vịt kêu quạc quạc” thì sao? Vẫn là bài toán số ít thôi.

if (animal.startTalking()) { 
    if (animal == DOG) 
        return "gâu gâu"; 
    else if (animal == CAT)
        return "meo meo"; 
    else if (animal == DUCK) 
        return "quạc quạc";  
}

Thật đơn giản. À từ từ, chuyển sang switch cho đẹp mắt.

switch (animal) {
    case DOG:
        return "gâu gâu";
    case CAT:
        return "meo meo"; 
    case DUCK: 
        return"quạc quạc";
}

Đẹp đẽ quá rồi. Tuyệt vời.

Bạn có thấy câu chuyện trên quen thuộc trong cuộc sống hàng ngày của LTV? Khi if-else bắt đầu phát huy sức mạnh, làm ơn đừng chuyển sang switch – chẳng hay ho gì đâu. Khi if-else bắt đầu phát huy sức mạnh, chính là khi nó bắt đầu trở nên xấu xí, chính là khi chúng ta cần phải xem lại cách đánh giá bài toán của mình. Đây không phải là bài toán số ít ngay từ đoạn code #2. Các LTV cần hiểu đúng đắn rằng đây là bài toán số nhiều ngay từ khi nó có dấu hiệu là bài toán số nhiều, thay vì cứ else-if và hy vọng giữ nó là bài toán số ít.

LTV có thể sống mà không cần if-else?

Có, dùng switch thôi. Không không, tiêu đề trên để cho vui thôi. Câu hỏi thực sự là “chúng ta có thể lập trình mà không sử dụng câu lệnh rẽ nhánh (conditional statement)?”.  Vâng, không dùng if-else, switch,…?

Từ thưở đầu học lập trình, ai trong chúng ta cũng biết những thứ căn bản nhất của một ngôn ngữ lập trình (NNLT): variable, array, conditional, loop statement. Lâu dần chúng ta coi đó là điều nghiễm nhiên của một NNLT. Nhưng bạn cần biết rằng, âu lệnh if-else còn nhiều điểm xấu xí khác, từ logic cho tới runtime speed, memory… nên một số NNLT hoàn toàn không có if-else.

Vậy thì sống làm sao? Làm sao để giải bài toán trên mà không dùng if-else? OOP – polymorphism là một giải pháp. Thử xem:

class Animal { 
    talk(); 
} 

class Dog : Animal { 
    talk() {
        return "gâu gâu"; 
    } 
} 

class Cat : Animal { 
    talk() {
        return "meo meo"; 
    } 
} 

class Duck : Animal { 
    talk() {
        return "quạc quạc"; 
    } 
} 

// something here
animal.talk();

Không có gì huyền bí cả, bạn có thể tham khảo tại blog của Martin Fowler về pattern này.

Nếu bạn muốn thực hành nhiều hơn, có thể tìm đến Anti-IF pattern tại đây.

No if-else

Về lý thuyết, chúng ta hoàn toàn có thể lập trình mà không sử dụng if-else. Tại các buổi Code Retreat thường có 1 session mà LTV nhất định không sử dụng if-else khi lập trình ngay cả khi NNLT đó hỗ trợ. Mục tiêu là luyện tập khả năng ít phụ thuộc vào conditional statement để hình thành tư duy abstract. Như ví dụ trên, câu lệnh if-else thực sự quá mạnh mẽ, đến nỗi các LTV không thể tránh được cám dỗ, giải bài toán theo “số ít” và tạo ra những thiết kế sai lầm, vi phạm nguyên tắc open-closed cơ bản.

Nếu bạn chưa biết thực hành thế nào, hãy tới một buổi Code Retreat cho biết.