当前位置:  编程技术>软件工程/软件设计
本页文章导读:
    ▪设计模式09---设计模式之生成器模式(Builder)也叫建造者模式      1.场景模式 在讨论工厂方法模式的时候,提到了一个导出数据的应用框架,但是没有涉及到导出文本的每种方式具体会如何实现。现在我们就来解决这个问题 假设导出的文件,无论什么格.........
    ▪svn_resin_持续优化中                                                                              .........
    ▪Bitmap recycle方法与制作Bitmap的内存缓存      recycle方法不是必须调用,就算调了GC也不会立即回收Java层的Bitmap对象。这个跟把一个对象手动置空一个道理。可以看一下API说明: This operation cannot be reversed, so it should only be called if you are sure .........

[1]设计模式09---设计模式之生成器模式(Builder)也叫建造者模式
    来源: 互联网  发布时间: 2013-11-19
1.场景模式 在讨论工厂方法模式的时候,提到了一个导出数据的应用框架,但是没有涉及到导出文本的每种方式具体会如何实现。现在我们就来解决这个问题
假设导出的文件,无论什么格式都分为三个部分,文件头,文件尾和文件体。
文件头:分公司或者门市点编号,导出数据的日期
文件尾:输出人
文件体:表名称
实现导出数据到文本文件和XML文件
2.代码模拟 2.1头文件内容
package demo07.builder.example1;


/**
 * 描述输出到文件头的内容的对象
 */
public class ExportHeaderModel {
	/**
	 * 分公司或门市点编号
	 */
	private String depId;
	/**
	 * 导出数据的日期
	 */
	private String exportDate;


	public String getDepId() {
		return depId;
	}


	public void setDepId(String depId) {
		this.depId = depId;
	}


	public String getExportDate() {
		return exportDate;
	}


	public void setExportDate(String exportDate) {
		this.exportDate = exportDate;
	}
}
2.2输出数据的对象
package demo07.builder.example1;


/**
 * 描述输出数据的对象
 */
public class ExportDataModel {
	/**
	 * 产品编号
	 */
	private String productId;
	/**
	 * 销售价格
	 */
	private double price;
	/**
	 * 销售数量
	 */
	private double amount;


	public String getProductId() {
		return productId;
	}


	public void setProductId(String productId) {
		this.productId = productId;
	}


	public double getPrice() {
		return price;
	}


	public void setPrice(double price) {
		this.price = price;
	}


	public double getAmount() {
		return amount;
	}


	public void setAmount(double amount) {
		this.amount = amount;
	}
}
2.3文件尾的内容的对象
package demo07.builder.example1;


/**
 * 描述输出到文件尾的内容的对象
 */
public class ExportFooterModel {
	/**
	 * 输出人
	 */
	private String exportUser;


	public String getExportUser() {
		return exportUser;
	}


	public void setExportUser(String exportUser) {
		this.exportUser = exportUser;
	}


}
2.4导出数据到文本文件的对象
package demo07.builder.example1;


import java.util.Collection;
import java.util.Map;


/**
 * 导出数据到文本文件的对象
 */
public class ExportToTxt {
	/**
	 * 导出数据到文本文件
	 * 
	 * @param ehm
	 *        文件头的内容
	 * @param mapData
	 *        数据的内容
	 * @param efm
	 *        文件尾的内容
	 */
	public void export(ExportHeaderModel ehm, Map<String, Collection<ExportDataModel>> mapData, ExportFooterModel efm) {
		// 用来记录最终输出的文件内容
		StringBuffer buffer = new StringBuffer();
		// 1:先来拼接文件头的内容
		buffer.append(ehm.getDepId() + "," + ehm.getExportDate() + "\n");
		// 2:接着来拼接文件体的内容
		for (String tblName : mapData.keySet()) {
			// 先拼接表名称
			buffer.append(tblName + "\n");
			// 然后循环拼接具体数据
			for (ExportDataModel edm : mapData.get(tblName)) {
				buffer.append(edm.getProductId() + "," + edm.getPrice() + "," + edm.getAmount() + "\n");
			}
		}
		// 3:接着来拼接文件尾的内容
		buffer.append(efm.getExportUser());


		// 为了演示简洁性,这里就不去写输出文件的代码了
		// 把要输出的内容输出到控制台看看
		System.out.println("输出到文本文件的内容:\n" + buffer);
	}
}
2.5导出数据到XML文件的对象
package demo07.builder.example1;


import java.util.Collection;
import java.util.Map;


/**
 * 导出数据到XML文件的对象
 */
public class ExportToXml {
	/**
	 * 导出数据到XML文件
	 * 
	 * @param ehm
	 *        文件头的内容
	 * @param mapData
	 *        数据的内容
	 * @param efm
	 *        文件尾的内容
	 */
	public void export(ExportHeaderModel ehm, Map<String, Collection<ExportDataModel>> mapData, ExportFooterModel efm) {
		// 用来记录最终输出的文件内容
		StringBuffer buffer = new StringBuffer();
		// 1:先来拼接文件头的内容
		buffer.append("<?xml version='1.0' encoding='gb2312'?>\n");
		buffer.append("<Report>\n");
		buffer.append("  <Header>\n");
		buffer.append("    <DepId>" + ehm.getDepId() + "</DepId>\n");
		buffer.append("    <ExportDate>" + ehm.getExportDate() + "</ExportDate>\n");
		buffer.append("  </Header>\n");
		// 2:接着来拼接文件体的内容
		buffer.append("  <Body>\n");
		for (String tblName : mapData.keySet()) {
			// 先拼接表名称
			buffer.append("    <Datas TableName=\"" + tblName + "\">\n");
			// 然后循环拼接具体数据
			for (ExportDataModel edm : mapData.get(tblName)) {
				buffer.append("      <Data>\n");
				buffer.append("        <ProductId>" + edm.getProductId() + "</ProductId>\n");
				buffer.append("        <Price>" + edm.getPrice() + "</Price>\n");
				buffer.append("        <Amount>" + edm.getAmount() + "</Amount>\n");
				buffer.append("      </Data>\n");
			}
			buffer.append("    </Datas>\n");
		}
		buffer.append("  </Body>\n");
		// 3:接着来拼接文件尾的内容
		buffer.append("  <Footer>\n");
		buffer.append("    <ExportUser>" + efm.getExportUser() + "</ExportUser>\n");
		buffer.append("  </Footer>\n");
		buffer.append("</Report>\n");


		// 为了演示简洁性,这里就不去写输出文件的代码了
		// 把要输出的内容输出到控制台看看
		System.out.println("输出到XML文件的内容:\n" + buffer);
	}
}
2.6客户端测试
package demo07.builder.example1;


import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;


public class Client {
	public static void main(String[] args) {
		// 准备测试数据
		ExportHeaderModel ehm = new ExportHeaderModel();
		ehm.setDepId("一分公司");
		ehm.setExportDate("2010-05-18");


		Map<String, Collection<ExportDataModel>> mapData = new HashMap<String, Collection<ExportDataModel>>();
		Collection<ExportDataModel> col = new ArrayList<ExportDataModel>();


		ExportDataModel edm1 = new ExportDataModel();
		edm1.setProductId("产品001号");
		edm1.setPrice(100);
		edm1.setAmount(80);


		ExportDataModel edm2 = new ExportDataModel();
		edm2.setProductId("产品002号");
		edm2.setPrice(99);
		edm2.setAmount(55);
		// 把数据组装起来
		col.add(edm1);
		col.add(edm2);
		mapData.put("销售记录表", col);


		ExportFooterModel efm = new ExportFooterModel();
		efm.setExportUser("张三");


		// 测试输出到文本文件
		ExportToTxt toTxt = new ExportToTxt();
		toTxt.export(ehm, mapData, efm);
		// 测试输出到xml文件
		ExportToXml toXml = new ExportToXml();
		toXml.export(ehm, mapData, efm);


	}
}
3.问题所在 仔细观察上面的实现,会发现,无论输出文本文件还是XML文件,在实现的时候,步骤基本上都是一样的,大致分为四步:
1. 拼接头文件的内容
2. 拼接文件体的内容
3. 拼接文件尾的内容
4. 把拼接好的内容输出到文件
这说明什么呢?说明对于不同的输出格式,处理步骤基本上是一致的。但是每步的具体实现是不一样的。
那么我们应该提炼出公共的处理过程,并且要能方便的快速切换不同的输出格式。
4.解决方案 4.1生成器模式的定义:(又叫建造者模式) 将一个复杂对象的构建与他的表示分离,使得同样的构建过程可以创建不同的表示。
4.2生成器模式的结构图  
5.生成器模式的示例代码 5.1被构建的产品对象的接口
package demo07.builder.example2;


/**
 * 被构建的产品对象的接口
 */
public interface Product {
	// 定义产品的操作
}
5.2构建器接口,定义创建一个产品对象所需的各个部件的操作
package demo07.builder.example2;


/**
 * 构建器接口,定义创建一个产品对象所需的各个部件的操作
 */
public interface Builder {
	/**
	 * 示意方法,构建部件1
	 */
	public void buildPart1();


	/**
	 * 示意方法,构建部件2
	 */
	public void buildPart2();


	/**
	 * 示意方法,构建部件3
	 */
	public void buildPart3();
}
5.3具体的构建器实现对象
package demo07.builder.example2;


/**
 * 具体的构建器实现对象
 */
public class ConcreteBuilder implements Builder {
	/**
	 * 构建器最终构建的产品对象
	 */
	private Product resultProduct;


	/**
	 * 获取构建器最终构建的产品对象
	 * 
	 * @return 构建器最终构建的产品对象
	 */
	public Product getResult() {
		return resultProduct;
	}


	@Override
	public void buildPart1() {
		// 有关this.resultProduct添加组      
    
[2]svn_resin_持续优化中
    来源: 互联网  发布时间: 2013-11-19
                                                                              通过svn的hooks自动部署项目到resin服务器
1.安装resin服务器
         tar zxvf resin.tar.gz

2.安装svn服务器,建立库

$ yum install subversion
$ yum install mod_dav_svn

   svnadmin create repos  /works/svnroot/repos
 

3.启动svn
svnserve -d -r /works/svnroot/repos

4.建立临时目录
mkdir /works/tem_svn

5.编辑post-commit
chomd 755 post-commit
-------------------------------------------------------------------------
export LANG=zh_CN.UTF-8

REPOS="$1"
REV="$2"

WEB=/works/webapps
TEM=/works/tem_svn/andy

svn checkout svn://localhost/andy  "$TEM"

rsync -auvrP --delete --quiet --exclude=".svn"  "$TEM"  "$WEB"

rm -rf /works/tem_svn/andy

echo "$REPOS  $REV  $WEB " >> /works/svnroot/svn.log
--------------------------------------------------------------------------------------
作者:Andy90914041 发表于2013-6-29 16:54:25 原文链接
阅读:20 评论:0 查看评论

    
[3]Bitmap recycle方法与制作Bitmap的内存缓存
    来源: 互联网  发布时间: 2013-11-19
recycle方法不是必须调用,就算调了GC也不会立即回收Java层的Bitmap对象。这个跟把一个对象手动置空一个道理。可以看一下API说明:
This operation cannot be reversed, so it should only be called if you are sure there are no further uses for the bitmap. This is an advanced call, and normally need not be called, since the normal GC process will free up this memory when there are no more references to this bitmap. 


那么为什么程序中一般还需要调用呢?我们可以看一下recycle方法到底干了什么,下面是它的调用链:
Bitmap.recycle()(java)->nativeRecycle(mNativeBitmap)(java native)->SKBitmap::setPixels(NULL, NULL)(C++)->freePixels()(C++)
可以看出,recycle方法就是把C层的像素内存给释放了。我们知道,C层的内存还是算到当前进程的内存里的,而构成一个Bitmap对象的内存大部分都是C层的像素数组。所以,手动调用Bitmap.recycle并把Bitmap对象的Java层引用手动置NULL可以瞬间释放像素所占的内存,并让虚拟机下次运行时回收Bitmap对象所占的内存。不要忘了,因为包含了一堆的像素数据,Bitmap对象通常都很大。当很容易判断出这个图片不再被使用的时候就把它recycle一下吧。


但有一种情况比较除外,这就是程序中的列表界面,因为你不能判断用户会滚上还是滚下,而列表又比较长你不能保持所有的列表项中的图片。怎么办呢?
先说一个小测试:
[java] view plaincopy
  • for (int i = 0; i < 1024; i++) {  
  •     Bitmap b = Bitmap.createBitmap(1024*4, 1024*2, Config.ARGB_8888);  
  • }  

  • 上面这段代码我运行了一下,没有报错。这验证了API文档中所说的,GC是可以自己回收Bitmap。这样,我们就可以有足够的理论支撑来使用SoftReference或者WeakReference制作一个内存缓存专门存放列表中的Bitmap了。网上讲强/软/弱引用时通常都会带着一个这样的例子,我就不再多说了,贴个网址,供参考:http://speed847.iteye.com/blog/374006
    这里强调一下在制作内存缓存时使用软/弱引用的区别:
    软引用:GC在分配对象时如果发现内存不足就会回收软引用的对象。
    弱引用:只要GC一运行就会被回收。也可以用它来制作内存缓存,缺点就是如果其它模块频繁分配/释放对象造成GC运行比较频繁,缓存中的对象很可能会在内存很充裕的时候被清除,达不到缓存的目的了。

    通常的内存缓存都是用软引用来制作。可以根据实际应用场景选择一个。


    Android中的两种硬缓存
    通常,借助于LinkHashMap我们可以很快建立一个硬缓存:
    mLruMap = new LinkedHashMap<K, V>(16, 0.75f, true) {
    @Override
    protected boolea

        
    最新技术文章:
    ▪主-主数据库系统架构    ▪java.lang.UnsupportedClassVersionError: Bad version number i...    ▪eclipse项目出现红色叉叉解决方案
    ▪Play!framework 项目部署到Tomcat    ▪dedecms如何做中英文网站?    ▪Spring Batch Framework– introduction chapter(上)
    ▪第三章 AOP 基于@AspectJ的AOP    ▪基于插件的服务集成方式    ▪Online Coding开发模式 (通过在线配置实现一个表...
    ▪观察者模式(Observer)    ▪工厂模式 - 程序实现(java)    ▪几种web并行化编程实现
    ▪机器学习理论与实战(二)决策树    ▪Hibernate(四)——全面解析一对多关联映射    ▪我所理解的设计模式(C++实现)——解释器模...
    ▪利用规则引擎打造轻量级的面向服务编程模式...    ▪google blink的设计计划: Out-of-Progress iframes    ▪FS SIP呼叫的消息线程和状态机线程
    ▪XML FREESWITCH APPLICATION 实现    ▪Drupal 实战    ▪Blink: Chromium的新渲染引擎
    ▪(十四)桥接模式详解(都市异能版)    ▪你不知道的Eclipse用法:使用Allocation tracker跟...    ▪Linux内核-进程
    ▪你不知道的Eclipse用法:使用Metrics 测量复杂度    ▪IT行业为什么没有进度    ▪Exchange Server 2010/2013三种不同的故障转移
    ▪第二章 IoC Spring自动扫描和管理Bean    ▪CMMI简介    ▪目标检测(Object Detection)原理与实现(六)
    ▪值班总结(1)——探讨sql语句的执行机制    ▪第二章 IoC Annotation注入    ▪CentOS 6.4下安装Vagrant
    ▪Java NIO框架Netty1简单发送接受    ▪漫画研发之八:会吃的孩子有奶吃    ▪比较ASP和ASP.NET
    ▪SPRING中的CONTEXTLOADERLISTENER    ▪在Nginx下对网站进行密码保护    ▪Hibernate从入门到精通(五)一对一单向关联映...
    ▪.NET领域驱动设计—初尝(三:穿过迷雾走向光...    ▪linux下的块设备驱动(一)    ▪Modem项目工作总结
    论坛 iis7站长之家
    ▪windows下用putty上传文件到远程Linux方法    ▪iBatis和Hibernate的5点区别    ▪基于学习的Indexing算法
    ▪设计模式11---设计模式之中介者模式(Mediator...    ▪带你走进EJB--JMS编程模型    ▪从抽象谈起(二):观察者模式与回调
    ▪设计模式09---设计模式之生成器模式(Builder)也...    ▪svn_resin_持续优化中    ▪Bitmap recycle方法与制作Bitmap的内存缓存
    ▪Hibernate从入门到精通(四)基本映射    ▪设计模式10---设计模式之原型模式(Prototype)    ▪Dreamer 3.0 支持json、xml、文件上传
    ▪Eclipse:使用PMD预先检测错误    ▪Jspx.net Framework 5.1 发布    ▪从抽象谈起(一):工厂模式与策略模式
    ▪Eclipse:使用CheckStyle实施编码标准    ▪【论文阅读】《Chain Replication for Supporting High T...    ▪Struts2 Path_路径问题
    ▪spring 配置文件详解    ▪Struts2第一个工程helloStruts极其基本配置    ▪Python学习入门基础教程(learning Python)--2 Python简...
    ▪maven springmvc环境配置    ▪基于SCRUM的金融软件开发项目    ▪software quality assurance 常见问题收录
    ▪Redis集群明细文档    ▪Dreamer 框架 比Struts2 更加灵活    ▪Maven POM入门
    ▪git 分支篇-----不断更新中    ▪Oracle非主键自增长    ▪php设计模式——UML类图
    ▪Matlab,Visio等生成的图片的字体嵌入问题解决...    ▪用Darwin和live555实现的直播框架    ▪学习ORM框架—hibernate(二):由hibernate接口谈...
    ▪(十)装饰器模式详解(与IO不解的情缘)    ▪无锁编程:最简单例子    ▪【虚拟化实战】网络设计之四Teaming
    ▪OSGi:生命周期层    ▪Javascript/Jquery——简单定时器    ▪java代码 发送GET、POST请求
    ▪Entity Framework底层操作封装(3)    ▪HttpClient 发送GET、POST请求    ▪使用spring框架,应用启动时,加载数据
    ▪Linux下Apache网站目录读写权限的设置    ▪单键模式的C++描述    ▪学习ORM框架—hibernate(一):初识hibernate
     


    站内导航:


    特别声明:169IT网站部分信息来自互联网,如果侵犯您的权利,请及时告知,本站将立即删除!

    ©2012-2021,,E-mail:www_#163.com(请将#改为@)

    浙ICP备11055608号-3