生成器模式
扯淡
写点什么之前总会想先说点什么,总觉得不说点什么就不舒服似的。昨天回头看了一下之前写的文章分享的东西虽然自我感觉很有用但是又总觉得在自言自语,以一个旁观者的身份来看的话如果不是有点造诣还真不是很好懂,所以以后的我打算少出文章,出精品。另外我的文章似乎太过庞杂了,android,java,ndk什么都有,有时我自己也觉得似乎这样不好但是这正是我的学习过程,大多数东西都是学了,没精通不能用于实战,但是有一点确是让我发现了其中的一点好处,随着我知识的维度增加,自己现在接触新东西上手越来越快,以往学东西主要靠视频,而现在碰到了问题往往先自己寻找解决方案,因为问题总是不可预知的,这个时候多维的知识往往能够主动的或潜意识的帮助解决问题,所以现在的我并不介意知识的庞杂,只要这些是在我们安卓本身不断精进的基础上就可以了,以后的文章也会继续现在的风格,只要是我认为有用的都会分享出来给大家
设计模式
今天给大家分享一种设计模式–生成器模式,关于设计模式的作用说实话目前为止我实战所用到的地方也是少之又少,更多的时候是运用对它的理解更好的理解源码(第三方的和官方的),但是这不影响它在我心中的地位,因为这些都是帮助我们将来写出更好代码的前提,所以只要认识到自己是对的就一往无前吧,下面进入正题。
生成器模式
一种设计模式,又名:建造模式,是一种对象构建模式。它可以将复杂对象的建造过程抽象出来(抽象类别),使这个抽象过程的不同实现方法可以构造出不同表现(属性)的对象。
个人实在不太擅长定义,所以这段定义是我copy的别人的阐述。
先看看今天的效果图提提神吧
代码与分析
设计模式的东西还是有些抽象的最好的学习它的方法恐怕就是写代码了,那么我也直接从代码里面分析吧,一共两个例子第二个有点复杂基础不好的可以绕过了。
Insurance
public class Insurance {
private String name;
private String id;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
}
ContreteBuilder
package com.example.builder1;
public class ContreteBuilder {
private String name;
private String id;
public Insurance build(){
Insurance in = new Insurance();
if(name == "李白"){
throw new IllegalArgumentException("李白太豪放");
}else{
in.setId(name);
}
in.setId(id);
return in;
}
public ContreteBuilder setName(String name) {
this.name = name;
return this;
}
public ContreteBuilder setId(String id) {
this.id = id;
return this;
}
}
Client
package com.example.builder1;
public class Client {
public static void main(String[] args) {
ContreteBuilder builder = new ContreteBuilder();
builder.setId("342342423").setName("李太白");
Insurance in = builder.build();
System.out.println(in.getId()+"name"+in.getName());
}
}
Insurance是一个实体类就是我们所要构建的对象,而ContreteBuilder是我们对象的表示过程,通过ContreteBuilder的build()方法得到,细心的你应该会发现这个类里我们是不能给Insurance直接赋值的而必须通过ContreteBuilder的包装才好,通常Insurance的权限应该是protected的这样就能既实现了生成器模式的流程,又避免了使用者直接初始化对象的情况发生,而且这种方法是支持链式编程的提高了代码的可读性。(本段代码比较易懂,效果图就不发了,有兴趣的可以直接将代码复制到自己的工程中查看)
下面的例子最初是我看的别人的代码,不过我在他的代码里看到了更多的可扩展性,所以私自改编并且增加了泛型等元素增加了程序的扩展性。
public interface ExportProdure< H, F, D> {
void exportHeader(H hm);
void exportData(Map<String, Collection<F>> dmMap);
void exportFooter(D fm);
StringBuffer getResult();
}
public class ExportToText implements ExportProdure<HeaderModuel,DataModel,FooterModel>{
private StringBuffer sb = new StringBuffer();
@Override
public void exportHeader(HeaderModuel hm) {
// TODO Auto-generated method stub
sb.append("表单开始"+"\n");
sb.append(hm.gettName()+",").append(hm.gettId()+"\n");
}
@Override
public void exportData(Map<String, Collection<DataModel>> dmMap) {
// TODO Auto-generated method stub
for(Map.Entry<String, Collection<DataModel>> entry:dmMap.entrySet()){
String key = entry.getKey();
Collection<DataModel> value = entry.getValue();
sb.append(key).append("\n");
for (DataModel fm : value) {
sb.append(fm.getSex()+",").append(fm.getsAge()+",").append(fm.getpNum()+"\n");
}
}
}
@Override
public void exportFooter(FooterModel fm) {
// TODO Auto-generated method stub
sb.append(fm.getExPName()+"\n");
sb.append("表单结束"+"\n");
}
@Override
public StringBuffer getResult() {
// TODO Auto-generated method stub
return sb;
}
}
public class ExportToXml implements ExportProdure<HeaderModuel,DataModel,FooterModel>{
private StringBuffer sb = new StringBuffer();
@Override
public void exportHeader(HeaderModuel hm) {
// TODO Auto-generated method stub
sb.append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
sb.append("<Table>\n");
sb.append(" <Header>\n");
sb.append(" <TableId>").append(hm.gettId()).append("</TableId>\n");
sb.append(" <TableName>").append(hm.gettName()).append("</TableName>\n");
sb.append(" </Header>\n");
}
@Override
public void exportData(Map<String, Collection<DataModel>> dmMap) {
// TODO Auto-generated method stub
sb.append("<Body>\n");
for(Map.Entry<String, Collection<DataModel>> entry:dmMap.entrySet()){
String key = entry.getKey();
Collection<DataModel> value = entry.getValue();
for (DataModel fm : value) {
sb.append(" <Datas PersonName=" +key+ ">\n");
sb.append(" <Age>").append(fm.getsAge()).append("</Age>\n");
sb.append(" <Sex>").append(fm.getSex()).append("</Sex>\n");
sb.append(" <Number>").append(fm.getpNum()).append("</Number>\n");
}
sb.append(" <Datas>\n");
}
sb.append("</Body>\n");
}
@Override
public void exportFooter(FooterModel fm) {
// TODO Auto-generated method stub
sb.append(" <Footer>\n");
sb.append(" <ExportPerson>").append(fm.getExPName()).append("</ExportPerson>\n");
sb.append(" </Footer>\n");
sb.append("</Table>\n");
}
@Override
public StringBuffer getResult() {
// TODO Auto-generated method stub
return sb;
}
}
public class FooterModel {
private String exPName;
public String getExPName() {
return exPName;
}
public void setExPName(String exPName) {
this.exPName = exPName;
}
}
public class HeaderModuel {
private String tId;
private String tName;
public String gettId() {
return tId;
}
public void settId(String tId) {
this.tId = tId;
}
public String gettName() {
return tName;
}
public void settName(String tName) {
this.tName = tName;
}
}
public class DataModel {
private String pNum;
private String sex;
private String sAge;
public String getpNum() {
return pNum;
}
public void setpNum(String pNum) {
this.pNum = pNum;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
public String getsAge() {
return sAge;
}
public void setsAge(String sAge) {
this.sAge = sAge;
}
}
上面的程序的功能是用同样的过程将三个实体类的内容导出到xml文件和txt文件,后三个类就是我们需要的实体类,ExportProdure是导出类的基类,ExportToText和ExportToXml是导出的实现类,Director是外观模式的一种体现,我们导出的顺序与内容都是通过他来控制的。我还是比较喜欢看图说话,下面还是用一张图来解释我们的代码
效果图
Director是执行类它持有了ExportProdure(Builder)的对象,实际上就是后面的两个具体实现的一种,而ExportToTxt和ExportToXml两个类就通过Builder里面的步骤完成了文件的导出,纵观整个过程可以看到,我们导出两种格式数据的步骤方法是一样的,只需要一一实现Builder中的方法就行,解释就到这里了,设计模式的东西终究还是要靠代码的积累,唉,又写了一篇超滥的文章,希望能有人看懂吧。
>
大概二十天之前就说过要写一篇正则表达式的文章,竟然收到了商大神的强烈渴求,不过之前太忙就搁浅了,本来我也是想让这篇文章胎死腹中的但是为了我们商大神的信任,我会尽快在下一篇文章中分享给大家
—–敬礼商大神