Creating an Interface To a Language’s Standard Library?

In the process of learning test-driven development, I’ve been introduced to dependency injection and the use of interfaces, and have started using these concepts in my own PHP code in order to make it more testable.

There have been times when I’ve needed to test code that was doing things like calling the PHP time() function. In order to make these tests predictable, it seemed logical to create an interface to the standard PHP functions I use so that I can mock them out in my tests.

Is this good software design? What are the pros and cons of doing this? I’ve found myself groaning at how quickly my PHP interface can stick its fingers into everything I do. Is there a better way to make code that relies on PHP-accessed state and functions more testable?

3

You should abstract away calls to time() like you should abstract away calls to rand() and its ilk. The reason for doing that is because functions like that are forms of global, non-deterministic state. Global, non-deterministic state makes testing much more difficult because you cannot isolate your tests and test all conditions at once. Imagine if I had to wait until after noon to see if my code said “Good afternoon” instead of “Good morning” or “Good evening”!

If you see your interface starting to permeate your application, this may not be a bad thing. If anything, it is telling you how much you are using these built-in functions. You can depend on you to maintain your code and your interfaces within your code base, so you should not have as many worries about a shifting interface causing shotgun surgery. Abstracting away time() should be a pretty stable interface and probably should not see any changes for the most part.

The alternative to an interface is to simply inject the result of a call to time() rather than calling it in the method. So write getGreeting(time()); rather than writing getGreeting($timeUtil); (which in the method does $time = $timeUtil->getTime()). This adheres more closely to the Law of Demeter as you are not reaching for one thing through another, but it also means that the time you want must be the time at which the method is invoked.

An alternative alternative is to pass in a function reference rather than generating a separate interface. In PHP, you could do something like:

function getTime($timeFunc) {
    return call_user_func($timeFunc);
}

echo getTime('time')."n"; # Call the built-in time function
echo getTime(function() { # Call a custom function
    return 1;
})."n";

This has less overhead than the full-blown interface while still allowing the function to be lazily called and allowing dependency injection.

3

You can either

  • create interfaces to system state methods like date or the content of session/cookie as you suggested or,
  • put these infos into business-method as additional parameters.

Example:

  • the invoice module can get the invoice date itself through an interface or,
  • the caller of the invoice module can provide the invoice date.

I prefer the 2nd method although this means that every time the module needs more state infos you have to change the method signature. On the other side in testing it is much easier to provide parameter than to mock methods.

I’ve found myself groaning at how quickly
my PHP interface can stick its fingers into everything I do.

If your module needs too many parameters or too many interfaces, this might be an indicator that your module is doing too much and violates “separations of concerns.”

1

Trang chủ Giới thiệu Sinh nhật bé trai Sinh nhật bé gái Tổ chức sự kiện Biểu diễn giải trí Dịch vụ khác Trang trí tiệc cưới Tổ chức khai trương Tư vấn dịch vụ Thư viện ảnh Tin tức - sự kiện Liên hệ Chú hề sinh nhật Trang trí YEAR END PARTY công ty Trang trí tất niên cuối năm Trang trí tất niên xu hướng mới nhất Trang trí sinh nhật bé trai Hải Đăng Trang trí sinh nhật bé Khánh Vân Trang trí sinh nhật Bích Ngân Trang trí sinh nhật bé Thanh Trang Thuê ông già Noel phát quà Biểu diễn xiếc khỉ Xiếc quay đĩa Dịch vụ tổ chức sự kiện 5 sao Thông tin về chúng tôi Dịch vụ sinh nhật bé trai Dịch vụ sinh nhật bé gái Sự kiện trọn gói Các tiết mục giải trí Dịch vụ bổ trợ Tiệc cưới sang trọng Dịch vụ khai trương Tư vấn tổ chức sự kiện Hình ảnh sự kiện Cập nhật tin tức Liên hệ ngay Thuê chú hề chuyên nghiệp Tiệc tất niên cho công ty Trang trí tiệc cuối năm Tiệc tất niên độc đáo Sinh nhật bé Hải Đăng Sinh nhật đáng yêu bé Khánh Vân Sinh nhật sang trọng Bích Ngân Tiệc sinh nhật bé Thanh Trang Dịch vụ ông già Noel Xiếc thú vui nhộn Biểu diễn xiếc quay đĩa Dịch vụ tổ chức tiệc uy tín Khám phá dịch vụ của chúng tôi Tiệc sinh nhật cho bé trai Trang trí tiệc cho bé gái Gói sự kiện chuyên nghiệp Chương trình giải trí hấp dẫn Dịch vụ hỗ trợ sự kiện Trang trí tiệc cưới đẹp Khởi đầu thành công với khai trương Chuyên gia tư vấn sự kiện Xem ảnh các sự kiện đẹp Tin mới về sự kiện Kết nối với đội ngũ chuyên gia Chú hề vui nhộn cho tiệc sinh nhật Ý tưởng tiệc cuối năm Tất niên độc đáo Trang trí tiệc hiện đại Tổ chức sinh nhật cho Hải Đăng Sinh nhật độc quyền Khánh Vân Phong cách tiệc Bích Ngân Trang trí tiệc bé Thanh Trang Thuê dịch vụ ông già Noel chuyên nghiệp Xem xiếc khỉ đặc sắc Xiếc quay đĩa thú vị
Trang chủ Giới thiệu Sinh nhật bé trai Sinh nhật bé gái Tổ chức sự kiện Biểu diễn giải trí Dịch vụ khác Trang trí tiệc cưới Tổ chức khai trương Tư vấn dịch vụ Thư viện ảnh Tin tức - sự kiện Liên hệ Chú hề sinh nhật Trang trí YEAR END PARTY công ty Trang trí tất niên cuối năm Trang trí tất niên xu hướng mới nhất Trang trí sinh nhật bé trai Hải Đăng Trang trí sinh nhật bé Khánh Vân Trang trí sinh nhật Bích Ngân Trang trí sinh nhật bé Thanh Trang Thuê ông già Noel phát quà Biểu diễn xiếc khỉ Xiếc quay đĩa

Creating an Interface To a Language’s Standard Library?

In the process of learning test-driven development, I’ve been introduced to dependency injection and the use of interfaces, and have started using these concepts in my own PHP code in order to make it more testable.

There have been times when I’ve needed to test code that was doing things like calling the PHP time() function. In order to make these tests predictable, it seemed logical to create an interface to the standard PHP functions I use so that I can mock them out in my tests.

Is this good software design? What are the pros and cons of doing this? I’ve found myself groaning at how quickly my PHP interface can stick its fingers into everything I do. Is there a better way to make code that relies on PHP-accessed state and functions more testable?

3

You should abstract away calls to time() like you should abstract away calls to rand() and its ilk. The reason for doing that is because functions like that are forms of global, non-deterministic state. Global, non-deterministic state makes testing much more difficult because you cannot isolate your tests and test all conditions at once. Imagine if I had to wait until after noon to see if my code said “Good afternoon” instead of “Good morning” or “Good evening”!

If you see your interface starting to permeate your application, this may not be a bad thing. If anything, it is telling you how much you are using these built-in functions. You can depend on you to maintain your code and your interfaces within your code base, so you should not have as many worries about a shifting interface causing shotgun surgery. Abstracting away time() should be a pretty stable interface and probably should not see any changes for the most part.

The alternative to an interface is to simply inject the result of a call to time() rather than calling it in the method. So write getGreeting(time()); rather than writing getGreeting($timeUtil); (which in the method does $time = $timeUtil->getTime()). This adheres more closely to the Law of Demeter as you are not reaching for one thing through another, but it also means that the time you want must be the time at which the method is invoked.

An alternative alternative is to pass in a function reference rather than generating a separate interface. In PHP, you could do something like:

function getTime($timeFunc) {
    return call_user_func($timeFunc);
}

echo getTime('time')."n"; # Call the built-in time function
echo getTime(function() { # Call a custom function
    return 1;
})."n";

This has less overhead than the full-blown interface while still allowing the function to be lazily called and allowing dependency injection.

3

You can either

  • create interfaces to system state methods like date or the content of session/cookie as you suggested or,
  • put these infos into business-method as additional parameters.

Example:

  • the invoice module can get the invoice date itself through an interface or,
  • the caller of the invoice module can provide the invoice date.

I prefer the 2nd method although this means that every time the module needs more state infos you have to change the method signature. On the other side in testing it is much easier to provide parameter than to mock methods.

I’ve found myself groaning at how quickly
my PHP interface can stick its fingers into everything I do.

If your module needs too many parameters or too many interfaces, this might be an indicator that your module is doing too much and violates “separations of concerns.”

1

Trang chủ Giới thiệu Sinh nhật bé trai Sinh nhật bé gái Tổ chức sự kiện Biểu diễn giải trí Dịch vụ khác Trang trí tiệc cưới Tổ chức khai trương Tư vấn dịch vụ Thư viện ảnh Tin tức - sự kiện Liên hệ Chú hề sinh nhật Trang trí YEAR END PARTY công ty Trang trí tất niên cuối năm Trang trí tất niên xu hướng mới nhất Trang trí sinh nhật bé trai Hải Đăng Trang trí sinh nhật bé Khánh Vân Trang trí sinh nhật Bích Ngân Trang trí sinh nhật bé Thanh Trang Thuê ông già Noel phát quà Biểu diễn xiếc khỉ Xiếc quay đĩa Dịch vụ tổ chức sự kiện 5 sao Thông tin về chúng tôi Dịch vụ sinh nhật bé trai Dịch vụ sinh nhật bé gái Sự kiện trọn gói Các tiết mục giải trí Dịch vụ bổ trợ Tiệc cưới sang trọng Dịch vụ khai trương Tư vấn tổ chức sự kiện Hình ảnh sự kiện Cập nhật tin tức Liên hệ ngay Thuê chú hề chuyên nghiệp Tiệc tất niên cho công ty Trang trí tiệc cuối năm Tiệc tất niên độc đáo Sinh nhật bé Hải Đăng Sinh nhật đáng yêu bé Khánh Vân Sinh nhật sang trọng Bích Ngân Tiệc sinh nhật bé Thanh Trang Dịch vụ ông già Noel Xiếc thú vui nhộn Biểu diễn xiếc quay đĩa Dịch vụ tổ chức tiệc uy tín Khám phá dịch vụ của chúng tôi Tiệc sinh nhật cho bé trai Trang trí tiệc cho bé gái Gói sự kiện chuyên nghiệp Chương trình giải trí hấp dẫn Dịch vụ hỗ trợ sự kiện Trang trí tiệc cưới đẹp Khởi đầu thành công với khai trương Chuyên gia tư vấn sự kiện Xem ảnh các sự kiện đẹp Tin mới về sự kiện Kết nối với đội ngũ chuyên gia Chú hề vui nhộn cho tiệc sinh nhật Ý tưởng tiệc cuối năm Tất niên độc đáo Trang trí tiệc hiện đại Tổ chức sinh nhật cho Hải Đăng Sinh nhật độc quyền Khánh Vân Phong cách tiệc Bích Ngân Trang trí tiệc bé Thanh Trang Thuê dịch vụ ông già Noel chuyên nghiệp Xem xiếc khỉ đặc sắc Xiếc quay đĩa thú vị
Trang chủ Giới thiệu Sinh nhật bé trai Sinh nhật bé gái Tổ chức sự kiện Biểu diễn giải trí Dịch vụ khác Trang trí tiệc cưới Tổ chức khai trương Tư vấn dịch vụ Thư viện ảnh Tin tức - sự kiện Liên hệ Chú hề sinh nhật Trang trí YEAR END PARTY công ty Trang trí tất niên cuối năm Trang trí tất niên xu hướng mới nhất Trang trí sinh nhật bé trai Hải Đăng Trang trí sinh nhật bé Khánh Vân Trang trí sinh nhật Bích Ngân Trang trí sinh nhật bé Thanh Trang Thuê ông già Noel phát quà Biểu diễn xiếc khỉ Xiếc quay đĩa
Thiết kế website Thiết kế website Thiết kế website Cách kháng tài khoản quảng cáo Mua bán Fanpage Facebook Dịch vụ SEO Tổ chức sinh nhật