当前位置: 编程技术>软件工程/软件设计
本页文章导读:
▪设计模式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头文件内容
1. 拼接头文件的内容
2. 拼接文件体的内容
3. 拼接文件尾的内容
4. 把拼接好的内容输出到文件
这说明什么呢?说明对于不同的输出格式,处理步骤基本上是一致的。但是每步的具体实现是不一样的。
那么我们应该提炼出公共的处理过程,并且要能方便的快速切换不同的输出格式。
4.解决方案 4.1生成器模式的定义:(又叫建造者模式) 将一个复杂对象的构建与他的表示分离,使得同样的构建过程可以创建不同的表示。
4.2生成器模式的结构图
5.生成器模式的示例代码 5.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
tar zxvf resin.tar.gz
2.安装svn服务器,建立库
$ yum install subversion
$ yum install mod_dav_svn
svnadmin create repos /works/svnroot/repos
$ yum install subversion
$ yum install mod_dav_svn
svnadmin create repos /works/svnroot/repos
3.启动svn
svnserve -d -r /works/svnroot/repos
svnserve -d -r /works/svnroot/repos
4.建立临时目录
mkdir /works/tem_svn
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
--------------------------------------------------------------------------------------
-------------------------------------------------------------------------
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一下吧。
但有一种情况比较除外,这就是程序中的列表界面,因为你不能判断用户会滚上还是滚下,而列表又比较长你不能保持所有的列表项中的图片。怎么办呢?
先说一个小测试:
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运行比较频繁,缓存中的对象很可能会在内存很充裕的时候被清除,达不到缓存的目的了。
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
上面这段代码我运行了一下,没有报错。这验证了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
最新技术文章: