博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
深入Java Builder模式--组装复杂的实例
阅读量:7257 次
发布时间:2019-06-29

本文共 16308 字,大约阅读时间需要 54 分钟。

  hot3.png

#Java Builder模式-组装复杂的实例。

  • 上一面介绍 简单介绍了下我在项目中的使用。

Builder

  • 什么是Builder模式?

    • ​ 大都市中林立着许多高楼大厦,这些高楼大厦都是具有建筑结构的大型建筑。通常,建造和构建这种具有建筑结构的大型物体在英文中成为Build。

      ​ 在建筑大楼时,需要打牢地基,搭建框架,然后自下而上地一层一层盖起来。通常,在建造这种具有复杂结构的物体时,很难一气呵成。我们需要首先建造组成这个物体的各个部分,然后分段将他们组装起来。

      ​ ---图解设计模式

  • 这个用例并不是特别的明显,大体的思路是这样的。

  • 改造上次的代码。首先分析下上篇文章中ztree的数据结构

输入图片说明

  • 依赖库
    • commons-lang3
      • 3.4
    • com.thoughtworks.xstream
      • 1.4.10
    • com.fasterxml.jackson.core
      • 2.8.1

Builder中角色

关系大概就是这样的样子

  • 建造者 Builder
  • 具体建造者ConcreteBuilder
    • ZtreeJSONBuilder
    • ZtreeXMLBuilder
  • 监工 Director
  • 测试 Testing
participant Testingparticipant Directorparticipant ConstructBuilderTesting -> ConstructBuilder: newTesting -> Director : constructDirector -> ConstructBuilder : initConstructBuilder -->> Director : Director-->> Testing: successful

输入图片说明

Builder建造者

package cn.z201.gof.builder; import java.util.Collection; public abstract class ZtreeBuilder
{ public static final String TOP = "0001"; public abstract String treeName(); public abstract Object findResuls(); public abstract void id(String id); public abstract void pid(String pid); public abstract void name(String name); public abstract void url(String url); public abstract void open(boolean open); public abstract void parent(boolean parent); public abstract void children(Collection
children); public abstract String id(); public abstract String pid(); public abstract String name(); public abstract String url(); public abstract boolean open(); public abstract boolean parent(); public abstract Collection
children(); }

ConcreteBuilder具体的建造者

package cn.z201.gof.builder;  import java.util.ArrayList;  import java.util.Collection;  import cn.z201.gof.utils.JsonUtil;  public class ZtreeJSONBuilder extends ZtreeBuilder
{ //本级Id private String id; //父级菜单的 id private String pid; //中文名称 private String name; //点击地址 private String url; //是否展开 private boolean open; //是否为父节点 private boolean isParent; private Collection
children = new ArrayList
();; public ZtreeJSONBuilder() { } @Override public String treeName() { return this.getClass().getSimpleName(); } @Override public Object findResuls(){ return JsonUtil.toJson(this); } @Override public void id(String id) { this.id = id; } @Override public void pid(String pid) { this.pid = pid; } @Override public void name(String name) { this.name = name; } @Override public void url(String url) { this.url = url; } @Override public void open(boolean open) { this.open = open; } @Override public void parent(boolean isParent) { this.isParent = isParent; } @Override public void children(Collection
children) { this.children = (Collection
) children; } @Override public String id() { return this.id; } @Override public String pid() { return this.pid; } @Override public String name() { return this.name; } @Override public String url() { return this.url; } @Override public boolean open() { return this.open; } @Override public boolean parent() { return this.isParent; } @Override public Collection
children() { return this.children; } public String getId() { return id; } public void setId(String id) { this.id = id; } public String getPid() { return pid; } public void setPid(String pid) { this.pid = pid; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getUrl() { return url; } public void setUrl(String url) { this.url = url; } public boolean isOpen() { return open; } public void setOpen(boolean open) { this.open = open; } public boolean getIsParent() { return isParent; } public void setIsParent(boolean isParent) { this.isParent = isParent; } public Collection
getChildren() { return children; } public void setChildren(Collection
children) { this.children = children; } } package cn.z201.gof.builder; import java.util.ArrayList; import java.util.Collection; import com.thoughtworks.xstream.XStream; import com.thoughtworks.xstream.annotations.XStreamAlias; import cn.z201.gof.utils.XMLUtil; @XStreamAlias("ZtreeXMLBuilder") public class ZtreeXMLBuilder extends ZtreeBuilder
{ //本级Id private String id; //父级菜单的 id private String pid; //中文名称 private String name; //点击地址 private String url; //是否展开 private boolean open; //是否为父节点 private boolean isParent; private Collection
children = new ArrayList
(); public ZtreeXMLBuilder() { } @Override public String treeName() { return this.getClass().getSimpleName(); } @Override public Object findResuls(){ XStream xstream = new XStream(); xstream.autodetectAnnotations(true); xstream.alias("ZtreeXMLBuilder", ZtreeXMLBuilder.class); xstream.registerConverter(new XMLUtil()); return xstream.toXML(this); } @Override public void id(String id) { this.id = id; } @Override public void pid(String pid) { this.pid = pid; } @Override public void name(String name) { this.name = name; } @Override public void url(String url) { this.url = url; } @Override public void open(boolean open) { this.open = open; } @Override public void parent(boolean isParent) { this.isParent = isParent; } @Override public void children(Collection
children) { this.children = (Collection
) children; } @Override public String id() { return this.id; } @Override public String pid() { return this.pid; } @Override public String name() { return this.name; } @Override public String url() { return this.url; } @Override public boolean open() { return this.open; } @Override public boolean parent() { return this.isParent; } @Override public Collection
children() { return this.children; } public String getId() { return id; } public void setId(String id) { this.id = id; } public String getPid() { return pid; } public void setPid(String pid) { this.pid = pid; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getUrl() { return url; } public void setUrl(String url) { this.url = url; } public boolean getOpen() { return open; } public void setOpen(boolean open) { this.open = open; } public boolean getIsParent() { return isParent; } public void setIsParent(boolean isParent) { this.isParent = isParent; } public Collection
getChildren() { return children; } public void setChildren(Collection
children) { this.children = children; } }

Director监工

package cn.z201.gof.builder;  import cn.z201.gof.utils.CodingFactoryUtil;  public class Director{  	  	private ZtreeBuilder
ztreeBuilder; public
> Director(ZtreeBuilder
builder){ ztreeBuilder = builder; } public Object getResuls(){ return ztreeBuilder.findResuls(); } public void construct(){ if(null == ztreeBuilder.id()){ ztreeBuilder.id(ZtreeBuilder.TOP); } if(null == ztreeBuilder.name()){ ztreeBuilder.name(ztreeBuilder.treeName()); } if(null == ztreeBuilder.pid()){ ztreeBuilder.pid(CodingFactoryUtil.ztreeCodingFactory(ZtreeBuilder.TOP, ZtreeBuilder.TOP)); }else{ ztreeBuilder.pid(CodingFactoryUtil.ztreeCodingFactory(ztreeBuilder.pid(), ztreeBuilder.id())); } } }

工具类

package cn.z201.gof.utils;import org.apache.commons.lang3.StringUtils;import org.apache.log4j.Logger;public class CodingFactoryUtil {		private static final Logger LOGGER = Logger.getLogger(CodingFactoryUtil.class);		/** ztree的编码加工规则 */	public static final int ztreeRules = 4;		/** 补码 */	public static final String complement = "0";		/**	 * @param head 前置编码 比如0001	 * @param tail 后置编码 比如1	 * @param reules 编码长度 比如4 表示长度四位	 * @return 00010001	 * @throws Exception 	 */	public static String codingFactory(String head ,String tail ,int reules) throws Exception{		if(tail.length() > reules) throw new Exception();		for (int i = 0; i < reules; i++) {			if(tail.length() == reules) break;			tail = StringUtils.join(complement , tail);		}		return StringUtils.join(head , tail);	}		public static String ztreeCodingFactory(String head , String tail){		try {			return codingFactory(head , tail , ztreeRules);		} catch (Exception e) {			LOGGER.error(e.getMessage());		}		return null;	}	}package cn.z201.gof.utils;import com.fasterxml.jackson.annotation.JsonInclude;import com.fasterxml.jackson.core.JsonGenerationException;import com.fasterxml.jackson.core.JsonParseException;import com.fasterxml.jackson.core.type.TypeReference;import com.fasterxml.jackson.databind.DeserializationFeature;import com.fasterxml.jackson.databind.JsonMappingException;import com.fasterxml.jackson.databind.ObjectMapper;import com.fasterxml.jackson.databind.SerializationFeature;import java.io.IOException;import java.text.SimpleDateFormat;import java.util.TimeZone;/** * JSON 和 Java对象相互转换 */public class JsonUtil {    private static final ObjectMapper objectMapper;    static {        objectMapper = new ObjectMapper();        //去掉默认的时间戳格式        objectMapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false);        //设置为中国上海时区        objectMapper.setTimeZone(TimeZone.getTimeZone("GMT+8"));        objectMapper.configure(SerializationFeature.WRITE_NULL_MAP_VALUES, false);        //空值不序列化        objectMapper.setSerializationInclusion(JsonInclude.Include.ALWAYS);        //反序列化时,属性不存在的兼容处理        objectMapper.getDeserializationConfig().withoutFeatures(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);        //序列化时,日期的统一格式        objectMapper.setDateFormat(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"));        objectMapper.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false);        objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);        //单引号处理        objectMapper.configure(com.fasterxml.jackson.core.JsonParser.Feature.ALLOW_SINGLE_QUOTES, true);        objectMapper.configure(com.fasterxml.jackson.core.JsonParser.Feature.ALLOW_UNQUOTED_FIELD_NAMES, true);        //objectMapper.configure(com.fasterxml.jackson.core.JsonParser.Feature.CANONICALIZE_FIELD_NAMES, true);    }    public static 
T toObject(String json, Class
clazz) { try { return objectMapper.readValue(json, clazz); } catch (JsonParseException e) { throw new MepException(e); } catch (JsonMappingException e) { throw new MepException(e); } catch (IOException e) { throw new MepException(e); } } public static
T toCollection(String json, TypeReference
typeReference) { try { return objectMapper.readValue(json, typeReference); } catch (JsonParseException e) { throw new MepException(e); } catch (JsonMappingException e) { throw new MepException(e); } catch (IOException e) { throw new MepException(e); } } public static
String toJson(T entity) { try { return objectMapper.writeValueAsString(entity); } catch (JsonGenerationException e) { throw new MepException(e); } catch (JsonMappingException e) { throw new MepException(e); } catch (IOException e) { throw new MepException(e); } }}/** * Copyright © 2017 z201.cn . All rights reserved. * @Title: XMLUtil.java * @Prject: learn-gof * @Package: cn.z201.gof.utils * @author: int_java_se@163.com * @date: 2017年7月15日 上午3:51:36 */package cn.z201.gof.utils;import java.lang.reflect.Field; import java.lang.reflect.Method; import java.lang.reflect.ParameterizedType; import java.lang.reflect.Type; import java.util.Arrays; import java.util.Collection; import java.util.List; import java.util.Set; import com.thoughtworks.xstream.converters.Converter; import com.thoughtworks.xstream.converters.MarshallingContext; import com.thoughtworks.xstream.converters.UnmarshallingContext; import com.thoughtworks.xstream.io.HierarchicalStreamReader; import com.thoughtworks.xstream.io.HierarchicalStreamWriter; public class XMLUtil implements Converter{ @SuppressWarnings("rawtypes") private Class currentType; private final String clazzNames[] = {"ZtreeXMLBuilder"};// 定义所要转换的对象及所包含的对象名称 private List
clazzNamesList; @SuppressWarnings("rawtypes") @Override public boolean canConvert(Class type) { currentType = type; clazzNamesList = Arrays.asList(clazzNames); if (clazzNamesList.contains(currentType.getSimpleName())) { return true; } else { return false; } } @Override public void marshal(Object source, HierarchicalStreamWriter writer, MarshallingContext context) { try { marshalSuper(source, writer, context, currentType); } catch (Exception e) { e.printStackTrace(); } } @SuppressWarnings({ "unchecked", "rawtypes" }) private Object getObj(Class clazz, String nodeName, Object source) throws Exception { Method method = clazz.getMethod("get" + Character .toUpperCase(nodeName.substring(0, 1).toCharArray()[0]) + nodeName.substring(1)); Object obj = null; obj = method.invoke(clazz.cast(source), new Object[0]); return obj; } @SuppressWarnings({ "rawtypes" }) private void objConverter(Object source, HierarchicalStreamWriter writer, MarshallingContext context, Class clazz, String nodeName, Class fieldClazz) throws Exception { Object obj = getObj(clazz, nodeName, source); writer.startNode(nodeName); marshalSuper(obj, writer, context, fieldClazz); writer.endNode(); } @SuppressWarnings({ "rawtypes" }) private void collectionConverter(Object source, HierarchicalStreamWriter writer, MarshallingContext context, Class clazz, String nodeName, Field field) throws Exception { Type types[] = ((ParameterizedType) field.getGenericType()) .getActualTypeArguments(); Object obj = getObj(clazz, nodeName, source); Collection collection = null; if (field.getType().equals(List.class)) { collection = (List) obj; } else if (field.getType().equals(Set.class)) { collection = (Set) obj; } writer.startNode(nodeName); for (Object object : collection) { String clazzName = ((Class) types[0]).getSimpleName(); writer.startNode(Character.toLowerCase(clazzName.substring(0, 1) .toCharArray()[0]) + clazzName.substring(1)); marshalSuper(object, writer, context, (Class) types[0]); writer.endNode(); } writer.endNode(); } @SuppressWarnings({ "rawtypes" }) private void basicTypeConverter(Object source, HierarchicalStreamWriter writer, MarshallingContext context, Class clazz, String nodeName) throws Exception { Object obj = getObj(clazz, nodeName, source); writer.startNode(nodeName); writer.setValue(obj == null ? "" : obj.toString()); writer.endNode(); } @SuppressWarnings({ "rawtypes" }) private void marshalSuper(Object source, HierarchicalStreamWriter writer, MarshallingContext context, Class clazz) throws Exception { Field fields[] = clazz.getDeclaredFields(); for (Field field : fields) { String nodeName = field.getName(); Class fieldClazz = field.getType(); if (clazzNamesList.contains(fieldClazz.getSimpleName())) { objConverter(source, writer, context, clazz, nodeName, fieldClazz); } else if (Arrays.asList(fieldClazz.getInterfaces()).contains( Collection.class)) { collectionConverter(source, writer, context, clazz, nodeName, field); } else { basicTypeConverter(source, writer, context, clazz, nodeName); } } } @Override public Object unmarshal(HierarchicalStreamReader reader, UnmarshallingContext context) { return null; } }

测试

package cn.z201.gof;import org.junit.Test;import cn.z201.gof.builder.Director;import cn.z201.gof.builder.ZtreeBuilderXML;import cn.z201.gof.builder.ZtreeBuilderJSON;public class Testing {	@Test	public void test(){		Director director = new Director(new ZtreeJSONBuilder());		director.construct();		System.out.println(director.getResuls());			director = new Director(new ZtreeXMLBuilder());			director.construct();		System.out.println(director.getResuls());			}	}

测试结果

  • 这里做了区分,所以使用了两种数据形式展示。
{"id":"0001","pid":"00010001","name":"ZtreeJSONBuilder","url":null,"open":false,"isParent":false,"children":[]}
0001
00010001
ZtreeXMLBuilder
false
false
[]

转载于:https://my.oschina.net/z201/blog/1396654

你可能感兴趣的文章
POJ-1256(permutation)
查看>>
杭电 hdu 2024
查看>>
Ansible的几个基本语句
查看>>
我的友情链接
查看>>
单态模式(单例模式)Singleton
查看>>
AndroidManifest.xml---XML的结构
查看>>
初来咋到
查看>>
微信小程序如何获取openid
查看>>
『Kruscal重构树 Exkruscal』
查看>>
php bom头问题解决
查看>>
linux rehat 9.0 系统基本操作/命令
查看>>
Android MediaPlayer各个状态和错误详情
查看>>
linux排优命令
查看>>
iptables学习笔记
查看>>
网络工程师的爱情...
查看>>
struts2
查看>>
ZOJ - 3981 - Balloon Robot (思维)
查看>>
s:property 获取 ValueStack中的值
查看>>
String.replace
查看>>
一次性事务和CTE插入数据的比较
查看>>