2011-08-22 40 views
34

Khi bạn xác định một enum kiếm cái gì đó có thể là "không xác định" trong giao diện của bạn, nên bạnBạn có nên xác định giá trị null/không xác định cho các enums Java không?

  • xác định một giá trị enum riêng biệt cho điều đó, hoặc
  • chỉ cần sử dụng enumValue = null cho những tình huống này?

Ví dụ,

serviceX.setPrice (Giá priceEnum)

enum Price { 
CHEAP, EXPENSIVE, VERRRY_EXPENSIVE, UNKNOWN 
} 

và priceEnum.UNKNOWN khi cần thiết

hoặc

enum Price { 
CHEAP, EXPENSIVE, VERRRY_EXPENSIVE 
} 

và priceEnum = null khi cần thiết?

Có một cuộc tranh luận nhỏ về vấn đề này. Một số điểm cần lưu ý:

  • sử dụng Price.UNKNOWN lưu một số mã "if (price == null)". Bạn có thể xử lý tất cả giá trị của Giá x trong một trường hợp chuyển đổi đơn lẻ
  • Tùy thuộc vào công nghệ xem, có thể dễ dàng định vị giá hơn.UNKNOWN
  • sử dụng Price.UNKNOWN loại nguyên nhân "số ma thuật" trong mã, IMO . Ở đây chúng tôi có Price.UNKNOWN, ở những nơi khác có thể là Color.UNDEFINED, Height.NULLVALUE, v.v.
  • sử dụng priceValue = null đồng nhất hơn với cách các loại dữ liệu khác được xử lý trong Java. Chúng tôi có Integer i = null, DomainObject x = null, String s = null cho các giá trị không xác định là tốt, phải không?
  • Giá.UNKNOWN buộc bạn phải quyết định liệu giá trị null có được phép chung cho tất cả các trường hợp sử dụng hay không. Chúng tôi có thể có phương thức Price getPrice() có thể trả về Price.UNKNOWN và setPrice (Giá p) mà không được phép chấp nhận Price.UNKNOWN. Vì Price.UNKNOWN luôn được bao gồm trong các giá trị của enum, những giao diện đó trông hơi bẩn thỉu. Tôi biết priceValue = null đã cùng một vấn đề (bạn không thể xác định trong giao diện dù null được chấp nhận hay không) nhưng nó cảm thấy một chút bụi và một chút ít sai lệch (?)
+7

bạn không thể sử dụng 'null' trong chuyển đổi và đó là nhược điểm chính. – bestsss

+0

Điểm tốt cho tất cả mọi người. Giảm bớt gánh nặng xử lý null, và khả năng cụ thể hơn về "giá trị null" có nghĩa là những điểm tốt chuyên nghiệp Price.UNKNOWN. Ngoài ra, điểm tốt về "mẫu đối tượng null", nó làm cho Price.UNKNOWN cảm thấy giống như giải pháp "hợp lệ" hơn và được chấp nhận phổ biến. Nhưng, không ai cảm thấy như vậy về các khía cạnh tiêu cực của Price.UNKNOWN? Tôi cảm thấy có Price.UNKNOWN gây ô nhiễm giá trị của enum. Nói trong showAllPrices(), tôi không thể chỉ liệt kê tất cả các giá trị enum nữa, tôi phải thêm if (! Price.UNKNOWN), cảm giác hơi bẩn và "ma thuật số". – user449236

+0

* @ user449236 *: Nếu bạn không thích kiểm tra giá trị đặc biệt này, hãy thêm cờ 'display' vào mỗi enum và kiểm tra nó. Sạch hơn và linh hoạt hơn. –

Trả lời

12

tôi muốn nói đi với Price.UNKNOWN nếu đó là giá trị hợp lệ cho một mức giá.

Tôi đồng ý với những hạn chế của việc xử lý các tham chiếu null mà bạn đề cập đến và tôi nghĩ rằng chúng tạo động lực cho quyết định đủ.

Ngôn ngữ mới, lấy Scala ví dụ (và một số cũ hơn, Haskell) biến mất khỏi tham chiếu null tất cả cùng nhau và sử dụng tùy chọn/có lẽ monads thay vì ... vì lý do tốt.

27

Đây thực sự là ví dụ về cách áp dụng Null Object pattern. IMHO nó luôn luôn là tốt hơn để có một đối tượng giả hơn là null. Ví dụ, bạn có thể thêm các phương thức giả vào đối tượng null thay vì phân tán mã của bạn bằng các phép kiểm tra rỗng trên khắp nơi. Rât thuận tiện.

Ngoài ra tên của enum cung cấp cho bạn một số nghĩa bổ sung: là giá biết, không xác định, không đáng tin cậy , chưa biết? Và điều đó có nghĩa là gì nếu giá là null?

CẬP NHẬT: Vì Aaron Digulla chỉ ra, Mô hình đối tượng không yêu cầu bộ nhớ. Nhưng đây không phải là trường hợp hầu hết thời gian. Trong việc thực hiện truyền thống, bạn thường có một singleton cho đối tượng Null được sử dụng ở khắp mọi nơi vì không có nhu cầu cho các trường hợp riêng biệt. Nó thậm chí còn tốt hơn với enums bởi vì bạn nhận được ngữ nghĩa singleton miễn phí.

Một điểm khác là tham chiếu null và tham chiếu đến một số đối tượng chiếm cùng một lượng bộ nhớ (giả sử 4 byte trên máy 32 bit). Đó là đối tượng được tham chiếu chiếm một số bộ nhớ phụ. Nhưng nếu đây là một singleton, thực tế là không có phí bộ nhớ ở đây.

+0

+1 để đề cập đến mẫu. Một điểm cần lưu ý: Lý do chính tại sao mọi người không sử dụng mẫu là vì nó cần bộ nhớ (con trỏ 'null' không cần bộ nhớ). Nhưng họ quên rằng điều này làm cho mã phức tạp hơn (-> nhiều thời gian hơn để phát triển và gỡ lỗi), sự phức tạp liên quan chặt chẽ đến số lỗi và nhiều dòng mã hơn có nghĩa là mã * cần nhiều bộ nhớ hơn, vì vậy quyết định đó thường là mất trên * tất cả * biên giới. –

+0

Điểm tốt, tôi thực sự đã chỉnh sửa câu hỏi của tôi để giải quyết nhận xét của bạn. –

+0

'Lý do chính tại sao mọi người không sử dụng mẫu là vì nó cần bộ nhớ (con trỏ null không cần bộ nhớ)' lý do chính là hiệu suất như kiểm tra null có thể dễ dàng loại bỏ bởi JIT, kiểm tra null là phần cứng hỗ trợ và như vậy . – bestsss

1

Nó phụ thuộc vào cách bạn sẽ sử dụng enum này. Nếu bạn sử dụng nó trong chuyển đổi/báo cáo trường hợp nó không quan trọng. Nếu bạn tạo (các) phương thức vào trong enum, bạn thực sự phải xác định UNKNOWN.

Ví dụ, bạn có thể xác định phương pháp trừu tượng public abstract Icon icon();

vào enum của bạn và sau đó thực hiện phương pháp này đối với từng thành viên của Giá. Có lẽ bạn sẽ muốn hiển thị dấu hỏi cho giá chưa biết. Trong trường hợp này, chỉ cần triển khai phương thức icon() để tạo biểu tượng thích hợp.

1

Enum-Switch-Null-Trap. Vì vậy, có vẻ như cũng giống như với bất kỳ tài sản nào là một đối tượng, nếu nó không tồn tại thì nó là null.

0

Màu hoặc Chiều cao sẽ được sử dụng trong logic chương trình. Chúng không thể xử lý bằng màu không xác định. Giá là userdata và có thể không xác định. Màu sắc có thể là dữ liệu người dùng khác, nhưng được sử dụng làm màu trong mã, chúng phải được xác định.

Vì vậy, Giá có thể không được xác nhận (thay vì null), Màu không (null có thể cho biết lỗi).

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