문제

나는 각각의 객체 세트를 만드는 것을 목표로하고 있으며, 각 객체에는 고유 식별자가 있습니다. 해당 식별자와 함께 객체가 이미 존재하는 경우 기존 객체를 사용하고 싶습니다. 그렇지 않으면 나는 새로운 것을 만들고 싶습니다. 싱글 톤이라는 단어를 사용하지 않으려 고 노력하고 있습니다. 여기서 더러운 단어라는 것을 알고 있기 때문입니다 ...

공장 방법을 사용할 수 있습니다.

    // A map of existing nodes, for getInstance.
private static Map<String, MyClass> directory = new HashMap<String, MyClass>();

public static MyClass getInstance(String name) {
    MyClass node = directory.get(name);
    if(node == null) {
       node == new MyClass(name);
    }
    return node;
}

또는 마찬가지로, 나는 별도의 myclassFactory 방법을 가질 수 있습니다.

그러나 나는 myclass를 서브 클래스하려고했다.

public class MySubClass extends MyClass;

더 이상하지 않고 mysubclass.getInstance ()를 호출하면 :

MyClass subclassObj = MySubClass.getInstance("new name");

... 그러면 하위 클라스 로즈는 mysubclass가 아닌 평범한 myclass가 될 것입니다.

그러나 모든 서브 클래스에서 getinstance ()를 우선적으로 보는 것은 해킹 된 것 같습니다.

내가 놓친 깔끔한 솔루션이 있습니까?


그것이 일반화 된 질문의 일반화 된 버전입니다. 답변자가 요청한 이후 더 자세한 내용.

이 프로그램은 소프트웨어를 나타내는 노드간에 의존성의 지시 된 그래프를 생성하는 것입니다. 서브 클래스에는 Java 프로그램, 웹 서비스, 저장된 SQL 절차, 메시지 중심 트리거 등이 포함됩니다.

따라서이 네트워크의 각 클래스 "IS-A"요소이며 다른 노드와 의존성 관계를 탐색하고 수정하는 방법이 있습니다. 서브 클래스 간의 차이는 populate() 적절한 소스에서 객체를 설정하는 데 사용되는 방법.

'login.java'라는 노드가 'checkpasswd.sqlpl'에 의존한다는 것을 알 수 있습니다.

this.addDependency( NodeFactory.getInstance("checkpasswd.sqlpl"));

문제는 checkpasswd.sqlpl 객체가 현재 존재하거나 존재하지 않을 수도 있다는 것입니다.

도움이 되었습니까?

해결책

정적 메소드는 상위 클래스에서 정의되며 정적으로도 불립니다. 따라서 서브 클래스에서 호출 한 방법에서 알 수있는 방법은 없습니다. Java 컴파일러는 아마도 상위 클래스에 대한 통화로 통화를 정적으로 해결할 수도 있습니다.

따라서 제안대로 자녀 수업에서 정적 메소드를 다시 구현하거나 정적이 아닌 공장의 계층 구조에서 상속을 할 수 있도록 정적이되지 않도록해야합니다. 사물, 클래스가 아님) 또는 매개 변수를 전달하여 작성하려는 유형을 나타냅니다.

enumset.noneof () 메소드를 확인하십시오. 그것은 당신과 비슷한 문제가 있으며 Java.lang.class 메소드를 통과하여 해결합니다. 수업에서 NewInstance를 사용할 수 있습니다. 그러나 개인적으로, 나는 정적 방법을 가진 클래스보다는 공장 객체를 사용합니다.

다른 팁

Guice를 살펴 보셨습니까? 문제가 정확히 해결 될지 확실하지 않지만 일반적인 공장 및 의존성 주입 컨테이너 역할을하며 타입이 아닌 안전한 스트링 키를 제거합니다.

읽은 후에 문제에 대한 설명을 설명하면 그래프 구성에서 하위 분류를 통해 자신이 매우 어렵다고 생각합니다. 의존성 그래프를 "프로그램 정보"에서 분리하면 문제가 훨씬 간단 해진다고 생각합니다.

다음과 같은 인터페이스를 사용하십시오.

Public Interface Node<T> {
  public Object<T>    getObject();
  public String       getKey();
  public List<String> getDependencies();
  public void         addDependence(String dep);
}

그런 다음 공장을 사용하여 노드를 인스턴스화하십시오

당신은 어딘가에 당신이 존재하지 않으면 어떤 클래스가되어야하는지 아는 것을 암시하는 것 같습니다. 공장에서 해당 논리를 구현하면 올바른 클래스를 얻어야합니다.

이렇게하면 공장에서 실제로 어떤 클래스가 반환되었는지 알 필요가 없습니다.

공장 패턴을 고려하고 있다면 'MyClass'를 인터페이스로 만들 것입니다.

클래스 클래스는 생성 할 수있는 인스턴스 유형으로 매개 변수화됩니다. (예 : 수업u003CString> 문자열 인스턴스를위한 공장입니다.)

여기에서 공장 메소드를 사용하여 생성 할 때 생성해야 할 인스턴스 유형을 알 수있는 방법이 없으므로 생성 된 유형에 대한 메소드에 전달하고 매개 변수를 전달하는 것이 좋습니다.

private static Map<String, MyClass> directory = new HashMap<String, MyClass>();

public static <T extends MyClass> T getInstance(String name, Class<T> generatorClass)
{
  MyClass node = directory.get(name);    
  if(node == null) {
    node = generatorClass.getConstructor(String.class).newInstance(name);
    directory.put(name, node);
  }
  return node;
}

또한, 나는 당신이 실제로 새로 구성된 노드를 디렉토리에 넣지 않았다는 것을 알았습니다. 저는 그것이 감독이라고 가정합니다. 이 메소드가 발전기를 가져 가지 않고 기본 유형으로 하드 코딩하는 다른 방법 에이 방법을 과부하 할 수도 있습니다.

public static MyClass getInstance(String name) {
  return getInstance(name, MyClass.class);
}

당신은 아마도 종속성 주입을 원할 것입니다. 그것은 당신이 다소하려고하는 일을 일반화 할 것입니다.

또한 상속은 아마도 당신이 필요로하는 것이 아닐 것입니다. "IS-A"테스트를 통과 할 수 없다면 사용하지 마십시오. 상속 클래스 "has-a"고유 한 문자열 태그 (본질적으로 클래스가있는 것 같다)라면 "is-a"를 의미하지는 않는다.

그래도 하나는 다른 하나를 붙잡을 수 있습니다. 아마도 몇 가지 솔루션이있을 수 있지만 a) 전체 요구 사항 목록을 게시하지 않았으므로 추측 할 수 있습니다. B) 원하는 것은 종속성 주입입니다. :)

패턴은 일종의 것처럼 보입니다 플라이급 (구조적으로, 의도와 완벽하게 일치하지는 않지만)

그만큼 populate 설명대로, 방법은 Template 반드시 표현 된 우려를 다루는 것은 아니지만 패턴.

내가 제안한 것은 공장의 일반화입니다. create (대신에 getInstance, 이것은 당신이 기대하는 다양한 유형에 대한 방법) 방법) 방법을 의미합니다.

public static MyClass createJavaNode(String name, <differentiator>);
public static MyClass createSqlPlNode (String name, <differentiator>);
.
.
.

방법에 대한 지식 name<differentiator> 실제로 구현 선택입니다. 이상적으로는 다형성이있을 것입니다 create 그리고 차별화는 의지 할 것입니다 node 유형. 그만큼 create 메소드 리턴 MyClass, 그러나 실제로 서브 클래스를 반환하고 있습니다. 나는 제작을 강력히 고려할 것입니다 MyClass 인터페이스 또는 추상 클래스, abstract populate 메소드가 있습니다 Template).

설명에서, 그것은 실제로 하위 클래스 자체의 동작이 아니라 유형간에 다른 창조 행동 인 것으로 보이므로 MyClass 인터페이스 또는 추상 클래스에 더 강해집니다.

Ra Heinlein을 역설하기 위해, TANSTAAFL - 무료 점심과 같은 것은 없습니다. 어딘가에 다양한 유형을 만드는 방법에 대한 지식은 응용 프로그램에 존재해야합니다. 그래서 당신의 선택은 다른 답변 중 일부가 표현한 것처럼 공장 수업에 그 지식을 두는 것입니다. 무엇 구현이 생성됩니다 어떻게 그것은 만들어졌습니다. 파일 시스템을 스캔하고 수집하는 기능이있는 것 같습니다. Node그것으로부터 s. 그 코드는 다음을 알 수 있습니다 유형Node (에 대한 답 무엇) 만들어 져야합니다.

그것이 구현되는지 여부 switch 또는 더 oo 방식 (테이블 구동 파견이 좋은 시간 중 하나)은 당신에게 달려 있습니다. 이것이 유용한 것이라면 여기에서 확장 할 수 있습니다.

BTW, 핵심 동작 인 경우 MyClass 일부 서브 클래스에 대해 확장 또는 수정해야합니다. Decorator 유용 할 수 있습니다.


원래 답변 :

당신은 고려할 수 있습니다 데코레이터 또는 주형 디자인 패턴 대안으로.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top