读者容错模式(Tolerant Reader Pattern)
来源:互联网 发布:淘宝订单能隐藏吗 编辑:程序博客网 时间:2024/06/04 20:02
读者容错模式是当从一个数据模型中读取数据的时候,无论这个数据模型如何变换,尽最大可能读取自己需要的数据,达到读取数据健壮性的要求。例如我们有一个数据模型类:RainbowFish,表示一种鱼。有一个读写数据的类:RainbowFishSerializer,来获取RainbowFish的name、age、lengthMeters、weightTons等数据。但是RainbowFish是第三方提供,可能在迭代升级的时候改变了类结构,例如增加了子类:RainbowFishV2,记录了更加详细的信息。数据结构发生了变化,我们在读取的时候就要进行适配,避免由于改变导致的crash。
代码:
/** * * RainbowFish is the initial schema * */public class RainbowFish implements Serializable { private static final long serialVersionUID = 1L; private String name; private int age; private int lengthMeters; private int weightTons; /** * Constructor */ public RainbowFish(String name, int age, int lengthMeters, int weightTons) { this.name = name; this.age = age; this.lengthMeters = lengthMeters; this.weightTons = weightTons; } public String getName() { return name; } public int getAge() { return age; } public int getLengthMeters() { return lengthMeters; } public int getWeightTons() { return weightTons; }}
/** * * RainbowFishV2 is the evolved schema * */public class RainbowFishV2 extends RainbowFish { private static final long serialVersionUID = 1L; private boolean sleeping; private boolean hungry; private boolean angry; public RainbowFishV2(String name, int age, int lengthMeters, int weightTons) { super(name, age, lengthMeters, weightTons); } /** * Constructor */ public RainbowFishV2(String name, int age, int lengthMeters, int weightTons, boolean sleeping, boolean hungry, boolean angry) { this(name, age, lengthMeters, weightTons); this.sleeping = sleeping; this.hungry = hungry; this.angry = angry; } public boolean getSleeping() { return sleeping; } public boolean getHungry() { return hungry; } public boolean getAngry() { return angry; }}
/** * * RainbowFishSerializer provides methods for reading and writing {@link RainbowFish} objects to * file. Tolerant Reader pattern is implemented here by serializing maps instead of * {@link RainbowFish} objects. This way the reader does not break even though new properties are * added to the schema. * */public final class RainbowFishSerializer { private RainbowFishSerializer() { } /** * Write V1 RainbowFish to file */ public static void writeV1(RainbowFish rainbowFish, String filename) throws IOException { Map<String, String> map = new HashMap<>(); map.put("name", rainbowFish.getName()); map.put("age", String.format("%d", rainbowFish.getAge())); map.put("lengthMeters", String.format("%d", rainbowFish.getLengthMeters())); map.put("weightTons", String.format("%d", rainbowFish.getWeightTons())); try (FileOutputStream fileOut = new FileOutputStream(filename); ObjectOutputStream objOut = new ObjectOutputStream(fileOut)) { objOut.writeObject(map); } } /** * Write V2 RainbowFish to file */ public static void writeV2(RainbowFishV2 rainbowFish, String filename) throws IOException { Map<String, String> map = new HashMap<>(); map.put("name", rainbowFish.getName()); map.put("age", String.format("%d", rainbowFish.getAge())); map.put("lengthMeters", String.format("%d", rainbowFish.getLengthMeters())); map.put("weightTons", String.format("%d", rainbowFish.getWeightTons())); map.put("angry", Boolean.toString(rainbowFish.getAngry())); map.put("hungry", Boolean.toString(rainbowFish.getHungry())); map.put("sleeping", Boolean.toString(rainbowFish.getSleeping())); try (FileOutputStream fileOut = new FileOutputStream(filename); ObjectOutputStream objOut = new ObjectOutputStream(fileOut)) { objOut.writeObject(map); } } /** * Read V1 RainbowFish from file */ public static RainbowFish readV1(String filename) throws IOException, ClassNotFoundException { Map<String, String> map = null; try (FileInputStream fileIn = new FileInputStream(filename); ObjectInputStream objIn = new ObjectInputStream(fileIn)) { map = (Map<String, String>) objIn.readObject(); } return new RainbowFish(map.get("name"), Integer.parseInt(map.get("age")), Integer.parseInt(map.get("lengthMeters")), Integer.parseInt(map.get("weightTons"))); }}
/** * * Tolerant Reader is an integration pattern that helps creating robust communication systems. The * idea is to be as tolerant as possible when reading data from another service. This way, when the * communication schema changes, the readers must not break. * <p> * In this example we use Java serialization to write representations of {@link RainbowFish} objects * to file. {@link RainbowFish} is the initial version which we can easily read and write using * {@link RainbowFishSerializer} methods. {@link RainbowFish} then evolves to {@link RainbowFishV2} * and we again write it to file with a method designed to do just that. However, the reader client * does not know about the new format and still reads with the method designed for V1 schema. * Fortunately the reading method has been designed with the Tolerant Reader pattern and does not * break even though {@link RainbowFishV2} has new fields that are serialized. * */public class App { private static final Logger LOGGER = LoggerFactory.getLogger(App.class); /** * Program entry point */ public static void main(String[] args) throws IOException, ClassNotFoundException { // Write V1 RainbowFish fishV1 = new RainbowFish("Zed", 10, 11, 12); LOGGER.info("fishV1 name={} age={} length={} weight={}", fishV1.getName(), fishV1.getAge(), fishV1.getLengthMeters(), fishV1.getWeightTons()); RainbowFishSerializer.writeV1(fishV1, "fish1.out"); // Read V1 RainbowFish deserializedFishV1 = RainbowFishSerializer.readV1("fish1.out"); LOGGER.info("deserializedFishV1 name={} age={} length={} weight={}", deserializedFishV1.getName(), deserializedFishV1.getAge(), deserializedFishV1.getLengthMeters(), deserializedFishV1.getWeightTons()); // Write V2 RainbowFishV2 fishV2 = new RainbowFishV2("Scar", 5, 12, 15, true, true, true); LOGGER.info( "fishV2 name={} age={} length={} weight={} sleeping={} hungry={} angry={}", fishV2.getName(), fishV2.getAge(), fishV2.getLengthMeters(), fishV2.getWeightTons(), fishV2.getHungry(), fishV2.getAngry(), fishV2.getSleeping()); RainbowFishSerializer.writeV2(fishV2, "fish2.out"); // Read V2 with V1 method RainbowFish deserializedFishV2 = RainbowFishSerializer.readV1("fish2.out"); LOGGER.info("deserializedFishV2 name={} age={} length={} weight={}", deserializedFishV2.getName(), deserializedFishV2.getAge(), deserializedFishV2.getLengthMeters(), deserializedFishV2.getWeightTons()); }}
阅读全文
1 0
- 读者容错模式(Tolerant Reader Pattern)
- #并行优化# 容错算法 (Fault Tolerant)
- 读者-写者问题(Reader-Writer Problem)
- Reader-Writer Pattern
- (1)前言——(12)读者反馈(Reader feedback)
- 操作系统实验,IPC(2): reader and writer, 读者和写者问题
- dubbo的容错模式
- 服务容错模式
- 服务容错模式
- dubbo集群容错模式
- 适配器模式(Adapter Pattern)、外观模式(Facade Pattern)
- 观察者模式(Observer Pattern)
- 组合模式(Composite Pattern)
- 原型模式(Prototype Pattern)
- 原型模式(Prototype Pattern)
- 装饰模式(Decorator Pattern)
- 设计模式(Design Pattern)
- 原型模式(Prototype Pattern)
- 华为编程题-加密解密
- 【动态】雷电网络预览:以太坊扩容解决方案发布开发者演示
- 【警告】SEC首席会计师警告ICO参与者不可对财务报表掉以轻心
- 基于Maven + SSM (Spring、SpringMVC、Mybatis)构建一个简单的
- Java 编程思想(四)动态代理
- 读者容错模式(Tolerant Reader Pattern)
- 把php卸载干净~
- Struts2环境搭建
- 【动态】Corda 1.0:R3确定生产用分布式分类账本技术推出预定日期
- 《财新网》:“比特币中国”宣布将停止所有交易业务
- Android中WebView使用4,java调js方法
- RTMPdump(libRTMP) 源代码分析 3: AMF编码
- C# 之泛型详解
- javax.imageio.IIOException: Can't create output stream!tomcat 验证码,图片(原理)