Vấn đề trung tâm của NULL là nó làm cho hệ thống không đáng tin cậy. Năm 1980 Tony Hoare trong bài viết dành cho Giải thưởng Turing của mình đã viết:
Và vì vậy, lời khuyên tốt nhất của tôi cho các nhà sáng lập và thiết kế của ADA đã bị bỏ qua. Sầu. Không cho phép ngôn ngữ này ở trạng thái hiện tại được sử dụng trong các ứng dụng mà độ tin cậy là rất quan trọng, tức là các nhà máy điện hạt nhân, tên lửa hành trình, hệ thống cảnh báo sớm, hệ thống phòng thủ tên lửa chống đối kháng. Tên lửa tiếp theo đi lạc hướng do lỗi ngôn ngữ lập trình có thể không phải là tên lửa không gian thăm dò trong chuyến đi vô hại tới Sao Kim: Nó có thể là một đầu đạn hạt nhân phát nổ trên một trong những thành phố của chúng ta. Một ngôn ngữ lập trình không đáng tin cậy tạo ra các chương trình không đáng tin cậy tạo ra rủi ro lớn hơn nhiều cho môi trường và xã hội của chúng ta so với ô tô không an toàn, thuốc trừ sâu độc hại hoặc tai nạn tại các nhà máy điện hạt nhân. Hãy thận trọng để giảm thiểu rủi ro, không làm tăng nó.
Ngôn ngữ ADA đã thay đổi rất nhiều kể từ đó, tuy nhiên những vấn đề như vậy vẫn tồn tại trong Java, C # và nhiều ngôn ngữ phổ biến khác.
Nhiệm vụ của nhà phát triển là tạo hợp đồng giữa khách hàng và nhà cung cấp. Ví dụ: trong C #, như trong Java, bạn có thể sử dụng Generics
để giảm thiểu tác động của Null
tham chiếu bằng cách tạo chỉ đọc NullableClass<T>
(hai Tùy chọn):
class NullableClass<T>
{
public HasValue {get;}
public T Value {get;}
}
và sau đó sử dụng nó như là
NullableClass<Customer> customer = dbRepository.GetCustomer('Mr. Smith');
if(customer.HasValue){
// one logic with customer.Value
}else{
// another logic
}
hoặc sử dụng hai kiểu tùy chọn với các phương thức mở rộng C #:
customer.Do(
// code with normal behaviour
,
// what to do in case of null
)
Sự khác biệt là đáng kể. Là một khách hàng của một phương pháp, bạn biết những gì mong đợi. Một nhóm có thể có quy tắc:
Nếu một lớp không có kiểu NullableClass thì thể hiện của nó không phải là null .
Nhóm có thể củng cố ý tưởng này bằng cách sử dụng Thiết kế theo Hợp đồng và kiểm tra tĩnh tại thời điểm biên dịch, ví dụ: với điều kiện tiên quyết:
function SaveCustomer([NotNullAttribute]Customer customer){
// there is no need to check whether customer is null
// it is a client problem, not this supplier
}
hoặc cho một chuỗi
function GetCustomer([NotNullAndNotEmptyAttribute]String customerName){
// there is no need to check whether customerName is null or empty
// it is a client problem, not this supplier
}
Những cách tiếp cận này có thể làm tăng đáng kể độ tin cậy của ứng dụng và chất lượng phần mềm. Design by Contract là một trường hợp logic Hoare , được phổ biến bởi Bertrand Meyer trong cuốn sách Xây dựng phần mềm hướng đối tượng nổi tiếng và ngôn ngữ Eiffel vào năm 1988, nhưng nó không được sử dụng một cách không hợp lệ trong chế tạo phần mềm hiện đại.