2017-11-20 21 views
0

에서 같은 클래스의 조성물은 내가 GitHub의에 코드 조각 다음 발견 :상속 및 Java

public class DummySSLSocketFactory extends SSLSocketFactory { 

    private static final Logger LOG = LoggerFactory.getLogger(DummySSLSocketFactory.class); 
    private SSLSocketFactory factory; 

    public DummySSLSocketFactory() { 
     try { 
      SSLContext sslContext = SSLContext.getInstance("TLS"); 
      TrustManager[] trustManagers = new TrustManager[] {new DummyTrustManager()}; 
      sslContext.init(null, trustManagers, new java.security.SecureRandom()); 
      factory = sslContext.getSocketFactory(); 
     } catch (Exception e) { 
      throw new RuntimeCamelException("Error creating DummySSLSocketFactory: " + e.getMessage(), e); 
     } 
    } 

    /** 
    * Must provide this getDefault operation for JavaMail to be able to use this factory. 
    */ 
    public static SocketFactory getDefault() { 
     LOG.warn("Camel is using DummySSLSocketFactory as SSLSocketFactory (only to be used for testing purpose)"); 
     return new DummySSLSocketFactory(); 
    } 

    public String[] getDefaultCipherSuites() { 
     return factory.getDefaultCipherSuites(); 
    } 

    public String[] getSupportedCipherSuites() { 
     return factory.getSupportedCipherSuites(); 
    } 

    public Socket createSocket(Socket socket, String host, int port, boolean autoClose) throws IOException { 
     return factory.createSocket(socket, host, port, autoClose); 
    } 

    public Socket createSocket(String host, int port) throws IOException { 
     return factory.createSocket(host, port); 
    } 

    public Socket createSocket(String host, int port, InetAddress localAddress, int localPort) 
     throws IOException { 
     return factory.createSocket(host, port, localAddress, localPort); 
    } 

    public Socket createSocket(InetAddress host, int port) throws IOException { 
     return factory.createSocket(host, port); 
    } 

    public Socket createSocket(InetAddress address, int port, InetAddress localAddress, int localPort) 
     throws IOException { 
     return factory.createSocket(address, port, localAddress, localPort); 
    } 

    public Socket createSocket() throws IOException { 
     // must have this createSocket method 
     return factory.createSocket(); 
    } 

} 

유사 구현은 널리 다른 프로젝트에서 사용된다. 나는 상속과 구성을 동시에 사용하는 목적이 무엇인지 알아 내려고 노력했다. sslContext.getSocketFactory();의 결과를 반환하는 팩토리 메서드를 사용하는 것만으로도 클래스를 확장하지 않아도 충분할 것으로 보입니다. 이 코드를 쓴 사람의 정확한 의도했지만, 수업이 조직에 분명하다 모르는

+0

액세스 가능한 생성자가있는 클래스가 필요한 리플렉션 기반 프레임 워크를 사용하고 있거나 일부 클래스에 대해 'SSLSocketFactory'의 사용자 지정 하위 클래스를 명시 적으로 만들어야하기 때문에 팩터 리 메서드를 사용할 수 없을 수도 있습니다. 이유. 또는 각 메소드에 로깅 기능을 추가하려고하지만 클래스 구현을 완료하지 않은 것일 수도 있습니다. 이 특별한 경우에는 확실하지 않습니다. –

답변

1

이 모두 조성과 상속을 사용하여 DummySSLSocketFactory 수이 의 SSLSocketFactory에서 구현 사용하는 보호 방법과 심지어 위의 클래스의 (슈퍼를 사용하여). DummySSLSocketFactory 클래스를 당신은 슈퍼를 사용 SSLSocketLayer에 도달 할 수있을 것입니다이 참조없이 DummySSLSocketFactory의 costructor

factory = sslContext.getSocketFactory(); 

에서 부모 클래스 SSLSocketFactory

private SSLSocketFactory factory; 

세트에 대한 참조를 가지고,하지만 때문에
이 가능하다 훨씬 더.

+0

매우 합리적인 것 같습니다. 이제는 한 가지 수업에서 작문과 상속을 결합하여 얻을 수있는 이점을 확인하여 답을 수락하겠습니다. – woockashek

+0

오히려 보호한다는 뜻이 아닌가요? 내가 아는 한 상속 클래스의 private 멤버/메서드에 액세스 할 수있는 방법이 없습니다. – woockashek

+0

예, 맞습니다. 답을 수정하겠습니다. 즉, 특정 구현에서 일부 메소드를 사용하기 위해 상위 클래스 인 SSLSocketFactory를 직접 가리킬 수 있다는 것을 의미했습니다. 아마도 더미가 오버라이드 된 것입니다. 회원에 관해서, 나는 틀렸고, 그렇게하는 것에 특별한 이득이 없다. – HJuls2

0

이것은 일반적인 패턴입니다 (언급 한 바와 같습니다).

하위 클래스는 "is-a"관계를 설정하기 위해 클래스를 확장 (또는 인터페이스 구현) 할 수 있습니다. 예에서 DummySSLSocketFactory은 -입니다. "is-a"관계는 다형성을 허용합니다.

자식 클래스는 메서드를 완전히 재정의하거나 (인터페이스의 경우 구현) 원치 않으므로 composition을 사용하여 재미없고 필수적인 메서드를 이미 재정의 한 내용을 얻습니다. 이렇게하려면 하위 클래스가 "재미없는"(내 용어가 있음) 메서드에 대한 호출을 구성된 구성원에게 전달합니다. 예에서 원래 클래스 SSLSocketFactoryDummySSLSocketFactory 클래스에서 흥미롭지 않은 "기본"구현을 제공합니다.

구성된 구성원에 대한 호출 전달은 프록시 패턴의 변형입니다. 기능을 변경하기 때문에 전체 프록시가 아닙니다.

+0

이 경우 나는 구성 할 필요가 없다고 생각합니다.프록시 메소드를 구현하는 대신 구현을 건너 뛸 수 있습니다. – woockashek