2013-05-25 24 views
10

Tôi đang viết mã truy vấn cơ sở dữ liệu để lấy dữ liệu. Có một số lớp bao gồm List s, nhưng đôi khi danh sách hoặc thuộc tính khác không thể được bắt đầu và giá trị của chúng là null, vì vậy tôi cần viết list!=null || list.isEmpty hoặc attribute != null, trước khi tôi có thể sử dụng thuộc tính.Cách tránh viết mã như "XXX! = Null" hoặc "XXX! = Null || XXX.isEmpty"

Thật không may, nó dễ quên nó, và tôi thực sự nghĩ rằng nó là xấu xí để làm điều đó mỗi khi tôi vận hành một thuộc tính. Tôi sẽ viết một số mã để giải thích nó.

public class SpotVo { 
    private Double avg; 

    private String brief; 

    private ArrayList<HotelVo> hotels; 

    private int id; 

    private ArrayList<byte[]> images; 

    private AddressVo location; 

    private String name; 

    private ArrayList<RestaurantVo> restaurants; 
} 

Như bạn có thể thấy, có một số danh sách và các thuộc tính khác trong lớp này, có tất cả có thể null hoặc trống rỗng, tôi có thể làm điều gì đó để tránh nó?

+1

Tôi nghĩ cách tốt nhất để tránh loại mã xấu này là luôn viết các phương thức ngắn, đơn giản, súc tích chỉ thực hiện một tác vụ cơ bản. Nếu bạn làm điều này, bạn thường có thể thực hiện một kiểm tra rỗng sạch ở đầu mỗi phương thức và thoát ngay lập tức nếu một cái gì đó quan trọng là null. Tôi có một giáo sư ở trường nói với chúng tôi rằng "chức năng bạn viết phải ít hơn 60 dòng_". Đó là một số lời khuyên tốt nhất mà tôi từng có. – jahroy

+1

@jahroy * "mọi phương thức nên nhỏ hơn 60 dòng" * amen, anh trai. – acdcjunior

+0

Tôi đã học được một phiên bản khác mà đá một người đàn ông viết một phương pháp có 10 dòng trong số bạn hạn. – ssj

Trả lời

3

Câu trả lời tùy thuộc vào việc null có ý nghĩa đặc biệt hay không. Ví dụ: đối với trường String, đơn đăng ký của bạn có cần phân biệt giữa null"" không? Đối với trường có giá trị Collection, cần phân biệt giữa null và đối tượng thu thập trống không?

Nếu câu trả lời là "không", thì bạn có thể viết các lớp "đối tượng dữ liệu" để chuẩn hóa các giá trị rỗng thành các giá trị "trong dải" tương ứng. Bạn có thể làm điều này trong getters hoặc setters hoặc constructors, tùy thuộc vào chính xác cách các đối tượng được vật chất hóa từ cơ sở dữ liệu.

Một vài điều khác mà bạn có thể làm là:

  • Thay đổi giản đồ cơ sở dữ liệu để làm các cột tương ứng "không null".

  • Nếu bạn đang sử dụng ORM hoặc cơ chế ràng buộc dữ liệu, hãy cố gắng định cấu hình (thông qua chú thích hoặc bất kỳ thứ gì) để sử dụng giá trị "trong băng" thay vì null.

Mấu chốt của biến null vào "" hoặc một mảng rỗng hoặc bộ sưu tập là bạn không cần phải đối xử với "trong ban nhạc" giá trị như một trường hợp đặc biệt ... trừ phi logic kinh doanh của ứng dụng của bạn đặc biệt yêu cầu điều này.

Tóm lại, nếu bạn đóng dấu một cách có hệ thống các giá trị null, bạn không cần kiểm tra chúng trong logic nghiệp vụ.


Lưu ý rằng cách tiếp cận này không phải lúc nào cũng hoạt động. Các trường hợp đó làm phiền tôi được lấy thông số từ một đối tượng HTTPRequest trong một servlet:

  • Ứng dụng này có khả năng phải đối phó với 4 trường hợp riêng biệt:

    • tham số không có mặt tham số

    • không có giá trị/giá trị trống

    • tham số có giá trị không trống

    • tham số hiển thị nhiều lần.

  • Tham số đang được tìm nạp từ API chuẩn thay vì lớp tùy chỉnh có thể được thực hiện để chuẩn hóa các giá trị theo yêu cầu của webapp.

+1

Tôi nghĩ bạn đúng, tôi nên kiểm soát nó từ nguồn. – ssj

+0

Tôi nghĩ rằng vì kỹ thuật này sẽ giúp bạn tiết kiệm từ việc gửi các đối tượng hoặc null không có lý do trong trường hợp nếu null hoặc "" cho Strings – YouYou

0

Bạn có thể viết chức năng kiểm tra xem đối tượng có là null và/hoặc nếu đó là một Chuỗi, là "". Sau đó, chỉ cần gọi hàm đó mỗi khi bạn cần kiểm tra tất cả các điều kiện. Làm cho nó trở lại một boolean để bạn chỉ có thể chèn nó trong các tuyên bố if.

boolean check(Object o) 
{ 
    if (o != null) 
     { 
      if (o instanceof String) 
      { 
       if (((String) o).equals("")) 
        return false; 
      } 
      return true; 
     } 
     return false; 
} 

Tham khảo đề xuất của RCook trong các nhận xét để triển khai tốt hơn điều này.

+0

nhưng tôi không thể viết chức năng cho mọi lớp mà tôi đã sử dụng trong ứng dụng của mình. – ssj

+0

kiểm tra chỉnh sửa của tôi. Nó sẽ làm việc cho tất cả các đối tượng (tất cả các lớp được định nghĩa của bạn ngầm mở rộng Object). Nếu bạn có bất kỳ trường hợp đặc biệt nào khác cho các đối tượng cụ thể, ngoài String, bạn có thể chèn chúng vào hàm. –

+3

Thay vì sử dụng instanceof, có một phương thức cho Object và một cho String. Hãy để trình biên dịch quyết định cái nào để gọi và lưu thời gian chạy của bạn một câu lệnh if ... boolean isEmpty (Object o) {return (o == null); } (thứ gì đó cần thiết cho các bộ sưu tập) – arcy

0

Cách dễ nhất để giải quyết vấn đề này là với CollectionUtils.isEmpty.

Returns: true nếu trống hoặc null

Bằng cách này bạn có thể làm điều đó trong một dòng.

Khi nói đến "thuộc tính", có các mẫu thiết kế có thể trợ giúp với điều này. Hoặc, bạn có thể sử dụng lớp Guava's Optional. Bạn có thể đọc thêm tại đây: What's the point of Guava's Optional class

0

Tôi nghĩ có hai vấn đề ở đây: Một là bạn phải kiểm tra các giá trị null mà tôi hoàn toàn đồng ý là ngu ngốc. Vấn đề là null là một bản địa của ngôn ngữ Java, do đó, cách duy nhất để làm cho nó đẹp hơn là sử dụng các phương pháp như những người được đề cập bởi Steve P và tieTYT. Tuy nhiên, có một cách khác để xử lý null bằng không bao giờ sử dụng nó. Tất nhiên bạn không thể hoàn toàn tránh được nó, nhưng ít nhất là trong mã của riêng bạn, bạn nên loại bỏ tất cả null -references. Có một vài lý lẽ tuyệt vời mà tôi sẽ không đề cập ở đây, nhưng bạn có thể đọc Avoiding != null statements để biết thêm chi tiết.

Nếu bạn quan tâm đến ngôn ngữ dựa trên Java, Scala, đã phát triển độc đáo này bằng cách triển khai lớp Tùy chọn có thể cho biết giá trị tồn tại hay không (bằng giá trị null). Bài đăng trên blog đẹp về nó ở đây: http://jim-mcbeath.blogspot.fr/2008/10/avoiding-nulls.html

Có (chủ yếu) xếp hàng không có vấn đề, vấn đề tiếp theo sẽ là kiểm tra isEmpty hoặc tương tự khi sử dụng bộ sưu tập. Đây là, như bạn nói, một nỗi đau trong ass. Nhưng tôi đã thực sự thấy rằng những kiểm tra này có thể tránh được phần lớn. Tất cả phụ thuộc vào những gì bạn cần làm với bộ sưu tập của bạn tất nhiên, nhưng trong hầu hết các trường hợp bộ sưu tập được sử dụng để đi qua hoặc thao tác theo một cách nào đó. Sử dụng vòng lặp foreach trong Java sẽ đảm bảo không có gì được thực hiện nếu không có gì trong bộ sưu tập. Khéo léo.

Có một số trường hợp bộ sưu tập không được để trống.Mặc dù vậy, một số trong số này có thể tránh được, bằng cách thiết kế tốt (ví dụ như một danh sách trống, đảm bảo rằng không có danh sách nào trống ...), nhưng đối với phần còn lại của chúng không có cách nào xung quanh. Không bao giờ. Tuy nhiên, đã loại bỏ các kiểm tra null, gọi một vài isEmpty bây giờ và sau đó không phải là xấu :-)

Hy vọng rằng đã giúp.

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