设计模式之抽象工厂模式:Hadoop序列化框架

参考:



http://www.w3cschool.cc/design-pattern/abstract-factory-pattern.html,《hadoop技术内幕》

介绍

意图:提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类。

主要解决:主要解决接口选择的问题。

何时使用:系统的产品有多于一个的产品族,而系统只消费其中某一族的产品。

如何解决:在一个产品族里面,定义多个产品。

关键代码:在一个工厂里聚合多个同类产品。

应用实例:工作了,为了参加一些聚会,肯定有两套或多套衣服吧,比如说有商务装(成套,一系列具体产品)、时尚装(成套,一系列具体产品),甚至对于一个家庭来说,可能有商务女装、商务男装、时尚女装、时尚男装,这些也都是成套的,即一系列具体产品。假设一种情况(现实中是不存在的,要不然,没法进入共产主义了,但有利于说明抽象工厂模式),在您的家中,某一个衣柜(具体工厂)只能存放某一种这样的衣服(成套,一系列具体产品),每次拿这种成套的衣服时也自然要从这个衣柜中取出了。用 OO 的思想去理解,所有的衣柜(具体工厂)都是衣柜类的(抽象工厂)某一个,而每一件成套的衣服又包括具体的上衣(某一具体产品),裤子(某一具体产品),这些具体的上衣其实也都是上衣(抽象产品),具体的裤子也都是裤子(另一个抽象产品)。

优点:当一个产品族中的多个对象被设计成一起工作时,它能保证客户端始终只使用同一个产品族中的对象。

缺点:产品族扩展非常困难,要增加一个系列的某一产品,既要在抽象的 Creator 里加代码,又要在具体的里面加代码。

使用场景: 1、QQ 换皮肤,一整套一起换。 2、生成不同操作系统的程序。

注意事项:产品族难扩展,产品等级易扩展。

总结:抽象工厂就是生产工厂的工厂,可以从里边取一类产品。hadoop序列化框架中,Serializer和Deserializer实例相反,相互依赖,必须通过抽象工厂Serialization,才能获得对应的实现。

相关代码如下(hadoop-1.0.0的代码,省略注释):

package org.apache.hadoop.io.serializer;
public interface Serialization<T> {        //Serialization抽象工厂,为Serializer和Deserializer对象创建抽象类来获取工厂。

  boolean accept(Class<?> c);

  Serializer<T> getSerializer(Class<T> c); //得到Serializer,定义为接口

  Deserializer<T> getDeserializer(Class<T> c); //得到Deserializer,定义为接口
}
package org.apache.hadoop.io.serializer;

import java.io.IOException;
import java.io.OutputStream;

public interface Serializer<T> {             //为Serializer创建一个接口
  void open(OutputStream out) throws IOException;

  void serialize(T t) throws IOException;

  void close() throws IOException;
}
package org.apache.hadoop.io.serializer;

import java.io.IOException;
import java.io.InputStream;

public interface Deserializer<T> {            //为Deserializer创建一个接口
  void open(InputStream in) throws IOException;

  T deserialize(T t) throws IOException;

  void close() throws IOException;
}
package org.apache.hadoop.io.serializer;

import java.io.IOException;
import java.io.InputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.OutputStream;
import java.io.Serializable;

public class JavaSerialization implements Serialization<Serializable> {
  //创建扩展了Serialization的工厂类JavaSerialization ,基于给定的信息生成实体类的对象。
  static class JavaSerializationDeserializer<T extends Serializable>
    implements Deserializer<T> {

    private ObjectInputStream ois;

    public void open(InputStream in) throws IOException {
      ois = new ObjectInputStream(in) {
        @Override protected void readStreamHeader() {
          // no header
        }
      };
    }

    @SuppressWarnings("unchecked")
    public T deserialize(T object) throws IOException {
      try {
        // ignore passed-in object
        return (T) ois.readObject();
      } catch (ClassNotFoundException e) {
        throw new IOException(e.toString());
      }
    }

    public void close() throws IOException {
      ois.close();
    }

  }

  static class JavaSerializationSerializer
    implements Serializer<Serializable> {

    private ObjectOutputStream oos;

    public void open(OutputStream out) throws IOException {
      oos = new ObjectOutputStream(out) {
        @Override protected void writeStreamHeader() {
          // no header
        }
      };
    }

    public void serialize(Serializable object) throws IOException {
      oos.reset(); // clear (class) back-references
      oos.writeObject(object);
    }

    public void close() throws IOException {
      oos.close();
    }

  }

  public boolean accept(Class<?> c) {
    return Serializable.class.isAssignableFrom(c);
  }

  public Deserializer<Serializable> getDeserializer(Class<Serializable> c) {
    return new JavaSerializationDeserializer<Serializable>();
  }

  public Serializer<Serializable> getSerializer(Class<Serializable> c) {
    return new JavaSerializationSerializer();
  }

}
package org.apache.hadoop.io.serializer;

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;

import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.conf.Configured;
import org.apache.hadoop.io.Writable;
import org.apache.hadoop.util.ReflectionUtils;

public class WritableSerialization extends Configured implements Serialization<Writable> {
  //创建扩展了Serialization的工厂类WritableSerialization,基于给定的信息生成实体类的对象。

  static class WritableDeserializer extends Configured
    implements Deserializer<Writable> {

    private Class<?> writableClass;
    private DataInputStream dataIn;

    public WritableDeserializer(Configuration conf, Class<?> c) {
      setConf(conf);
      this.writableClass = c;
    }

    public void open(InputStream in) {
      if (in instanceof DataInputStream) {
        dataIn = (DataInputStream) in;
      } else {
        dataIn = new DataInputStream(in);
      }
    }

    public Writable deserialize(Writable w) throws IOException {
      Writable writable;
      if (w == null) {
        writable
          = (Writable) ReflectionUtils.newInstance(writableClass, getConf());
      } else {
        writable = w;
      }
      writable.readFields(dataIn);
      return writable;
    }

    public void close() throws IOException {
      dataIn.close();
    }

  }

  static class WritableSerializer implements Serializer<Writable> {

    private DataOutputStream dataOut;

    public void open(OutputStream out) {
      if (out instanceof DataOutputStream) {
        dataOut = (DataOutputStream) out;
      } else {
        dataOut = new DataOutputStream(out);
      }
    }

    public void serialize(Writable w) throws IOException {
      w.write(dataOut);
    }

    public void close() throws IOException {
      dataOut.close();
    }

  }

  public boolean accept(Class<?> c) {
    return Writable.class.isAssignableFrom(c);
  }

  public Deserializer<Writable> getDeserializer(Class<Writable> c) {
    return new WritableDeserializer(getConf(), c);
  }

  public Serializer<Writable> getSerializer(Class<Writable> c) {
    return new WritableSerializer();
  }

}
package org.apache.hadoop.io.serializer;

import java.util.ArrayList;
import java.util.List;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.conf.Configured;
import org.apache.hadoop.util.ReflectionUtils;
import org.apache.hadoop.util.StringUtils;

public class SerializationFactory extends Configured {
  //创建一个工厂创造器/生成器类,通过传递类(Class<T> c)信息来获取工厂。
  private static final Log LOG =
    LogFactory.getLog(SerializationFactory.class.getName());

  private List<Serialization<?>> serializations = new ArrayList<Serialization<?>>();

  public SerializationFactory(Configuration conf) {
    super(conf);
    for (String serializerName : conf.getStrings("io.serializations",
      new String[]{"org.apache.hadoop.io.serializer.WritableSerialization"})) {
      add(conf, serializerName);
    }
  }

  @SuppressWarnings("unchecked")
  private void add(Configuration conf, String serializationName) {
    try {

      Class<? extends Serialization> serializionClass =
        (Class<? extends Serialization>) conf.getClassByName(serializationName);
      serializations.add((Serialization)
          ReflectionUtils.newInstance(serializionClass, getConf()));
    } catch (ClassNotFoundException e) {
      LOG.warn("Serilization class not found: " +
          StringUtils.stringifyException(e));
    }
  }

  public <T> Serializer<T> getSerializer(Class<T> c) {
    return getSerialization(c).getSerializer(c);
  }

  public <T> Deserializer<T> getDeserializer(Class<T> c) {
    return getSerialization(c).getDeserializer(c);
  }

  @SuppressWarnings("unchecked")
  public <T> Serialization<T> getSerialization(Class<T> c) {
    for (Serialization serialization : serializations) {
      if (serialization.accept(c)) {
        return (Serialization<T>) serialization;
      }
    }
    return null;
  }
}



时间: 2024-10-05 05:50:15

设计模式之抽象工厂模式:Hadoop序列化框架的相关文章

设计模式之抽象工厂模式

抽象工厂模式:提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类. 最大的好处便是易于交换产品系列,由于具体工厂类,在一个应用中只需在初始化的时候出现一次,这就使得改变一个应用的具体工厂变得非常容易,它只需改变具体工厂即可使用不同的产品配置. 他使具体创建实例的过程与客户端分离,客户端是通过它们的抽象接口操纵实例,产品的具体类名也被具体工厂的实现分离. 下面的代码还使用了反射与XML. 代码如下: using System; using System.Collections.Ge

设计模式之抽象工厂模式20170803

创建型设计模式之抽象工厂模式: 一.含义 为创建一组相关或相互依赖的对象提供一个接口,而且无需指定它们的具体类. 具体来说, 为一组具有相同约束(属性)的对象,提供一个接口,这个接口下有不同的实现,每个实现类对应一种类型的约束(一种具体的属性),同时提供该类型的约束(属性)下所有对象的创建方法 二.代码说明 1.主要有两个角色 1)一组互相影响的产品线(对象),也叫做产品族 2)抽象工厂类及其实现类 抽象工厂类:在N个产品族中,在抽象工厂类中就应该有N个创建方法 实现类:具体实现类是产品族的具体

大话设计模式_抽象工厂模式(Java代码)

抽象工厂模式:提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们的具体类. 简单描述:有多种抽象产品,并且每种抽象产品都有多个具体产品.一个抽象工厂,提供多个具体工厂,每个工厂则提供不同种类的具体产品. 大话设计模式中的截图: 例子代码: AbstractProductA类: 1 package com.longsheng.abstractfactory; 2 3 public abstract class AbstractProductA { 4 5 public abstract v

设计模式三—抽象工厂模式

设计模式三-抽象工厂模式 一.定义 抽象工厂模式是工厂方法模式的进一步抽象.如果产品簇中只有一种产品,则退化为工厂方法模式. 二.原理图 三.代码实例 * 苹果和土豆是园丁1的杰作 * 葡萄和西红柿是园丁2的杰作 1.Fruit.java public interface Fruit { /* * 生长 * 收获 * 栽种 */ public void grow(); public void harvest(); public void plant(); } 2.Apple.java publi

设计模式之抽象工厂模式(Abstract Factory)

1.定义 抽象工厂模式为创建一组相关或相互依赖的对象提供一个接口,而且无需指定他们的具体类. 2.类图 由于类太多就不上源码了~ 最佳实践: 在一个应用中,需要在三个不同平台(Windows.Linux.Android)上运行,通过抽象工厂模式屏蔽掉操作系统对应的影响三个不同操作系统上的软件功能.应用逻辑.UI都应该是非常类似的,唯一不同的是调用不同的工厂方法,由不同的产品类去处理与操作系统交互的信息. 设计模式之抽象工厂模式(Abstract Factory)

C#设计模式之三抽象工厂模式(AbstractFactory)【创建型】

原文:C#设计模式之三抽象工厂模式(AbstractFactory)[创建型] 一.引言 写了3篇有关设计模式的文章了,大家有了些反馈,说能从中学到一些东西,我感到很欣慰,那就继续努力.今天我要写第四个模式了,该模式叫抽象工厂.上一篇文章我们讲了[工厂方法]模式,它是为了解决[简单工厂]模式所面对的问题,它的问题就是:如果我们增加新的产品,工厂类的方法就要修改本身的代码,增加产品越多,其逻辑越复杂,同时这样的修改也是不符合[开放关闭原则OCP],对修改代码关闭,对增加代码开放.为了解决[简单工厂

设计模式——4.抽象工厂模式

1. 模式动机 在工厂方法模式中具体工厂负责生产具体的产品,每一个具体工厂对应一种具体产品,工厂方法也具有唯一性,一般情况下,一个具体工厂中只有一个工厂方法或者一组重载的工厂方法.但是有时候我们需要一个工厂可以提供多个产品对象,而不是单一的产品对象. 为了更清晰地理解工厂方法模式,需要先引入两个概念: 产品等级结构 :产品等级结构即产品的继承结构,如一个抽象类是电视机,其子类有海尔电视机.海信电视机.TCL电视机,则抽象电视机与具体品牌的电视机之间构成了一个产品等级结构,抽象电视机是父类,而具体

设计模式之抽象工厂模式(c++)

问题描述 假设我们要开发一款游戏, 当然为了吸引更多的人玩, 游戏难度不能太大(让大家都没有信心了,估计游戏也就没有前途了),但是也不能太简单(没有挑战性也不符合玩家的心理).于是我们就可以采用这样一种处理策略: 为游戏设立等级,初级.中级.高级甚至有BT 级. 假设也是过关的游戏, 每个关卡都有一些怪物( monster) 守着, 玩家要把这些怪物干掉才可以过关. 作为开发者, 我们就不得不创建怪物的类, 然后初级怪物. 中级怪物等都继承自怪物类(当然不同种类的则需要另创建类,但是模式相同).

【设计模式】抽象工厂模式

抽象工厂模式(Abstract Factory Pattern)是围绕一个超级工厂创建其他工厂.该超级工厂又称为其他工厂的工厂.这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式. 在抽象工厂模式中,接口是负责创建一个相关对象的工厂,不需要显式指定它们的类.每个生成的工厂都能按照工厂模式提供对象. 介绍 意图:提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类. 主要解决:主要解决接口选择的问题. 何时使用:系统的产品有多于一个的产品族,而系统只消费其中某一族的产品