3[Item 3]-Privateジェネレータまたは列挙タイプを使用して単一周を保証


単頓とは何ですか。


単一インスタンスとは、1つのインスタンスしか生成できないクラスです.すなわち、オブジェクトまたは設計では、一意のシステムコンポーネントである必要があります.
単一インスタンスではmockでインスタンスを置き換えることができないため、テストが困難になる可能性があります.
単輪を作成する方法は、通常、次の2つの方法の1つです.

Singletonを作成する方法


(1)共通静的finalフィールド方式の単転

  • プライベートジェネレータはElvisです.INSTANCEの初期化時に一度だけ呼び出されます.
  • には共通または保護された作成者がいないため、Evelisクラスの初期化時に作成されたインスタンスがインスタンス全体に1つしかないことを確認します.
    -->ただし、Reflection APIはオブジェクトにアクセスします.setAccessを使用してプライベートジェネレータを呼び出すことができます.
    -->ジェネレータを修正して、2番目のオブジェクトを作成しようとしたときに例外を放出します.
  • public class Elvis{
        public static final Elvis INSTANCE = new Elvis();
        private Elvis() {...}
        
        public void leaveTheBuilding() {...}
    }

    (2)静的工場式単転

  • Elvis.getInstanceは常に同じオブジェクトの参照を返すため、1つのInstanceだけが保証されます.
  • 反射API例外は(1)と同じである.
  • public class Elvis{
        private static final Elvis INSTANCE = new Elvis();
        private Elvis() {...}
        
        public static Elvis getInstance() { retrun INSTANCE; }
        
        public void leaveTheBuilding() {...}
    }
    [利点]
  • APIを変更する必要はなく、非単一ループに変更できます.
  • public static Elvis getInstance() { retrun new Elvis(); }
  • 静的工場を汎用的な単例工場に変えることができる.
  • // 제네릭으로 타입설정 가능한 인스턴스를 만들어두고, 
    // 반환 시에 제네릭으로 받은 타입을 이용해 타입을 결정한다.
    public class GenericFactoryMethod { 
    	public static final Set EMPTY_SET = new HashSet(); 
    	
        public static final <T> Set<T> emptySet() { 
    		return (Set<T>) EMPTY_SET; 
    	} 
    }
    
    출처: https://jake-seo-dev.tistory.com/13 [제이크서 블로그]
  • 静的プラントの方法を使用して、Supplierとして参照することができる.
  • Elvis::getInstaceSupplier<Evlis> 로 사용한다.

    (3)1つの要素がEnumであることを宣言する.

  • Enumであるため、Enum以外のクラスを継承する必要がある場合は、このメソッドは使用できません.
  • public enum Elvis{
    	// 인스턴스는 하나만 만들 수 있음
    	INSTANCE; 
    
    	public String getName() {
    		return "아무개";
    	}
    }
    
    String name = Elvis.INSTANCE.getName();