Singleton là cách tiếp cận tốt hơn từ quan điểm thử nghiệm. Không giống như các lớp tĩnh, singleton có thể thực hiện các giao diện và bạn có thể sử dụng thể hiện giả và tiêm chúng.
Trong ví dụ dưới đây tôi sẽ minh họa điều này. Giả sử bạn có một phương thức is Goodprice () sử dụng phương thức getprice () và bạn triển khai getprice () làm phương thức trong một singleton.
singleton cung cấp chức năng getprice:
public class SupportedVersionSingelton {
private static ICalculator instance = null;
private SupportedVersionSingelton(){
}
public static ICalculator getInstance(){
if(instance == null){
instance = new SupportedVersionSingelton();
}
return instance;
}
@Override
public int getPrice() {
// calculate price logic here
return 0;
}
}
Sử dụng getprice:
public class Advisor {
public boolean isGoodDeal(){
boolean isGoodDeal = false;
ICalculator supportedVersion = SupportedVersionSingelton.getInstance();
int price = supportedVersion.getPrice();
// logic to determine if price is a good deal.
if(price < 5){
isGoodDeal = true;
}
return isGoodDeal;
}
}
In case you would like to test the method isGoodPrice , with mocking the getPrice() method you could do it by:
Make your singleton implement an interface and inject it.
public interface ICalculator {
int getPrice();
}
Thực hiện Singleton cuối cùng:
public class SupportedVersionSingelton implements ICalculator {
private static ICalculator instance = null;
private SupportedVersionSingelton(){
}
public static ICalculator getInstance(){
if(instance == null){
instance = new SupportedVersionSingelton();
}
return instance;
}
@Override
public int getPrice() {
return 0;
}
// for testing purpose
public static void setInstance(ICalculator mockObject){
if(instance != null ){
instance = mockObject;
}
lớp kiểm tra:
public class TestCalculation {
class SupportedVersionDouble implements ICalculator{
@Override
public int getPrice() {
return 1;
}
}
@Before
public void setUp() throws Exception {
ICalculator supportedVersionDouble = new SupportedVersionDouble();
SupportedVersionSingelton.setInstance(supportedVersionDouble);
}
@Test
public void test() {
Advisor advidor = new Advisor();
boolean isGoodDeal = advidor.isGoodDeal();
Assert.assertEquals(isGoodDeal, true);
}
}
Trong trường hợp chúng tôi sử dụng phương pháp thay thế bằng cách sử dụng phương thức tĩnh để triển khai getprice (), rất khó để giả định getprice (). Bạn có thể giả lập tĩnh với mock điện, nhưng không phải tất cả các sản phẩm đều có thể sử dụng nó.
getInstance()
phương thức mỗi lần bạn muốn sử dụng nó (mặc dù có thể trong hầu hết các trường hợp không thành vấn đề ).