2010-08-03 24 views
9

Tôi đã lập trình được rất nhiều thời gian. Nói chung tôi lập trình bằng một số ngôn ngữ như PHP, ASP.net, Java, JavaScript và các ngôn ngữ khác. Trong tất cả các ngôn ngữ tôi phải sử dụng rất nhiều nếu các statments khác. Giống như nếu giá trị = 10 thì ... nếu tôi xem lại mã của tôi thì tôi thấy rất nhiều điều kiện. Vì vậy, tôi muốn giảm thiểu chúng nhưng làm thế nào không chắc chắn.Làm thế nào để tránh nếu ... khác và chuyển trường hợp

một điểm đã sử dụng các lớp học phần nào giảm thiểu nhưng họ vẫn có nhiều ...

như nhiệm vụ, mèo, sec và gõ:

if task = 'add' then 
    if cat = "animal" then 
     if sec = "man" then 
      if type = "male" then 
       'do the following stuffs 
      else 
       'do the following stuffs 
      end if 
     elseif sec = "horse" then 
      if type = "run" 
       'do the following stuffs 
      else 
       'do the following stuffs 
      end if 
     elseif.... 
     end if 
    elseif cat = "plant" then 
    if sec = "land" then 
      if type="tree" then 
       'do the following stuffs 
      elseif type = "grass" then.. 
       'do the following stuffs 
      elseif... 
      end if 
    elseif sec = "water" then 
    ... 
... 

...

hơn n hơn tiếp tục n tiếp tục

để tự hỏi làm thế nào tôi có thể thu nhỏ chúng và viết một số mã hiệu quả?

Xin lỗi để thông báo gần đây rằng có thể có rất nhiều giá trị cho tác vụ, mèo, giây và loại. Các câu lệnh if của tôi sẽ được lồng vào nhau lồng nhau.

More giải mã của tôi cũng trông giống như giống như:

http://thedailywtf.com/Articles/Coding-Like-the-Tour-de-France.aspx

+0

thêm một số mã vào câu trả lời của tôi – Mchl

+2

Một sidenote: Cố gắng viết mã với ý định rằng hàm/phụ không bao giờ lớn hơn bạn có thể xem toàn bộ chức năng/phụ trong một màn hình (màn hình có thể thay đổi không bao gồm:]). Bằng cách này, bạn sẽ bị buộc phải chia mã này thành các mảnh nhỏ hơn và điều này sẽ giúp bạn dễ dàng xem và hiểu hơn – Default

Trả lời

14

Nhiều if..else báo cáo thường là một triệu chứng của Polymorphism không được sử dụng.

+0

đọc nội dung có thể là tìm kiếm ... sẽ đăng bình luận sau ... nếu một số trực quan giải thích liên kết plz đăng nó – KoolKabin

+0

Tôi không nghĩ rằng đa hình giải quyết tất cả các vấn đề của quá nhiều nếu người khác. Điều gì sẽ xảy ra nếu đầu vào của nó từ bảng điều khiển cần được hiểu? – Default

+0

Người downvoter xin vui lòng để lại một bình luận. Cảm ơn. –

4

Nó được gọi là 'mũi tên antipattern' Một số phương pháp để đối phó với nó được mô tả ở đây: http://c2.com/cgi/wiki?ArrowAntiPattern

Một trong những cách bạn migt xem xét, là để cấu trúc lại mã số trong mức lồng nhau để chức năng tách như

if cat = "animal" then 
    functionForAnimal(); 
elseif cat = "plant" then 
functionForPlant(); 
elseif... 


function functionForAnimal() 
    if sec = "man" then 
    functionForMan(); 
    elseif sec = "horse" then 
    functionForHorse(); 
    elseif... 

etc... 

Việc này chia mã thành các đoạn nhỏ hơn, dễ bảo trì hơn và có thể tái sử dụng được.

+0

xin lỗi vì đã đặt câu hỏi rõ ràng gần đây ... nhưng các trường hợp có thể nhiều như trong câu hỏi đã chỉnh sửa – KoolKabin

+0

vâng giải thích thêm mã của tôi cũng giống như sau: http://thedailywtf.com/Articles/Coding-Like-the-Tour -de-France.aspx – KoolKabin

+0

+1, đây cũng là suy nghĩ của tôi, chia nhỏ nó, làm cho nó dễ xem hơn và tái sử dụng các phần có thể được tái sử dụng. – Default

0

Nếu các lựa chọn cho mỗi biến đó là hữu hạn, thì bạn thậm chí có thể sử dụng các thủ thuật như các trường bit với phép toán OR.

Ví dụ:

// give each field a byte so that each can have 256 possible values 
#define TASK_ADD 0x01 
#define TASK_SUB 0x02 
... 
#define CAT_ANIMAL 0x01 
... 
#define SEC_BOY 0x03 
#define SEC_MAN 0x04 
... 
#define TYPE_FEMALE 0x01 
#define TYPE_MALE 0x02 
... 

if ((task << 24 | cat << 16 | sec << 8 | type) == 0x01010402) { 
    // do stuff 
} 
+0

xin lỗi vì đã đặt câu hỏi rõ ràng gần đây ... nhưng các trường hợp có thể rất giống với câu hỏi đã chỉnh sửa – KoolKabin

2

Polymorphism có thể có ích khi bạn có triển khai khác nhau nhưng nhiệm vụ là khái niệm giống nhau. Đôi khi thật khó để tìm một cấu trúc lớp tự nhiên và các cách tiếp cận như state pattern hoặc strategy pattern có thể phù hợp hơn.

+0

vâng đa hình chắc chắn là hữu ích nhưng trước khi sử dụng đa hình, chúng ta nên tạo đối tượng và trước khi tạo đối tượng, chúng ta nên biết các tùy chọn được thiết lập bởi người dùng. ví dụ. nếu giữ tất cả các tùy chọn đó trong một biểu mẫu và sau đó người dùng nhấp vào nút để bắt đầu công việc thì một lớp nào đó sẽ được tạo và gọi theo polymorphisim – KoolKabin

0

Một nơi nào đó bạn sẽ cần phải kiểm tra các điều kiện với if-elses, để đảm bảo bạn làm đúng. Bạn có thể tạo tàu ngầm mới nếu bạn không muốn nhồi nhét một phụ

Sub AddAnimalManMale() 
    If task = 'add' And cat = 'animal' And sec = 'man' And type = 'male' Then 
     'perform the add animal man male action' 
    End If 
End Sub 
Sub AddAnimalHorseRun() 
    If task = 'add' And cat = 'animal' And sec = 'horse' And type = 'run' Then 
     'perform the add animal horse run action' 
    End If 
End Sub 

sau đó trong tiểu chính của bạn

... 
Call AddAnimalManMale() 
Call AddAnimalHorseRun() 
... 
+0

Nội dung của bạn cũng tốt và tương tự như trên. Nếu chúng ta thực hiện một cuộc gọi hàm bằng cách concatinating tất cả các tùy chọn thì chúng ta cần phải kiểm tra các biến một lần nữa bên trong hàm – KoolKabin

2

Bạn mô tả một ma trận với 4 thông số đến - task, cat, sec, type và một đi - stuff. Vì vậy, bạn phải mã nó một cách nào đó.

Ví dụ: bản đồ XML và truy vấn XPath, tức là String.Format("task[@value={0}]/cat[@value={1}]/sec[@value={2}]/type[@value={3}]", "add", "animal", "man", "male") nhưng cách tiếp cận này trỏ đến dữ liệu chứ không phải là phương thức ủy quyền.

Một cách khác:

void DoStuffA() { } 
void DoStuffB() { } 

var arr = new[] 
{ 
    new { Task = "Add", Cat = "Animal", Sec = "Man", Type = "Male", Method = (Action)DoStuffA }, 
    new { Task = "Add", Cat = "Plant", Sec = "Land", Type = "Tree", Method = (Action)DoStuffB }, 
    // etc.. 
}; 

var action = arr.FirstOrDefault(i => 
    i.Task == "Add" && 
    i.Cat == "Animal" && 
    i.Type == "Male").Method; 
action(); 

Ngoài ra bạn có thể sử dụng các thành viên không vô danh nhưng khai báo một lớp, mô tả các biến thể của bạn trong XML và deserialize chúng từ XML để một số trường hợp lớp học của bạn.

+0

cách tiếp cận tốt đẹp bằng cách sử dụng mảng ... nó cũng thú vị ... sẽ được nhìn về phía trước nó quá – KoolKabin

1

Tôi nghĩ có một số sai sót cơ bản trong thiết kế của bạn. Tôi không biết bạn đang cố giải quyết vấn đề gì với mã này, nhưng mã như vậy sẽ rất hiếm trong ngôn ngữ hướng đối tượng. Mã của bạn cũng có vẻ hơi phi logic với tôi, bởi vì, ví dụ, kiểu biến có nghĩa là giới tính lần đầu tiên nó được sử dụng (nam) và sau đó nó có nghĩa là một hành động (chạy). Bạn đã nhận thấy điều này chưa?

Dù sao, nếu bạn thực sự đang sử dụng Java (hoặc bất kỳ thứ gì có các lớp), thì điều bạn cần là trừu tượng. Tiếp theo, di chuyển tất cả các logic bạn có thể cho các đối tượng của bạn - không xử lý nó trong một thói quen quái dị. Hãy suy nghĩ theo cách này: các đối tượng của tôi biết cách làm một phần của họ.

Thực ra hơi khó để đưa ra lời khuyên tốt trong tình huống này, tôi nghi ngờ vấn đề của bạn có nguồn ở cấp cao trong ứng dụng của bạn và mã trường hợp này chỉ là một triệu chứng. Hãy thử thiết kế lại chương trình của bạn để sử dụng cách tiếp cận hướng đối tượng và có lẽ một giải pháp tốt hơn sẽ đến với tâm trí của bạn khi bạn đi.

Nếu bạn không chắc chắn về đa hình, trừu tượng và các thuật ngữ OO khác có nghĩa là gì, bạn sẽ cần phải đọc về điều này.

4

Giả sử bạn luôn thực hiện so sánh bình đẳng và so sánh tất cả bốn trường, cách tiếp cận theo hướng dữ liệu đơn giản là khá thực tế. Tất cả những gì bạn cần làm là xây dựng bản đồ từ (nhiệm vụ, mèo, giây, loại) đến một chức năng để gọi:

handlers = { 
    ('add', 'animal', 'man', 'male'): add_man_func, 
    ('add', 'animal', 'horse', 'run'): run_horse_func, 
    # ... 
} 

handler = handlers[(task, cat, sec, type)] 
handler(some_args) 
+0

điều này thành các cấp độ khác nhau (cặp khóa - cặp chức năng). Lý do chính là, có khả năng là mã được chia sẻ cho tất cả _add_ s và tất cả _animal_ s, v.v. – Dolphin

0

Phá vỡ mã lên là tất cả những gì trò chơi nói về.

Về mặt lịch sử, bạn sẽ làm gì (và đã có tốt, hoặc ít nhất là mã ổn định, và vẫn còn là trong tất cả các)

  • như bạn đang làm nó bây giờ, nguyên khối trong các chức năng khổng lồ, với nhiều ý kiến ​​

  • chia nó thành các chức năng được xác định rõ tên và cũng nhỏ

  • chức năng đặt tên là khó khăn cho các công cụ phức tạp và cũng nếu bạn tiếp tục đi tham khảo cho các cấu trúc lớn, sau đó đối tượng là một natura l để phát minh ra (tuy nhiên, một khi bạn đi theo hướng đối tượng thì nó có ý nghĩa để làm mọi thứ và thông qua việc tái sử dụng các mẫu hướng đối tượng mã xuất hiện ...)

Nhận biết các mẫu tương tự như cho tốt tên để chức năng (cộng với bạn có được phương pháp hữu ích tự nhiên ném vào, có thể được chiến thắng rất lớn).

Các vấn đề liên quan