2013-08-05 21 views
5

Nếu tôi truy vấn một đối tượng nói cho một Động vật và đối tượng được trả về không phải là null nhưng chứa các biến null là sai? Ví dụ: tôi có thể gọi animal.getDeathDate(); và vì nó chưa chết nhưng nó trả về null. Đối với một con rùa sẽ trả về null vì nó không thể bay cho đến khi nó có thêm gói tên lửa Turtle. Ví dụ:Đối tượng Java có chứa các biến null là một mẫu không? Nếu vậy thì cái nào?

Tôi nghĩ rằng đây là một cách xấu để thực hiện mọi việc vì nó thường gây ra rất nhiều kiểm tra rỗng khi gọi các phương thức của đối tượng để xác minh rằng chúng chứa giá trị không null. Có bất kỳ liên kết nào đến thông tin về điều này có thể thông báo cho cả bản thân tôi và đồng nghiệp của tôi hơn nữa không?

+1

Bạn có thể muốn mẫu đối tượng Null. – SLaks

+0

Tôi đã đọc về mẫu đối tượng Null nhưng tôi không chắc liệu nó có đề cập đến các đối tượng có biến null hay không. Tôi nghĩ rằng nó có liên quan nhiều hơn đến việc một null hoặc một đối tượng nên được trả về từ một phương thức truy vấn chứ không phải là một đối tượng dữ liệu. – FooBar

+1

Mô hình đối tượng Null về cơ bản áp dụng cho mọi 'null'. Việc đảm bảo các giá trị không null làm cho mã dễ dàng hơn nhiều. – zapl

Trả lời

4

null thường mơ hồ. Đã được uninitialized lĩnh vực nào được nêu ra hoặc nó chỉ không có giá trị?

Thường tốt hơn để có một số hằng số được xác định trước cho các trường không được khởi tạo/không liên quan.

Thậm chí tốt hơn là có một lớp chỉ có một trách nhiệm. Phương pháp như không nên được kế thừa, thay vì đến từ việc triển khai giao diện (các phương thức như getDeathDate(), tuy nhiên, phải có hằng số được xác định trước được trả lại khi Animal vẫn còn hoạt động).

As brought by google-guava docs:

Doug Lea (tác giả của java.util.concurrent gói) cho biết Null s**ks.

Ngoài ra sir C. A. R. Hoare, nhà phát minh của tài liệu tham khảo null cho biết: I call it my billion-dollar mistake.

Đó là một số vai rộng để đặt trên.

+0

Đó là ý kiến ​​của tôi, tôi đã hy vọng cho một số tài liệu tham khảo để giúp hỗ trợ nó mặc dù. Đã không thể bật lên nhiều hơn một cuộc tranh luận khá lớn xung quanh Mô hình đối tượng Null thông qua Google. – FooBar

+0

@FooBar đã thêm một số tham chiếu. – yair

+0

Bạn đề xuất gì cho 'getDeathDate()' để trả về? – Gabe

1

Null đôi khi có thể là một cách hoàn toàn hợp lý để đại diện cho một đối tượng thiếu một thuộc tính cụ thể.

Tuy nhiên, thật hữu ích khi cho phép kiểm tra đơn.

Đối với một mảng hoặc Danh sách, thường tốt hơn là nên có một biến số không phải là rỗng, nhưng có thể trỏ đến một danh sách trống. Nếu không, nó trở nên cần thiết để kiểm tra cả hai biến là không null và danh sách có các thành viên.

0

Đây chỉ là ý kiến ​​của tôi, nhưng ví dụ của bạn có vẻ giống như một mô hình chống (như một đối tượng rỗng thoái hóa), vì bạn sẽ cần phải thực hiện kiểm tra null về những phương thức trên đối tượng "null object". Nếu bạn không gọi những getters đó, thì ví dụ của bạn sẽ chính xác. Ý tưởng với các đối tượng null là bạn không cần phải thực hiện kiểm tra null, vì vậy nó có thể hoạt động nếu getters của bạn trả về các đối tượng null khác hoặc các phương thức sử dụng phương thức tell-don't-ask (và chỉ trả lại void).

4

Trở null cho ngày tử hình đối với một con vật còn sống là hoàn toàn hợp lý, nhưng trong những trường hợp như thế này tôi thấy nó tốt hơn để cung cấp một kiểm tra cái chết boolean:

public boolean isDead() { 
    return deathDate != null; 
} 

này cung cấp một cách hợp lý kiểm tra cái chết -ness của một thể hiện mà không có một kiểm tra null vụng về của thuộc tính:

// this is ugly and exposes the choice of the value of the field when alive 
if (animal.getDeathDate() != null) { 
    // the animal is dead 
} 

với isDead() phương pháp tại chỗ, bạn sẽ nằm trong quyền hạn của mình để làm điều này:

public Date getDeathDate() { 
    if (deathDate == null) 
     throw new IllegalStateException("Death has not occurred"); 
    return deathDate; 
} 

Về tốc độ bay của con rùa, bạn có thể áp dụng phương pháp tương tự, mặc dù tôi cho rằng có một vấn đề trong thiết kế lớp học của bạn - không phải tất cả động vật bay, vì vậy lớp Animal không nên có một getFlyingSpeed() phương pháp.

Thay vào đó, sử dụng một cái gì đó như thế này:

interface Flyer { 
    Integer getFlightSpeed(); 
} 

class Animal {} 

class Turtle extends Animal {} 

class Eagle extends Animal implements Flyer { 
    public Integer getFlightSpeed() { 
     // 
    } 
} 
+0

cho trường hợp getFlyingSpeed, thay vì thực hiện một giao diện, chúng ta có thể có một biến cá thể trong lớp Animal tham chiếu đến loại Flyer (sẽ có hai phương thức trong giao diện này có thể bay và có tốc độ bay) không? – Atul

+0

Có một canFly() là không cần thiết hoặc mong muốn, bởi vì a) bạn có thể sử dụng 'if (animal instaceof Flyer)', và b) bạn cần phải cast để Flyer anyway để truy cập các phương thức Flyer, vì vậy bạn đã biết đó là Flyer bởi vì bạn phải thực hiện một bản kiểm tra trước khi bạn có thể truyền. – Bohemian

0

Null là hoàn toàn tốt đẹp, nhưng bạn nên cố gắng tránh chúng bằng giá trị mặc định càng nhiều càng tốt

Ví dụ danh sách trống nên được trả lại thay vì of null loại dữ liệu enum phải chứa UNKNOWN

Giả định trên làm cho cuộc sống của người tiêu dùng API dễ dàng

trong ví dụ của bạn, tôi sẽ trả về null từ animal.getDeathDate vì tôi không thể nghĩ ra bất kỳ giá trị mặc định phù hợp nào.

tôi sẽ cung cấp phương pháp thuận tiện animal.isDead trở về đúng/sai

Đối getFlightSpeed ​​() Tôi sẽ trở về 0 cho trường hợp của bạn

0

Null Object mẫu thực sự có thể được sử dụng trong trường hợp của các biến null. Trong trường hợp của Turtle.getFlightSpeed ​​(), bạn có thể trừu tượng ra khái niệm SPEED (có thể là giao diện hoặc lớp trừu tượng), và có một đối tượng NULL thực hiện "không thể bay" kịch bản. Điều này sẽ giúp gán hành vi mặc định cho các lớp Rùa. Trả về giá trị rỗng trong trường hợp animal.getDeathDate() có vẻ như là

1

Tôi không nghĩ là sai. Là một loại suy, suy nghĩ của ngữ nghĩa của NULL in SQL:

Một cách tốt để nhớ những gì NULL có nghĩa là hãy nhớ rằng về mặt thông tin "thiếu một giá trị" không phải là điều tương tự như "một giá trị của không "; tương tự, "thiếu câu trả lời" không giống với câu trả lời "an ".

Hoàn toàn hợp lệ để áp dụng cùng một logic trong Java.

Để làm cho các loại nguyên thủy không thể sử dụng được, hãy xem nullable types in C#. Nó sẽ dễ dàng thực hiện Nullable như một Java generic.

0

Tôi nghĩ rằng đối với động vật.getDeathDate() trả về null nếu con vật còn sống là cách chính xác để làm việc. Bạn sẽ luôn cần mã đặc biệt để xử lý 2 trường hợp: động vật còn sống, và động vật chết, và không có ngày hữu ích nào bạn có thể trả lại nếu động vật còn sống.

Đối với getFlightSpeed ​​() mọi thứ có thể khác nhau. Tôi không biết chính xác những gì nó trả về nhưng chúng ta hãy chỉ cho một ví dụ tưởng tượng nó chỉ trả về tốc độ như m/s

Trong trường hợp đó trở về 0 (Hoặc một đối tượng có cùng hiệu quả) sẽ có ý nghĩa hoàn hảo, bởi vì nó mô tả tốc độ bay.

+0

"Tôi nghĩ rằng đối với animal.getDeathDate() trả về null nếu động vật còn sống là cách chính xác để làm việc." Vâng, nếu con vật đã chết, nhưng không ai biết khi nào? –

1

Quy tắc kiểm tra không chính xác tôi không bao giờ được đặt null thay vì danh sách hoặc mảng.

Danh sách và mảng trống tốt hơn nhiều để thể hiện những gì chúng thực sự là.

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