2010-01-19 6 views
8

what is so bad about singletons싱글 톤을 대체하기 위해 프록시 패턴을 어떻게 사용할 수 있습니까?

여기에 일부 의견에 대한 응답으로 DB 데이터를 캐시하는 데 싱글 톤 대신 프록시 패턴을 사용할 수 있다고 제안되었습니다. 그러나 나는 장점을 볼 수 없으며, 실제로 싱글 톤은보다 "제어 가능"해 보입니다.

문제에 대해 자세히 설명하겠습니다. 대용량의 데이터가있는 데이터베이스가 변경되지 않으므로 읽기 전용으로 간주 될 수 있다고 가정합니다. 프록시 패턴이 싱글 톤보다이 데이터 캐시를 모델링하는 더 좋은 방법일까요?

(PS : 당신이 "그것보다 '검증'이 있기 때문에!"말을하려고하는 경우 -, 난 아직 그 개념에 익숙해하고 정교하게하십시오) 당신의 도움에 대한

감사합니다!

+3

디자인 패턴 mindmap : http://www.mindmeister.com/7008138/design-patterns – jldupont

답변

7

면책 조항 : 여기 자바 용어

싱글 말하는거야 지금은 응용 프로그램에서 데이터를 공유 할 수있는 빠르고 편리한 방법으로 최근에 많이 악용 된 대부분 때문에 안티 패턴 간주됩니다 - 다소이다 공유 리소스에 대한 액세스 제어를 제공하기에 더 적합한 디자인 패턴의 과도 확장.

프로그램 표준 출력을 고려하십시오.이 리소스의 액세스는 쓰기의 동기화를 허용하는 단일 액세스 지점에 의해 보호되어야합니다. 그 이유는 예를 들어 System.out을 java의 정적 인스턴스로 사용하는 이유입니다.

싱글 톤을 시작했을 때 싱글 톤 클래스에 대해 엄격한 가정을 많이하고 있기 때문에 자신이하는 일에 대한 자세한 정보를 알아야합니다. 시스템의 유일한 클래스. 여러분의 리소스에 대한 단일 엔트리 포인트가 될 것이라고 가정하고, 클래스가 이제 ejb 서버에 배치되었고 각각의 ejb 컨텍스트가 자신의 싱글 톤과 더 많은 싱글 톤을 갖기 때문에 그것을 사용하기 시작합니다 서버에서 다시로드 된 모든 JSP와 싱글 톤이 직렬화되고 역 직렬화 될 때마다 하나의 싱글 톤을 추가합니다 (readResolve() 메소드를 무시하는 것을 잊어 버렸기 때문에).

그래서 싱글 톤은 많은주의를 기울여 사용되어야하며, 이제 의도 된 용도에 완전히 유용함에도 불구하고 반 패턴으로 간주됩니다.

데이터베이스 캐시의 경우이 "캐시"리소스에 대한 프록시를 사용하여 각 클래스에 캐시가 필요한 경우 더 나은 방법이므로 "리소스 찾기"로직을 추가 할 수 있습니다. 논리를 캐시 싱글 톤 검색에 묶는 대신 프록시 자체를 사용하면 환경에 따라 작동하지 않을 수도 있습니다.

그래서 리소스를 공유하는 방법을 하드 코딩하고 (싱글 톤 함정을 무시하고) 동기화 목적으로 리소스를 제어하는 ​​싱글 톤을 사용하기 때문에 싱글 톤을 리소스로 사용하는 수단으로 사용하는 단어가 거의 없습니다. 완전히 받아 들일 수 있습니다.

세마포어는 항상 동일한 세마포어를 얻을 수있는 경우에만 작동합니다. 후자의 경우 문제는 세마포어에 액세스해야하는 모든 곳에서 싱글 톤에 액세스하는 것입니다. 여기서는 싱글 톤을 랩핑하고 세마포어 자체의 라이프 사이클을보다 세밀하게 제어하는 ​​데 필요한 클래스가 필요합니다.

프록시는 하나의 응용 프로그램, 클라이언트 서버 시스템, 동일한 시스템의 다른 구성 요소 등 "시스템에서 자원 제공"역할을 포함하도록 의도되었으며 érpxy를 사용하면 자원 검색 방법이 불투명합니다. 캐시 된 값의 해시 맵을 포함하는 싱글 톤을 제공하도록 할 수 있습니다. 네트워크에서 memcached 셸에 액세스하도록 할 수 있습니다. 응용 프로그램에서 호출하는 방법을 변경하지 않고도 테스트 중에 CSV를 읽을 수 있습니다.

+0

안녕하세요, 좋은 지적입니다. 내가 가진 문제는 누군가가이 캐시 된 데이터에 액세스하려고 할 때마다 DB 구성을 분석하는 것을 원하지 않는다는 것입니다. 캐시를 채우는 것도 느린 과정입니다. 이전에는 모든 요청에 ​​약 7 초가 걸렸습니다. 이제는 1보다 작습니다 (이제는 처음 만 느립니다. 그 다음부터 느리게 느껴짐). 프록시 패턴이 캐시의 위치를 ​​신경 쓰지 않아도되고 응용 프로그램 간의 종속성을 줄이는 점이 좋습니다. –

+1

물론 캐시는 시스템의 광범위한 가용성과 불투명 한 액세스 모두에서 이익을 얻는 특정 종류의 자원입니다. 이런 종류의 문제에 대해서는 입니다. 세 번째 패턴이 사용될 수 있습니다 : 디렉토리에 저장된 명명 된 서비스. 당신은 InitialContext 클래스를 사용하여 ejb와 javaEE에서이 패턴을 많이 볼 수있다. 그러나 많은 다른 종류의 컨텍스트를 가질 수있다. 긴 이야기 짧게 : 시작시 싱글 톤으로 캐시를 생성하는 응용 프로그램을 알고 알려진 이름 (rmi bind를 상상해보십시오)의 Context 에 등록한 다음이 컨텍스트에 액세스하여 캐시를 검색 할 수 있습니다 –

0

프록시 패턴이 캐시 된 데이터와 데이터로드 사이의 프록시에 사용된다고 상상할 수 있습니다 (지연로드). 의

정렬 :

class DbProxy 
{ 
    private static Data cache = null; // Sort-of Singleton 

    public static Data GetData(String query) 
    { 
    if (DbProxy.cache == null) 
    { 
     // Data = Do Stuff to read Data 
     DbProxy.cache = Data; 
    } 
    return DbProxy.cache; 
    } 
} 

이 그냥 GetData의 및 수행을 호출 할 수 있으며,이를 사용하여 코드 데이터가 이미 존재 어떠했는지를 걱정 할 필요가 없다는 장점을 가지고있다.

/* 면책 조항 : 코드가 유효하지 않은, 그냥 데모 목적으로 제 생각에는 */

+0

네,하지만 이것은 싱글 톤처럼 보입니다. 어쩌면 내 싱글 톤은 이미 프록시 일까? –

+1

저는 디자인 패턴 전문가가 아니며 CS 학위 또는 기타가 없으므로 잘못되었을 수도 있습니다. 그러나 제 지식에 따르면 그 패턴은 상당히 관련이 있습니다. 프록시 패턴은 더 많은 작업을 수행 할 수 있습니다 (즉, 캐시 된 항목을 반환하는 대신 항상 쿼리를 반복하지 않는 경우 결과를 캐시 할 수 있는지 확인). – dbemerlin

2

만을위한 의사이다, 거기에는 "하거나,"하지 않습니다. 클래스는 동시에 여러 디자인 패턴을 구현할 수 있습니다. 외부 데이터베이스에 대한 액세스를 구현하는 클래스는 어떤 경우 든 프록시 (이 경우 원격 프록시)라고합니다. 추가 기능 캐싱을 고려해 보면 Decorator이기도합니다.

그래서 진짜 질문은, 그것이 또한 싱글 톤일까요? 정확하게 하나의 외부 데이터베이스가 있다고 가정합시다. 하나의 CachingDBProxy만이 필요합니까? 나는 사용에 의존한다고 말할 수 있습니다 :

비슷한 데이터에 액세스하는 클라이언트가 여러 개인 경우 동일한 CachingDBProxy를 공유하면 분명히 이점이 있습니다. 한 클라이언트가 필요로하는 데이터는 이미 다른 클라이언트가 필요로 할 수 있으므로 값 비싼 데이터베이스 액세스를 수행하는 대신 캐시에서 검색 할 수 있습니다.

한편 일부 클라이언트는 상당히 다른 데이터에 액세스 할 수 있습니다. 따라서 CachingDBProxy가 한 그룹의 클라이언트에 의한 제한된 양의 데이터 액세스 만 캐시한다고 가정하면 다른 클라이언트 그룹이 필요로하는 데이터가 삭제되어 캐시 성능이 저하 될 수 있습니다. 이 경우 하나의 데이터베이스 만 있지만 여러 개의 CachingDBProxies를 갖는 것이 합리적 일 수 있습니다 (물론 동시 액세스가 가능하다고 가정합니다).

그래서 CachingDBProxies 수는 사용에 따라 다릅니다. CachingDBProxy는 정당한 이유없이 사용을 제한해서는 안되므로 인스턴스가 하나만 존재하도록해서는 안됩니다. 따라서이 경우 CachingDBProxies는 IMTO가 아닌 Singleton이어야합니다. 클라이언트 만 CachingDBProxies가 얼마나 많은지 알 수 있습니다.

한편 한 번에 하나의 액세스 만 처리 할 수있는 특정 리소스에 대한 프록시가있는 경우 Singleton이어야 할 수 있습니다. 그러나 그것은 위의 경우와는 다른 뚜렷한 사례입니다. 여기에서 요구 사항은 Proxy가 담당하는 영역에서 직접 발생합니다 (그 목적은 특정 리소스에 대한 액세스를 채널하는 것입니다).

+0

예, 당신의 요지를 봅니다. 당신이 대부분의 클래스의 디자인을 분석한다면, 많은 패턴을 구현하는 것으로 밝혀지며, 모두 하나의 패턴으로 매치됩니다. –

관련 문제