Singleton เป็นวิธีที่ดีกว่าจากมุมมองการทดสอบ ซึ่งแตกต่างจากคลาสแบบคงที่ซิงเกิลสามารถใช้อินเตอร์เฟสและคุณสามารถใช้อินสแตนซ์จำลองและฉีดได้
ในตัวอย่างด้านล่างฉันจะอธิบายสิ่งนี้ สมมติว่าคุณมีเมธอด isGoodPrice () ซึ่งใช้เมธอด getPrice () และคุณใช้ getPrice () เป็นเมธอดในซิงเกิล
ซิงเกิลที่ให้ฟังก์ชั่น 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;
}
}
การใช้ 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();
}
การใช้งาน Singleton ขั้นสุดท้าย:
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;
}
ชั้นทดสอบ:
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);
}
}
ในกรณีที่เราเลือกใช้วิธีการคงที่ในการใช้ getPrice () มันยากที่จะจำลอง getPrice () คุณสามารถเยาะเย้ยแบบคงที่ด้วยการเยาะเย้ยพลังงาน แต่ผลิตภัณฑ์บางอย่างไม่สามารถใช้งานได้
getInstance()
วิธีการในแต่ละครั้งที่คุณต้องการใช้งาน (แม้ว่าในกรณีส่วนใหญ่อาจไม่สำคัญ )