2009-11-06 35 views
6

Câu hỏi này có trong tâm trí tôi một thời gian, xin lỗi nếu nó xuất hiện chủ quan. Có một số nhược điểm trong việc sử dụng bool trong các thuộc tính công cộng và các hàm tạo cho các đối tượng dữ liệu. Hãy xem xét mã sau đây làm ví dụ.Hai điều tra thành viên so với giá trị boolean

Sử dụng bool:

public class Room 
{ 
    public string Name { get; set; } 
    public bool Bookable { get; set; } 

    public Room(string name, bool bookable); 
} 

và việc sử dụng các lớp này

Room r = new Room ("101", true); 

Đây là phù hợp chức năng, có tuy nhiên một cách khác để thực hiện nó:

Sử dụng enum :

public enum BookingStatus 
{ 
    Bookable, 
    NotBookable 
} 

public class Room 
{ 
    public string Name { get; set; } 
    public BookingStatus Bookable { get; set; } 

    public Room(string name, BookingStatus bookable); 
} 

và việc sử dụng các lớp

Room r = new Room ("101", BookingStatus.Bookable); 

này Đối với tôi hai xuất hiện chức năng tương đương, có một số ưu điểm và nhược điểm của mỗi tuy nhiên:

  • Khi thiết lập các thuộc phương pháp Enum là hơn verbose (bạn có thể phỏng đoán việc sử dụng enum từ mã một mình)
  • Các số đếm có thể được mở rộng để hỗ trợ các trạng thái khác (đặc biệt hữu ích cho một API)
  • Các số đếm yêu cầu nhập nhiều hơn đáng kể (mặc dù giảm rất nhiều)
  • Không thể sử dụng các số đếm trong điều kiện (tức là nếu (r.bookable)), mặc dù tôi đánh giá cao điều này là tầm thường để giải quyết.

Tôi có thiếu thứ gì đó, hoàn toàn không có dấu? Tôi không chắc tại sao điều này lại gây lỗi cho tôi rất nhiều, có lẽ tôi cũng quá OCD vì lợi ích của chính tôi!

+0

Ý kiến: này có vẻ như nó không phải là ví dụ tốt nhất - nếu nó một câu trả lời đúng/không đúng, thì bools là thích hợp. Mặc dù bạn nên đặt tên cho các thuộc tính của mình một cách chính xác theo quy ước (ví dụ "IsBookable") - Ví dụ tốt hơn là một câu hỏi không có hoặc không có, chẳng hạn như giới tính hoặc đơn vị đo lường, v.v. - ngay cả khi bạn chỉ nhận ra hai trạng thái (inch vs cm, hoặc nam vs nữ), bạn nên sử dụng enum, bởi vì đây chắc chắn không phải là câu hỏi "có hoặc không" (mặc dù bạn có thể làm cho chúng thành có/không có câu hỏi, chúng không, và mỗi người có thể mở rộng để hỗ trợ nhiều tiểu bang hơn). – BrainSlugs83

Trả lời

2

Trong cuốn sách Refactoring, Martin Fowler giải thích lý do tại sao anh ấy nghĩ rằng enums là một mùi mã, và tôi chỉ có thể đồng ý. Trong ví dụ của bạn, cách tiếp cận tốt hơn là tạo lớp Tóm tắt trong phòng:

public abstract class Room 
{ 
    public string Name { get; set; } 

    public abstract bool Bookable { get; } 
} 

Sau đó, bạn có thể tạo ra lớp BookableRoom và NonBookableRoom.

public class BookableRoom : Room 
{ 
    public override bool Bookable 
    { 
     get { return true; } 
    } 
} 

public class NonBookableRoom : Room 
{ 
    public override bool Bookable 
    { 
     get { return false; } 
    } 
} 
+0

Điểm mạnh và phương pháp tôi đã sử dụng ở nơi khác. Tôi đoán điều này sẽ không làm việc tốt với một cái gì đó giống như Entity Framework? Tuy nhiên nó chắc chắn sẽ bản đồ rất tốt vào một cái gì đó giống như một danh sách SharePoint. –

+10

Tại sao bạn nói rằng đây là cách tiếp cận tốt hơn? Đối với tôi nó trông giống như sự gia tăng của sự phức tạp. Tôi nghĩ nguyên tắc KISS là phù hợp ở đây. – nightcoder

+0

Cuốn sách cung cấp một mô tả toàn diện :) –

5

Ih có bất kỳ cơ hội mà trong tương lai có thể có nhiều hơn hai lựa chọn ban đầu, thêm một lựa chọn thứ ba để một enum là ít hơn rất nhiều công việc sau đó thay đổi tất cả bool để enum.

+0

Đó là những gì ông đã nói trong câu trả lời của mình (điểm thứ hai trong danh sách viên đạn). –

+0

ngoại trừ phần "kế hoạch cho tương lai". – fforw

8

Đơn giản chỉ vì khả năng đọc và hiểu mã, tôi sẽ chuyển sang enum thay vì boolean.

So sánh BookingStatus.Bookabletrue, tất nhiên bạn sẽ hiểu thêm đọc BookingStatus.Bookable.

Cũng giống như những gì fforw đã đề cập, trong trường hợp trong tương lai bạn có thể cần thêm nhiều tùy chọn hơn, enum sẽ dễ thay đổi hơn.

+0

Điều gì về loại an toàn? Một enum sẽ ngăn chặn bất kỳ giá trị Boolean cũ nào bị rơi vào một tham số enum. – weberc2

+1

Điều này cũng tốt hơn để duy trì. Thay đổi nhỏ hơn khi sử dụng enum nếu một loại mới của BookingStatus được phát minh –

4

Đối với tài sản, tôi có thể đồng ý. Trong 'Mã sạch', mặc dù, nó được chỉ định (chính xác) rằng mục đích ẩn bool s khi được sử dụng làm tham số.Ví dụ, một phương pháp định dạng có thể trông giống như:

public void Format(bool pBold, bool pItalic, bool pUnderline) 
{ ... } 

Khi gọi này trông giống như:

Format(true, false, true); 

Thay vào đó nó sẽ được nhiều dễ đọc hơn như:

public enum BOLD { BOLD, NOT_BOLD } 
public enum ITALIC { ITALIC, NOT_ITALIC } 
public enum UNDERLINE { UNDERLINE, NOT_UNDERLINE } 

public void Format(BOLD pBold, ITALIC pItalic, UNDERLINE pUnderline) 
{ ... } 

Mà sau đó làm cho gọi điện thoại trông giống như:

Format(BOLD.BOLD, ITALIC.NOT_ITALIC, UNDERLINE.NOT_UNDERLINE); 

(Hãy nhớ rằng đây chỉ là một ví dụ về cách các tham số bool ẩn ý định; . Có những cách có lẽ tốt hơn để thực hiện các mã trên)

Trong trường hợp cụ thể của bạn, hãy chú ý sự khác biệt giữa hai constructor gọi:

// enum; intent is clear 
Room r = new Room ("101", BookingStatus.Bookable); 

// bool; true what? 
Room r = new Room("101", true); 
+2

Ngoài ra, bạn không thể đặt một biến chứa giá trị được in đậm vào vùng tham số 'nghiêng' khi sử dụng enums. :) Gõ an toàn. – weberc2

+0

'// chuỗi; "101" cái gì? "Thêm một vài chuỗi nữa và bạn đang ở cùng vị trí với bool. Vậy bạn làm gì? Bạn nhìn vào định nghĩa phương thức. – Stijn

+0

@Stijn Đồng ý. Không đọc chữ ký phương thức không phải là một cái cớ để không hiểu chữ ký của phương thức. – Dan

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