2011-01-27 4 views
0

질문 : 개발자가 자신의 serialize 형식을 만드는 것이 얼마나 일반적입니까? 특히, 자바를 사용하여 본질적으로 변수를 구분하는 토큰이있는 거대한 문자열로 개체를 보냅니다.개체 보내기/직렬화 모범 사례

My Logic : 언어 의존성 (Java의 수정 된 UTF-8 무시)이 거의 없으며 객체 버전 문제가 없기 때문에 이것을 선택했습니다. Java의 직렬화를 사용하는 경우 정확한 수신자가 있어야합니다. 이전 버전에서 실행중인 클라이언트가 오브젝트 데이터를 수신 할 수 없도록 오브젝트의 동일한 버전. 코드가 너무 추한 아니지만 괜찮아,하지만 내 질문에이 인스턴스에 대한 모범 사례 무엇입니까? 이것은 개인 프로젝트를위한 것입니다.

기타 알려진 선택 사항 : 알았습니다. 객체를 네트워크를 통해 전송하기 위해 일련 번호를 지정하고 googles 프로토콜 버퍼를 발견했습니다. 객체를 직렬화하는 것이 얼마나 표준화되어 있습니까? 근본적으로 세 가지 방법으로 나왔습니다. (내가 자바에 관해서 이야기 할 것이다.) 1) 언어의 (자바의) 네이티브 직렬화 클래스를 사용한다. 2) 문자열과 토큰을 사용하여 객체를 직렬화하는 자신 만의 방법을 사용한다. 3) 프로토콜 버퍼를 사용한다. 1) 속도/효율성/크기 2) 언어 독립 3) 버전의 수용 : 난 당신이 기본적으로 직렬화 할 때 달성하기 위해 3 개 주요 목표를 가지고 수집 한 것과는 다른 알려진 형식 (JSON, XML 등)

(코드의 구버전은 여전히 ​​새로운 버전의 부분을 받아 들일 수 있습니다. &)

대부분의 대형 소프트웨어 프로젝트는 프로토콜 버퍼를 사용합니까? 클라이언트가 리소스가 훨씬 적은 모바일 장치 인 경우 변경됩니까?

+1

그래프를 처리합니까? – bestsss

+0

아니요, 개체는 일반적으로 연락처 정보 (이름, #, 주소)와 같이 매우 작습니다. 문자열을 사용하여 내 "직렬화 된"형식을 작성하여 알 수 있습니다. 이름/전화 번호와 같은 개체의 일부만 요청/보낼 수 있으므로 200-300 개의 연락처를 요청할 때 매우 빠릅니다. –

+1

목표를 잊지 마세요. 4) 데이터를 망가 뜨리지 마십시오. 분명히 알고 있지만 구분 문자로 문자 인코딩을 작성하는 것은 고전적인 문제 (예 : 데이터에 포함 된 구분 기호, 기타 이상한 문자 등)가 있습니다. – jtahlborn

답변

5

표준 형식 (JSON, XML 또는 심지어 프로토 버퍼)을 사용하는 경우 통합 지점을 통해 앱을 확장 할 수있는 기회가 훨씬 더 많습니다. 그러나 그것이 내부 일 뿐이라면 쉬운 일을하십시오. 개인적으로, 나는 주어진 객체의 직렬화 된 형태를 나타내는 전용 영속 프록시 클래스를 만든다. 그런 다음 writeReplace 및 readResolve를 사용하여 어떤 방법이든 가장 적합한 방법 (예 : 실시간 라이브 전송의 Java 직렬화, 장기 지속성의 경우 xml)을 사용하여 해당 객체를 직렬화합니다. 클래스가 발전함에 따라, 영구 프록시의 완전히 새로운 구현을 생성하고, 프록시에 버전 관리를 추가하는 등의 작업을 적절하게 수행 할 수 있습니다. 나는 Bloch이 Effective Java에서이 패턴을 설명한다고 믿는다.

순수 스크래치 와이어 프로토콜을 고안하는 경우 성능이 앱에 얼마나 중요한지에 따라 달라집니다. 대부분의 경우와 마찬가지로 표준 라이브러리/프로토콜을 활용하면할수록 새로운 코드를 빠르게 얻을 수 있습니다. 내가 직렬화하는 것과 관련된 막대한 양의 코드를 볼 때/나는 보통 코드의 냄새라고 생각하고 그것이 정당화되었는지 여부에 매우주의를 기울인다. 단지 $ 0.02.

그리고 PS - 누군가가 그래프에 대해 질문을 올렸습니다 ... 이것은 실제로 표준 직렬화를 의도적으로 피한 한 영역입니다. 복잡한 그래프를 직렬화하는 자바의 능력은 그리 좋지 않습니다. 그래프가 원격으로 복잡하다면 스택 오버 플로우 문제 (hah)로 끝날 것입니다. 이러한 경우 영구 프록시가 매우 중요합니다. 바로 내 마음에 봄

+0

@ 케빈의 날 - 문제는 복잡한 그래프가 아닌 * 깊은 그래프 일 것입니다. 이론적으로 이는 일반적인 경우에 직렬화가 느려질 가능성이 있지만 Sun/Oracle에서 해결할 수 있습니다. (재귀 트리 워크를 방문 할 큐 또는 스택을 사용하는 것으로 바꾸십시오.) –

+0

@Stephen - 동의. 이 분야의 교훈 : 그래프의 직렬화는 5 단계 이하의 그래프로 실패했습니다. 분명히 직렬화 알고리즘은 그래프를 정확히 잘못된 방향으로 이동하기로 결정했습니다. 깊이가 문제는 절대적으로 옳지 만 직렬화 알고리즘이 통과하는 깊이는 종종 그래프의 객체 계층 구조를 시각적으로 검사하여 예상하는 깊이와 다를 수 있습니다. –

+0

@ 케빈의 날 - 사실, 노드에 대한 여러 경로가있는 그래프의 경우 트리의 깊이/높이를 측정하는 방법이 하나 이상 있습니다. –

2

몇 가지 :

  • 는 모든 메시지 또는 연결 협상에 두 버전 번호를 포함합니다. 엄청 두통에서 벗어날 수 있습니다. 수신기가 지원하는 버전을 보낸 사람에게 알려주는 것이 바람직합니다.

  • 자연스럽게 이진 데이터 (이미지, 사운드)를 보내지 않는 한 읽을 수있는 일반 텍스트 (UTF-8) 형식을 사용하십시오.많은 문제를 해결하는 데 도움이됩니다. 나는 JSON을 고수 할 것이지만 그것은 당신에게 최적이 아닐 수도있다. XML에는 높은 오버 헤드가 있습니다.

  • 메시지가 길면 gzip (GZIPOutputStream)과 같은 잘 알려진 알고리즘으로 메시지를 압축 할 수 있습니다.

이 단계는 알 수 있듯이 서버와 가능한 클라이언트 간의 형식 개방성 및 느슨한 결합을 촉진합니다. 미래에 고객이 사용해야 할 기술은 무엇인지 아무도 모릅니다 : iPhone 클라이언트를 만드는 데 관심이 있습니까? HTML5 + JS 클라이언트? 서버용 유사도 :

+0

JSON은 모든 거래의 잭입니다. y, 그것을 좋아하지 않아. XML은 장황하지만 DTD/XSD를 통해 확인할 수 있으며 실제로 잘 정의 된 규칙을 사용하여 공개 API 프로토콜로 사용할 수 있습니다. 메시지/serializarion 당 gzip을 사용하면 좋은 성능과 압축 수준을 얻을 수 없습니다. 메시지 기반에서 압축을 구현하면 Z_SYNC_FLUSH로 플러시해야합니다 (일부 매우 이상한 이유는 java.util.zip에서 지원하지 않기 때문에 jzlib가 지원합니다). – bestsss

5

질문 : 개발자가 고유 한 직렬화 형식을 만드는 것이 얼마나 일반적입니까?

처음부터 생성한다고 가정하면 "매우 드문 경우"입니다.

또한 일반적으로 이렇게하는 것이 "우수 사례"가 아니라고 말하고 싶습니다. 대부분의 경우 기존에 일반적으로 사용되는 대안 중 하나 (Java 직렬화, JSON, XML 등)가 좋은 해결책을 제공합니다.

IMO의 경우 명확한 요구 사항이 있거나 기존의 대체물 이 제공하지 않는 경우에만 "자체적 인 롤링"형식 (해당 직렬/직렬화 코드 구현)을 고려해야합니다. 일. "XYZ가 느리다"는 민중의 지혜는 충분한 증거가 아닙니다.

0

구조화 된 데이터 XML의 경우 JSon이 최상의 선택입니다. 그러나 간단한 평면 레코드의 경우 CSV를 고려하는 것이 좋습니다. 더 간단하게/빨리 구현할 수 있습니다. 레코드 수가 매우 많으면 관리하기가 쉽습니다. 예 : 스프레드 시트에로드하십시오.