首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >问答首页 >是否有以不同格式序列化和反序列化对象层次结构的模式?

是否有以不同格式序列化和反序列化对象层次结构的模式?
EN

Stack Overflow用户
提问于 2011-07-18 05:05:20
回答 3查看 3.3K关注 0票数 6

给定一个复杂的对象层次结构(幸运地不包含循环引用),我如何实现支持各种格式的序列化?我不是来讨论实际实施的。相反,我正在寻找可能派上用场的设计模式的提示。

更确切地说:我使用Ruby,我希望解析XML和JSON数据来构建一个复杂的对象层次结构。此外,应该可以将这个层次结构序列化为JSON、XML,可能还有HTML。

为此,我可以使用Builder模式吗?在上述任何一种情况下,我都有某种结构化数据--无论是在内存中还是在文本中--我想用这些数据来构建其他的东西。

我认为最好将序列化逻辑与实际业务逻辑分开,这样以后我就可以轻松地支持多种XML格式。

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2011-07-18 09:07:43

最后,我创建了一个基于Builder和策略模式的解决方案。我使用Builder模式提取解析,并将逻辑构建到自己的类中。这允许我分别轻松地添加新的解析器和构建器。我使用策略模式来实现单独的解析和构建逻辑,因为这个逻辑取决于我的输入和输出格式。

下图显示了我的解决方案的UML图。

下面的清单显示了我的Ruby实现。实现有点琐碎,因为我正在构建的对象相当简单。对于那些认为这段代码臃肿和Java-ish的人来说,我认为这实际上是一个很好的设计。我承认,在这种微不足道的情况下,我可以直接将构建方法构建到我的业务对象中。然而,我并不是在我的其他应用程序中构建成果,而是相当复杂的对象,因此分离解析、构建和业务逻辑似乎是个好主意。

代码语言:javascript
运行
AI代码解释
复制
require 'nokogiri'
require 'json'

class Fruit

  attr_accessor :name
  attr_accessor :size
  attr_accessor :color

  def initialize(attrs = {})
    self.name = attrs[:name]
    self.size = attrs[:size]
    self.color = attrs[:color]
  end

  def to_s
    "#{size} #{color} #{name}"
  end

end

class FruitBuilder

  def self.build(opts = {}, &block)
    builder = new(opts)
    builder.instance_eval(&block)
    builder.result
  end

  def self.delegate(method, target)
    method = method.to_sym
    target = target.to_sym

    define_method(method) do |*attrs, &block|
      send(target).send(method, *attrs, &block)
    end
  end

end

class FruitObjectBuilder < FruitBuilder

  attr_reader :fruit

  delegate :name=,  :fruit
  delegate :size=,  :fruit
  delegate :color=, :fruit

  def initialize(opts = {})
    @fruit = Fruit.new
  end

  def result
    @fruit
  end

end

class FruitXMLBuilder < FruitBuilder

  attr_reader :document

  def initialize(opts = {})
    @document = Nokogiri::XML::Document.new
  end

  def name=(name)
    add_text_node(root, 'name', name)
  end

  def size=(size)
    add_text_node(root, 'size', size)
  end

  def color=(color)
    add_text_node(root, 'color', color)
  end

  def result
    document.to_s
  end

  private

  def add_text_node(parent, name, content)
    text = Nokogiri::XML::Text.new(content, document)
    element = Nokogiri::XML::Element.new(name, document)

    element.add_child(text)
    parent.add_child(element)
  end

  def root
    document.root ||= create_root
  end

  def create_root
    document.add_child(Nokogiri::XML::Element.new('fruit', document))
  end

end

class FruitJSONBuilder < FruitBuilder

  attr_reader :fruit

  def initialize(opts = {})
    @fruit = Struct.new(:name, :size, :color).new
  end

  delegate :name=,  :fruit
  delegate :size=,  :fruit
  delegate :color=, :fruit

  def result
    Hash[*fruit.members.zip(fruit.values).flatten].to_json
  end

end

class FruitParser

  attr_reader :builder

  def initialize(builder)
    @builder = builder
  end

  def build(*attrs, &block)
    builder.build(*attrs, &block)
  end

end

class FruitObjectParser < FruitParser

  def parse(other_fruit)
    build do |fruit|
      fruit.name  = other_fruit.name
      fruit.size  = other_fruit.size
      fruit.color = other_fruit.color
    end
  end

end

class FruitXMLParser < FruitParser

  def parse(xml)
    document = Nokogiri::XML(xml)

    build do |fruit|
      fruit.name  = document.xpath('/fruit/name').first.text.strip
      fruit.size  = document.xpath('/fruit/size').first.text.strip
      fruit.color = document.xpath('/fruit/color').first.text.strip
    end
  end

end

class FruitJSONParser < FruitParser

  def parse(json)
    attrs = JSON.parse(json)

    build do |fruit|
      fruit.name  = attrs['name']
      fruit.size  = attrs['size']
      fruit.color = attrs['color']
    end
  end

end

# -- Main program ----------------------------------------------------------

p = FruitJSONParser.new(FruitXMLBuilder)
puts p.parse('{"name":"Apple","size":"Big","color":"Red"}')

p = FruitXMLParser.new(FruitObjectBuilder)
puts p.parse('<fruit><name>Apple</name><size>Big</size><color>Red</color></fruit>')

p = FruitObjectParser.new(FruitJSONBuilder)
puts p.parse(Fruit.new(:name => 'Apple', :color => 'Red', :size => 'Big'))
票数 11
EN

Stack Overflow用户

发布于 2011-07-18 06:09:12

每当有人说他们想使用不同的算法进行相同的操作,并选择在运行时使用哪种算法时,战略模式总是浮现在脑海中。不同类型的序列化(XML、JSON、二进制等等)都是将对象转换为纯数据、更可移植的结构的不同策略。这似乎适用于你的情况。

票数 1
EN

Stack Overflow用户

发布于 2011-07-18 11:48:19

看看面向模式的软件体系结构,反射模式;我认为它应该给出一些关于如何实现这样一个结构的好提示。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/6733317

复制
相关文章
对象的序列化和反序列化
package com.serialize.utils; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; /**  * 序列化工具类  */ public class SerializeUtil {  
用户1220053
2018/02/09
8660
Java对象的序列化和反序列化
Java 对象的序列化和反序列化是一种将对象转换成字节流并存储在硬盘或网络中,以及从字节流中重新加载对象的操作。Java 的序列化和反序列化提供了一种方便的方式,使得可以将对象在不同的应用程序之间进行交互。
阿珍
2023/04/18
1.4K0
将对象序列化和反序列化
对象在java中是以堆的方式存储。有时候需要复制对象或者存储对象,而不是对象的引用,这时候就需要用的对象的序列化和反序列化。 1.序列化 Java序列化是指把Java对象转换为字节序列的过程;而Java反序列化是指把字节序列恢复为Java对象的过程。 很详细的博客Java中的序列化Serialable高级详解。 简单的来说大概有几点注意事项: 对象要实现了Serializable 接口 如果序列化和反序列化的serialVersionUID不同则反序列化失败,因为java是通过这个来进行序列化验证的。因此
Ryan-Miao
2018/03/13
1.1K0
Java 对象序列化和反序列化
     之前的文章中我们介绍过有关字节流字符流的使用,当时我们对于将一个对象输出到流中的操作,使用DataOutputStream流将该对象中的每个属性值逐个输出到流中,读出时相反。在我们看来这种行
Single
2018/01/04
9720
PHP中对象的序列化和反序列化
serialize() 可处理除了 resource 之外的任何类型。甚至可以 serialize() 那些包含了指向其自身引用的数组。
宣言言言
2019/12/18
1.4K0
Java对象的序列化和反序列化 转
把对象转换为字节序列的过程称为对象的序列化。 把字节序列恢复为对象的过程称为对象的反序列化。   对象的序列化主要有两种用途:   1) 把对象的字节序列永久地保存到硬盘上,通常存放在一个文件中;   2) 在网络上传送对象的字节序列。
wuweixiang
2018/08/14
7230
Java对象的序列化(Serialization)和反序列化详解
####1.序列化和反序列化 序列化(Serialization)是将对象的状态信息转化为可以存储或者传输的形式的过程,一般将一个对象存储到一个储存媒介,例如档案或记忆体缓冲等,在网络传输过程中,可以是字节或者XML等格式;而字节或者XML格式的可以还原成完全相等的对象,这个相反的过程又称为反序列化;
全栈程序员站长
2022/07/04
7570
Java对象的序列化和反序列化是什么?
Java对象的序列化和反序列化是Java中常用的一种数据持久化方式。简单地说,序列化是将一个Java对象转换为字节流的过程,而反序列化则是将字节流转换回Java对象的过程。 Java对象序列化的主要目的是将对象转换为字节流,以便在网络上传输或将对象持久化到本地磁盘上。当一个Java对象被序列化后,它的所有属性和成员变量的值都被转换成字节流,并可以通过网络或者存储到本地磁盘上。由于Java对象序列化后可以被传输和存储,因此它在分布式系统和网络编程中扮演着非常重要的角色。
用户1289394
2023/08/22
2390
Java对象的序列化和反序列化是什么?
Java对象的序列化和反序列化源码阅读
前言 序列化和反序列化看起来用的不多,但用起来就很关键,因为稍一不注意就会出现问题。序列化的应用场景在哪里?当然是数据存储和传输。比如缓存,需要将对象复刻到硬盘存储,即使断电也可以重新反序列化恢复。下面简单理解序列化的用法以及注意事项。 如何序列化 Java中想要序列化一个对象,必须实现Serializable接口。然后就可以持久化和反序列化了。下面是一个简单用法。 项目测试代码: https://github.com/Ryan-Miao/someTest/blob/master/src/main/jav
Ryan-Miao
2018/03/14
1.2K0
对象的序列化与反序列化
对象的序列化就是将Object转换成byte序列,反之叫做对象的反序列化 1.序列化流: ObjectOutputStream,是过滤流----->writeObject 反序列化流: ObjectInputStream ------->readObject 2.序列化接口: Serializable 对象必须实现序列化接口,才能进行序列化,否则将会出现异常 这个接口没有任何方法,只是一个标准 3.一个类实现了序列化接口,子类也就都能进行序列化了 java.io 接口 Serializable publ
拾点阳光
2018/05/11
1.1K0
对象序列化与反序列化
对象的序列化,反序列化 对象序列化,就是将Object转换成byte序列,反之叫对象的反序列化 序列化流(ObjectOutputStream),是过滤流—-writeObject 反序列化流(ObjectInputStream)—readObject 序列化接口(Serializable) 对象必须实现序列化接口 ,才能进行序列化,否则将出现异常 这个接口,没有任何方法,只是一个标准 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17public static void
待你如初见
2018/08/01
8440
SpringMVC+GSON 对象序列化--日期格式的处理
Gson异常强大因此使用它代替了Jackson作为SpringMVC消息转换器。 在自己的项目中,发现对象在序列化后,日期格式出现了问题。 先看问题 在员工表中有一列是生日,字段类型为Date,也就是
用户2193479
2018/06/28
2.5K0
JavaScript 学习-6.对象(object)的序列化和反序列化
当我们需要向后端传json字符串的时候,需将JavaScript的对象转成json格式,这个过程就是序列化。
上海-悠悠
2022/05/17
2.3K0
JavaScript 学习-6.对象(object)的序列化和反序列化
对象序列化与反序列化 原
第一步:定义对象 @SuppressWarnings("serial") class Person implements Serializable{ //实现Serializable接口 private String name; private Integer age; private Double height; public Person() { super(); } public Person(String name, Integer age, Double height) {
南郭先生
2018/08/14
5700
面向对象--序列化与反序列化
内存中的数据对象只有转换成二进制才可以进行数据持久化和网络传输。将数据对象转换成二进制的流程称之为对象的序列化(Serialization)。
田维常
2019/08/05
1.4K0
面向对象--序列化与反序列化
再谈Silverlight中的对象序列化/反序列化
曾经发过一篇如何在Silveright中利用XmlSerializer序列化对象的文章“Silverlight中的序列化”,限于当时的认识有限,一度以为silverlight只有这一种办法,今天意外发现,其实还有更好的方式,特此做一个汇总与比较 1.json序列化方式 silverlight支持json字符串已是众人皆知的事情,没啥好说的,有点容易让人误导的是:我们在vs的silverlight项目中添加引用时,一眼就能看到System.Runtime.Serialization.Json这个命名空间,于是
菩提树下的杨过
2018/01/22
1.1K0
再谈Silverlight中的对象序列化/反序列化
NSCopying和NSCoding对象序列化反序列化基础详解你要知道的NSCopying、NSCoding协议及对象序列化和反序列化都在这里
你要知道的NSCopying、NSCoding协议及对象序列化和反序列化都在这里 转载请注明出处 https://cloud.tencent.com/developer/user/1605429 本篇文章主要讲解NSCopying协议,以及NSCoding协议实现对象的序列化和反序列化,实际开发中如果要自己造轮子这两个协议还是比较重要的。 NSCopying协议 Foundation框架中为我们提供的基础的类基本都实现了NSCopying协议,因此,我们可以使用copy方法用来获取对象的一个不可变副本对象,
WWWWDotPNG
2018/04/10
1.5K0
Java 对象序列化与反序列化
所谓的对象序列化就是将 保存在内存中的对象数据转换为二进制数据流进行传输的操作 ;但不是所有对象都可以进行序列化,要被序列化的的对象那么其所在的类一定要实现 java.io.Serializable 接口,该接口并没有认识的操作方法,因为该接口是一个 标识接口 。
Mirror王宇阳
2020/11/13
4830
[javaSE] 练习队列线程和对象序列化
主要练习了队列数据结构,对象序列化和反序列化,多线程操作 import java.io.BufferedReader; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.InputStream; import java.io.InputStreamReader; import java.io.ObjectInputStream; import java.io
唯一Chat
2019/09/10
4480
[javaSE] 练习队列线程和对象序列化
点击加载更多

相似问题

获取SnakeYAML以正确序列化对象层次结构

13

Json对象(反)序列化。具有类层次结构的类型化语言

13

序列化java中对象的层次结构。

24

将Python类层次结构的对象序列化为现有的JSON模式

117

JSON序列化和反序列化是否是复制层次结构的合适方法?

14
添加站长 进交流群

领取专属 10元无门槛券

AI混元助手 在线答疑

扫码加入开发者社群
关注 腾讯云开发者公众号

洞察 腾讯核心技术

剖析业界实践案例

扫码关注腾讯云开发者公众号
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档