누구든지 플라이급 패턴을 사용하는 구체적인 예가 있습니까? [닫은]


21

나는 디자인 패턴을 연구하고 플라이 웨이트 패턴을 가로 질러왔다. 응용 프로그램에서 패턴을 사용할 기회를 보려고 노력했지만 패턴을 사용하는 방법을 보는 데 문제가 있습니다. 또한 다른 사람들의 코드를 읽을 때 플라이 웨이트 패턴이 사용되고 있다는 신호는 무엇입니까?

정의에 따르면 다음과 같이 말합니다.

많은 수의 세밀한 개체를 효율적으로 지원하려면 공유를 사용하십시오.

올바르게 읽으면 사전 및 해시 테이블이 플라이 가중치의 인스턴스가 될 수 있습니까?

미리 감사드립니다.


7
플라이 웨이트에 대한 일화 : 제 3 자 API로 큰 엑셀 파일 (최대 500k 레코드, 열 100 개 이상)을 만들어야했습니다. 셀의 스타일은 메모리를 많이 사용하게되었습니다. 따라서 스타일이 필요할 때마다 동일한 스타일이 이미 존재하는지 해시 테이블을 확인한 다음이 스타일에 대한 참조 만 제공했습니다. 이 수정으로이 내보내기가 가능해졌습니다. 이제 많은 양의 데이터가 엑셀에 있다고 생각합니다. 그러나 컨트롤러는 분석 매크로를 유지하고 싶었습니다.
팔콘

9
의견 : 패턴과 OO 책과 기사를 쓰는 사람들이 평범한 프로그래머의 현실 세계에 와서 변호사 스타일 영어 사용을 중단하기를 바랍니다!
NoChance

1
"나는 한 번 (50 만 개 기록까지 100 개 이상의 열) 큰 엑셀 파일을 만들 수 있었다"- 많은 일부 상인이 만드는 능력이 있는지에 비해 아니에요 그 ;-)
quant_dev

이 예제 중 몇 가지를 읽은 후에 메모리 데이터 압축 에서이 기술을 구현하기에 탁월한 장소라고 생각합니다. 도와 주셔서 감사합니다!
Jeremy E

GWT의 테이블 셀은 플라이 웨이트입니다.
user16764

답변:


19

한 예로 Java 라이브러리에 있습니다. Java는 기본 유형 (예 : int32 비트 정수)과 랩퍼 (예 : Integer랩핑 int)를 갖 습니다 . 이 "상자"는에 방법이 있습니다 int에은 Integer과를 언 박싱 Integerint. 래퍼는 프리미티브 유형이 객체가 아니므로 Maps의 키로 사용 하거나 s에 배치 할 수 없기 때문에 필요합니다 Collection.

복싱 방법은 -128에서 127 사이의 값에 Integer해당 하는 일종의 캐시로 flyweight 객체 배열을 사용합니다 int.이 값은 키로 사용되거나 컬렉션에 배치 될 가능성이 가장 높은 값이므로 할당 및 메모리 사용이 줄어 듭니다. ( Integer0 주위에 떠있는 값을 나타내는 5000000이 있으면 플라이급 인스턴스를 재사용하는 것보다 5000000 배 많은 메모리를 사용합니다).



1
C #에서 문자열에 대한 인턴 풀이 플라이급 패턴의 또 다른 예입니까?
Jeremy E

1
@ Jeeremy E : 예, 제 생각에는 문자열에 대한 플라이급 패턴의 응용 프로그램을 interning하는 문자열을 호출 할 수 있습니다. 문자열은 메모리 소비뿐만 아니라 런타임 효율성에 관한 것입니다.
팔콘

Objective-C 태그가 지정된 포인터는이를 극한까지 끌어 올립니다. 최대 56 비트의 박스형 정수와 최대 6 자의 문자열은 객체로 할당되지 않지만 모든 정보는 객체 포인터 자체에 포함됩니다.
gnasher729

9

제도법. 일반적으로 래스터 이미지 (대부분의 소비자 수준 컴퓨터 그래픽의 중추)는 CPU를 많이 사용하지만 메모리 비용이 많이 듭니다 (메모리가 저렴하지만 CPU가 비싸기 때문에 괜찮습니다). 더 큰 UI (Windows GUI 앱의 아이콘에서 워드 프로세서의 글꼴 문자, 3D 게임의 표면 질감에 이르기까지)를 렌더링 할 때 해당 래스터 이미지를 여러 번 반복해야하는 경우에는 이치에 맞습니다. 이미지를 메모리에 한 번로드 한 다음 저렴하고 자체적으로 많은 메모리를 차지하지 않는 매우 간단한 객체를 사용하여 이미지를 가리 킵니다. 이미지가 표시되어야하는 그래픽 공간의 한 지점 인 스프라이트는 3D 포인트 일 뿐이며 사용할 이미지의 첫 번째 픽셀에 대한 메모리 포인터입니다. 스프라이트 이미지 파일 부분의 크기를 포함 할 수도 있습니다. 그래픽 또는 메모리 용어로. 이 정보는 스프라이트의 이미지 또는 위치를 변경하는 등 변경하기에 매우 저렴하며 매번 새 이미지를로드하지 않고도 수행 할 수 있으므로 기본 프로그램의 적절한 부분을 조작하고 표시하는 기본 프로그램의 성능이 크게 향상됩니다. 완전한 UI "장면"을 렌더링하기위한 적절한 이미지.


3

Character스몰 토크의 ASCII 범위 인스턴스는 플라이 웨이트입니다.

때이 같은 평가 Character space, Character class >> #value:이 실행을 :

value: anInteger 
    "Answer the Character whose value is anInteger."

    anInteger > 255 ifTrue: [^self basicNew setValue: anInteger].
    ^ CharacterTable at: anInteger + 1.

클래스 변수 CharacterTable는 다음과 같이 초기화됩니다.

initialize
    "Create the table of unique Characters, and DigitsValues."
    "Character initializeClassificationTable"

    CharacterTable ifNil: [
        "Initialize only once to ensure that byte characters are unique"
        CharacterTable := Array new: 256.
        1 to: 256 do: [:i | CharacterTable
            at: i
            put: (self basicNew setValue: i - 1)]].
    self initializeDigitValues

따라서 문자열을 만들 때 ASCII 범위 CharacterCharacterTable매번 새로 작성되지 않고 발생합니다.


3

플라이급 패턴을 사용하는 목적은 불필요한 객체 초기화를 피하여 공간을 절약하는 것입니다. GOF 에 의해 정의 된 것처럼 객체는 내재 상태와 외재 상태의 두 가지 상태를 가질 수 있습니다.

  • 고유 상태 : 플라이급에 저장됩니다. 플라이급 상황과 독립적 인 정보로 구성되어 공유 할 수 있습니다.
  • 외부 상태 : 플라이급의 상황에 따라 달라 지므로 공유 할 수 없습니다. 클라이언트 객체는 외부 상태를 필요할 때 플라이급으로 전달합니다.

각 열에 모든 텍스트 행이 포함되고 행에 문자가 포함될 수있는 간단한 텍스트 편집기 응용 프로그램을 개발한다고 가정합니다.

여기서 딜레마는 Character 클래스를 디자인하는 방법입니다. char c문자 클래스 내에서 메인 (고유 상태) 객체이어야한다. 그러나 문자는 글꼴 및 크기 (외부 상태)를 가질 수 있습니다. 따라서 외부 상태를 Row (클라이언트)에 저장하고 필요할 때 액세스해야합니다. 이를 위해 글꼴과 크기를 저장하는 두 개의 목록이 작성됩니다.

Flyweight 패턴을 따라 문자를 재사용 할 수 있으며 모든 ASCII 기호 ( Character개체) 를 포함하는 특정 개체 목록 (flyweight pool)에서 개체를 참조하고 있습니다.

다음은 시각적으로 설명한 내용입니다.

여기에 이미지 설명을 입력하십시오

'hello'를 인쇄 Character하려면 5 대신 4 개의 개체 만 필요합니다. 글꼴이 변경되면 새 개체가 필요하지 않습니다. 이 점에 유의 하지 않을 것이다 가능한 우리는, 예를 들어, 문자 클래스의 외부 상태를 저장했다

class Character
{
    char c;
    int Size;
    Font font;

    ....
}

큰 데이터 세트에이 패턴을 적용 하면 응용 프로그램의 메모리 복잡성과 개체 재사용 성 이 크게 최적화 됩니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.