- 浏览: 308565 次
- 性别:
- 来自: 上海
最新评论
-
橙子hhh:
哪有时间给你去研究!!!大神 你时间多
Java获取网络RSS源并使用SAXParser解析 -
a12345531:
...
InputStream为什么不能被重复读取? -
yizishou:
引用另一方面当串行化这个子类实例时外部类也会被不知不觉的串行化 ...
谈谈Java的匿名内部类 -
zhangpan1207:
...
InputStream为什么不能被重复读取? -
痴呆患者:
不过受教了 ,不过稍稍修改 还是很好用的 。顶
mybatis如何配置使用多个数据源(environment)?
这个话题也是我在程序开发过程中常常会遇到的困惑,程序到底应该设计成什么样子?
诚然,是个程序员都知道程序设计应该要做到低耦合,高复用,高扩展等等。但是怎么设计才能达到这样的程序以及那个度的把握也常常是很困惑的。在我的工作中接触了很多Java程序员,大多数的程序员设计风格都大相径庭,这里暂且不说熟好熟劣,先就我遇到的程序员们分个派别,你属于哪一派呢?
纯属调侃玩笑。
1. 拿来主义派。
特点:要解决一个问题,现在网上或者自己过去的程序找到相应的代码,拿过来改改能用,OK,结束。
好处:效率高。
坏处:如果对代码理解不透彻,可能造成维护上的困难。
2. 纯代码派
特点:写代码从来不写注释,坚持我的程序只有我能懂的编码原则。
好处:保密性高,可以很好的搞晕对手。
坏处:也容易搞晕自己和队友。
3. 复制黏贴派
特点:一模一样的代码到处都是,这一派坚信,即使要改,只要有伟大的IDE,全文替换还是很方便的。
好处:增加代码量,从而有利于提高个人职业生涯的代码行数据。
坏处:可能导致不会用IDE全文替换的队友住院。
4. if else派
特点:这一派逻辑思维极强,将Java语言的流程控制发挥到了极致,如果业务允许,一个三元表达式可以写3000行。
好处:在一段代码内把事情搞定,不用整许多类调来调去。
坏处:容易导致{}就占200行,浪费IDE空间。直接导致队友住院。
5. 接口派
特点:任何类都要写个接口,深谙Java多态的思想。
好处:面向接口编程,扩展性极强。
坏处:写接口也有很多技巧性,设计得不恰当也不见得接口多就是好事,反而导致代码很乱。
6. 工具类派
特点:能用工具类就用工具类,不能用工具类努力也要用工具类。
好处:工具类简单直接,便于阅读。
坏处:首先工具类其本身也有一些缺点,其实工具类不符合面向对象编程的思想,程序很难扩展。
7. 设计过度派
特点:将平生所学都要用尽全力用在实现一个功能上,该用上的设计模式都得用上,各种封装,各种接口。
好处:程序设计的好便于扩展,重用。
坏处:过度的设计可能导致程序更难懂,浪费工作效率,有可能根本就没有你想象的那些扩展场景。
8. 其他派
特点:五花八门
好处:百花齐放
坏处:良莠不齐
其实上面的都是在开玩笑啦。
说实话程序设计还真是一件挺麻烦的事情,自己做一个工具或者软件怎么都好说,自己爱怎么写怎么写。但是当我们处在一个团队中时,很多事情就变得不是那么简单。
一方面团队成员水平高低有限,有的就只看得懂静态类,你整个设计模式他反而看不懂,所以这个时候代码可读性的定义是否就不是我们说的那么简单,是将就团队成员,还是考虑代码的结构和优美,其实都同等重要,我们要做的就是多学习,多提高,尽量懂得Java设计的标准和原则,只要大家都懂得这些标准和原则团队成员之间还是能很好的配合的。
二一方面可能每个团队都有他们自己的一些标准和原则,也要尽量遵守,以便成员之间更好的沟通,以便团队之间更好的协作。
三一方面需求永远是变化的,永远是揣摩不透的,我们只能尽量做到易扩展易重用,但是你永远做不到尽善尽美,举个很极端的例子,你一个模块设计得再好,如果下一次这个功能不用了,再好的代码也得删除。
举个实际的例子,项目中要使用Gson解析工具,实现将对象和Json的互相转换:
【场景1】有的人这个写:
下一次需要使用Gson的时候同样一段代码整上去:
【场景2】有的人认为我得整个方法重用一下,于是就这么写:
【场景3】有的人认为,在我的项目中,其实每一个使用Gson的地方我需要的builder都不一样,都需要设置不同的参数,于是:
当然,我可以将我项目中大多数的builder使用场景构建一个默认的GsonBuilderAttributeSetter于是,GsonCreator类就变成:
【场景4】有的人又认为,在我的项目中,不仅要使用Gson做json的解析,有的地方还需要使用其他的json解析工具,比如Jackson,因为Gson序列化时并不是调用对象的getter方法,这会导致很多不爽。甚至有的地方需要使用json-lib自己解析json。当然了,实际上并不提倡项目里实现一个功能用多种不同的技术,尽量要做到统一,这儿只是为了举例子而举例子,假想的业务需求。可能不大恰当,不管了。总之,就是有的人项目中需要使用不同的第三方工具或者自己写的工具解析Json。那么我就需要自己封装一个接口,以便在项目中统一使用自己封装的接口。
Gson解析方式的实现类,设计成单例。
Jackson解析方式的实现类:
使用方式如下:
很明显,上述的设计是有一个问题的,那就是每一个JsonBuilder的实现内部都可能使用了自己的API,比如GsonBuilder,ObjectMapper,甚至自己用json-lib实现的话也是要使用其特有的API。那么如果我们的接口(如上述)隐藏了内部实现细节,那么意味着接口将不提供方法操作其实现细节,因为接口并不关心实现细节,这就导致了一个问题,那就是我们使用接口无法修改GsonBuilder或者ObjectMapper所设置的属性。以上两个实现都是默认的设置了属性,接口并没有提供方法对其修改,也无法提供,因为接口并不知道你的实现类的一切细节,换句话说就是定义接口的时候你根本不知道用户怎么去实现你的接口,更别说用什么API了。
当然我们可以在我们自己的实现类中暴露自己的一些特有的方法,比如设置GsonBuilder或者ObjectMapper的属性。在使用的时候通过强转成自己的实现类就行设置属性。
【场景5】有的人又认为了,其实项目中只需要一直方式解析json,但是我需要非常灵活的切换,从一种方式换到另一种方式游刃有余。如果是【场景4】的方式,虽然客户端使用还是很简单,但是需要切换的时候还是需要将每一个Gson4JsonBuilder换成ObjectMapper4JsonBuilder,
反之亦然,当然有强大的IDE全文替换也不是什么难事,但是个人觉得这始终不是解决问题的方式。所以再写一个统一的JsonBuilder封装一下就可以了,有一点点代理的意思:
客户端使用:
扯了这么多犊子,从来都没有说哪一种方式好与不好,我的观点是什么方式能够更好的解决你的问题哪种方式就是好的方式。当然,还是那句老话,软件开发设计是一个很灵活的工作,留给程序员的创造空间很大,我一向都认为编码是一项富有想象力,创造力和艺术气息的工作,关键在于我们程序员自己怎么去很好的利用这其中的创造空间,既能很好的解决问题,又能让它变成一项富有乐趣的事情。要做到这一点,唯有不断的提高自己,不断的Coding,不断的总结,不断的问问自己还有还有更好,这是不是最好,这样有什么缺点,这样做是为什么。总之,不断的学习总结交流,不怕不懂,就怕不学,不问,不思考。
所以,我们都应该祝福自己是一个程序员,少吐槽,少抱怨,少自我贬低,每一项工作都有它的乐趣,关键是你自己怎么看,而不是元芳怎么看。
当然没有什么问题。
只是有一点点区别,在外部类直接写静态变量,就意味着该静态变量(也就是该类的实例)会在该类第一次被使用的时候初始化(第一次使用你可能并不是想获取该类的单实例),这样的话就没有延迟加载的效果。
比如:
如果使用静态内部类的话,同理,静态内部类的静态变量也是该静态内部类第一次被使用的时候被初始化,因为我们的静态内部类是private的,所以外部其他类也访问不到,外部类只有在getInstance()的时候会访问静态内部类,然后第一次初始化instance,这样就保证了,instance的初始化发生在外部类第一次getInstance()的时候。
当然,一般情况下一个设计成单例的对象也就值提供静态的getInstance()方法,不会提供像XXOO这样的静态变量或者其他静态方法,所以呢也能保证只要使用该类就只会调用getInstance()方法,就是想获取其单实例,也不存在浪费初始化实例的说法。
另一方面,一般情况下如果我们初始化该类的实例没有特别繁琐和复杂,这也完全可以忽略不计。
所以,大多数情况下,上面的的写法只是一个习惯。一方面很好的保证了多线程安全,只会初始化一个instance,以为它是一个类(静态内部类)的一个静态变量。一方面呢就是上面所说的延迟加载。
当然,还是那句话,这只是编程的习惯问题,直接在外部类写静态变量也没什么问题,甚至在getInstance里面用同步锁实例化也没什么问题,getInstance如果只同步一次,也会有线程安全的问题,但是概率几乎可以忽略。
我的原则是:如果不知道,做不到最好影响也不大。如果知道了,尽量做到更好。
eclipse 也有foreach
这个比较搞笑
还有一派,姑且称之为完美主义派吧。
看见IDE中任何黄色小三角图标(警告)就不爽,喜欢看一片SVN受控的清清爽爽的小图标。
CTRL+SHIFT+O CTRL+SHIFT+F CTRL+S 几个快捷键习惯性不停的敲..
还有很多习惯..
阁下一看就是eclipse派啊,哈哈,idea派表示看不懂啊。
哈哈,import format save
对应idea是ctrl+alt+o, ctrl+alt+L, auto.....
这个比较搞笑
还有一派,姑且称之为完美主义派吧。
看见IDE中任何黄色小三角图标(警告)就不爽,喜欢看一片SVN受控的清清爽爽的小图标。
CTRL+SHIFT+O CTRL+SHIFT+F CTRL+S 几个快捷键习惯性不停的敲..
还有很多习惯..
阁下一看就是eclipse派啊,哈哈,idea派表示看不懂啊。
对,勤快的程序员不是好程序员!!!
这个比较搞笑
还有一派,姑且称之为完美主义派吧。
看见IDE中任何黄色小三角图标(警告)就不爽,喜欢看一片SVN受控的清清爽爽的小图标。
CTRL+SHIFT+O CTRL+SHIFT+F CTRL+S 几个快捷键习惯性不停的敲..
还有很多习惯..
我也有轻微的这方面的强迫症
有的人说黄色的警告又不是错误,不用理会,
我则认为,无缘无故的人家也不会警告你,既然人家都警告你了你还恬不知耻的不管不问,岂不是太不人道了。。。
大家说我是不是有病啊。。。。
我一直以为这样的强迫症比较少,原来同伴大有人在!
关键是要搞清楚warning的含义,有些真可以不用管,或者说是IDE的设计人员根据标准语法来warning的,但实际不用考虑,比如有时候使用泛型。
我也强迫症,看着黄色警告感觉不爽~~
我也有点,大家有没有对现实生活的事物也追求完美啊
这个比较搞笑
还有一派,姑且称之为完美主义派吧。
看见IDE中任何黄色小三角图标(警告)就不爽,喜欢看一片SVN受控的清清爽爽的小图标。
CTRL+SHIFT+O CTRL+SHIFT+F CTRL+S 几个快捷键习惯性不停的敲..
还有很多习惯..
我也有轻微的这方面的强迫症
有的人说黄色的警告又不是错误,不用理会,
我则认为,无缘无故的人家也不会警告你,既然人家都警告你了你还恬不知耻的不管不问,岂不是太不人道了。。。
大家说我是不是有病啊。。。。
我一直以为这样的强迫症比较少,原来同伴大有人在!
关键是要搞清楚warning的含义,有些真可以不用管,或者说是IDE的设计人员根据标准语法来warning的,但实际不用考虑,比如有时候使用泛型。
我也强迫症,看着黄色警告感觉不爽~~
这个比较搞笑
还有一派,姑且称之为完美主义派吧。
看见IDE中任何黄色小三角图标(警告)就不爽,喜欢看一片SVN受控的清清爽爽的小图标。
CTRL+SHIFT+O CTRL+SHIFT+F CTRL+S 几个快捷键习惯性不停的敲..
还有很多习惯..
我也有轻微的这方面的强迫症
有的人说黄色的警告又不是错误,不用理会,
我则认为,无缘无故的人家也不会警告你,既然人家都警告你了你还恬不知耻的不管不问,岂不是太不人道了。。。
大家说我是不是有病啊。。。。
我一直以为这样的强迫症比较少,原来同伴大有人在!
关键是要搞清楚warning的含义,有些真可以不用管,或者说是IDE的设计人员根据标准语法来warning的,但实际不用考虑,比如有时候使用泛型。
这个比较搞笑
还有一派,姑且称之为完美主义派吧。
看见IDE中任何黄色小三角图标(警告)就不爽,喜欢看一片SVN受控的清清爽爽的小图标。
CTRL+SHIFT+O CTRL+SHIFT+F CTRL+S 几个快捷键习惯性不停的敲..
还有很多习惯..
我也有轻微的这方面的强迫症
有的人说黄色的警告又不是错误,不用理会,
我则认为,无缘无故的人家也不会警告你,既然人家都警告你了你还恬不知耻的不管不问,岂不是太不人道了。。。
大家说我是不是有病啊。。。。
我一直以为这样的强迫症比较少,原来同伴大有人在!
这个比较搞笑
还有一派,姑且称之为完美主义派吧。
看见IDE中任何黄色小三角图标(警告)就不爽,喜欢看一片SVN受控的清清爽爽的小图标。
CTRL+SHIFT+O CTRL+SHIFT+F CTRL+S 几个快捷键习惯性不停的敲..
还有很多习惯..
我也有轻微的这方面的强迫症
有的人说黄色的警告又不是错误,不用理会,
我则认为,无缘无故的人家也不会警告你,既然人家都警告你了你还恬不知耻的不管不问,岂不是太不人道了。。。
大家说我是不是有病啊。。。。
我也是这样。。。
这个比较搞笑
还有一派,姑且称之为完美主义派吧。
看见IDE中任何黄色小三角图标(警告)就不爽,喜欢看一片SVN受控的清清爽爽的小图标。
CTRL+SHIFT+O CTRL+SHIFT+F CTRL+S 几个快捷键习惯性不停的敲..
还有很多习惯..
我也有轻微的这方面的强迫症
有的人说黄色的警告又不是错误,不用理会,
我则认为,无缘无故的人家也不会警告你,既然人家都警告你了你还恬不知耻的不管不问,岂不是太不人道了。。。
大家说我是不是有病啊。。。。
这个比较搞笑
还有一派,姑且称之为完美主义派吧。
看见IDE中任何黄色小三角图标(警告)就不爽,喜欢看一片SVN受控的清清爽爽的小图标。
CTRL+SHIFT+O CTRL+SHIFT+F CTRL+S 几个快捷键习惯性不停的敲..
还有很多习惯..
对对,纯属调侃。。。
诚然,是个程序员都知道程序设计应该要做到低耦合,高复用,高扩展等等。但是怎么设计才能达到这样的程序以及那个度的把握也常常是很困惑的。在我的工作中接触了很多Java程序员,大多数的程序员设计风格都大相径庭,这里暂且不说熟好熟劣,先就我遇到的程序员们分个派别,你属于哪一派呢?
纯属调侃玩笑。
1. 拿来主义派。
特点:要解决一个问题,现在网上或者自己过去的程序找到相应的代码,拿过来改改能用,OK,结束。
好处:效率高。
坏处:如果对代码理解不透彻,可能造成维护上的困难。
2. 纯代码派
特点:写代码从来不写注释,坚持我的程序只有我能懂的编码原则。
好处:保密性高,可以很好的搞晕对手。
坏处:也容易搞晕自己和队友。
3. 复制黏贴派
特点:一模一样的代码到处都是,这一派坚信,即使要改,只要有伟大的IDE,全文替换还是很方便的。
好处:增加代码量,从而有利于提高个人职业生涯的代码行数据。
坏处:可能导致不会用IDE全文替换的队友住院。
4. if else派
特点:这一派逻辑思维极强,将Java语言的流程控制发挥到了极致,如果业务允许,一个三元表达式可以写3000行。
好处:在一段代码内把事情搞定,不用整许多类调来调去。
坏处:容易导致{}就占200行,浪费IDE空间。直接导致队友住院。
5. 接口派
特点:任何类都要写个接口,深谙Java多态的思想。
好处:面向接口编程,扩展性极强。
坏处:写接口也有很多技巧性,设计得不恰当也不见得接口多就是好事,反而导致代码很乱。
6. 工具类派
特点:能用工具类就用工具类,不能用工具类努力也要用工具类。
好处:工具类简单直接,便于阅读。
坏处:首先工具类其本身也有一些缺点,其实工具类不符合面向对象编程的思想,程序很难扩展。
7. 设计过度派
特点:将平生所学都要用尽全力用在实现一个功能上,该用上的设计模式都得用上,各种封装,各种接口。
好处:程序设计的好便于扩展,重用。
坏处:过度的设计可能导致程序更难懂,浪费工作效率,有可能根本就没有你想象的那些扩展场景。
8. 其他派
特点:五花八门
好处:百花齐放
坏处:良莠不齐
其实上面的都是在开玩笑啦。
说实话程序设计还真是一件挺麻烦的事情,自己做一个工具或者软件怎么都好说,自己爱怎么写怎么写。但是当我们处在一个团队中时,很多事情就变得不是那么简单。
一方面团队成员水平高低有限,有的就只看得懂静态类,你整个设计模式他反而看不懂,所以这个时候代码可读性的定义是否就不是我们说的那么简单,是将就团队成员,还是考虑代码的结构和优美,其实都同等重要,我们要做的就是多学习,多提高,尽量懂得Java设计的标准和原则,只要大家都懂得这些标准和原则团队成员之间还是能很好的配合的。
二一方面可能每个团队都有他们自己的一些标准和原则,也要尽量遵守,以便成员之间更好的沟通,以便团队之间更好的协作。
三一方面需求永远是变化的,永远是揣摩不透的,我们只能尽量做到易扩展易重用,但是你永远做不到尽善尽美,举个很极端的例子,你一个模块设计得再好,如果下一次这个功能不用了,再好的代码也得删除。
举个实际的例子,项目中要使用Gson解析工具,实现将对象和Json的互相转换:
【场景1】有的人这个写:
//GsonBuilder采用的就是建造者模式 GsonBuilder builder = new GsonBuilder(); //设置builder的很多属性 builder.setDateFormat("yyyy-MM-dd"); Gson gson = builder.create(); String json = gson.toJson(obj);
下一次需要使用Gson的时候同样一段代码整上去:
GsonBuilder builder = new GsonBuilder(); builder.setDateFormat("yyyy-MM-dd"); Gson gson = builder.create(); String json = gson.toJson(obj);
【场景2】有的人认为我得整个方法重用一下,于是就这么写:
//静态方法获取Gson public class GsonCreator { public static Gson createGson() { GsonBuilder builder = new GsonBuilder(); builder.setDateFormat("yyyy-MM-dd"); Gson gson = builder.create(); return gson; } } //使用 Gson gson = GsonCreator.createGson(); String json = gson.toJson(obj); //再次使用 Gson gson = createGson(); String json = gson.toJson(obj);
【场景3】有的人认为,在我的项目中,其实每一个使用Gson的地方我需要的builder都不一样,都需要设置不同的参数,于是:
public class GsonCreator { public static Gson createGson(GsonBuilderAttributeSetter gsonBuilderAttributeSetter) { GsonBuilder builder = new GsonBuilder(); gsonBuilderAttributeSetter.setAttribute(builder); Gson gson = builder.create(); return gson; } public static interface GsonBuilderAttributeSetter { public void setAttribute(GsonBuilder gsonBuilder); } } //使用的时候 Gson gson = GsonCreator.createGson(new GsonBuilderAttributeSetter() { public void setAttribute(GsonBuilder gsonBuilder) { gsonBuilder.setDateFormat("yyyy-MM-dd"); gsonBuilder.setPrettyPrinting(); } }); String json = gson.toJson(obj);
当然,我可以将我项目中大多数的builder使用场景构建一个默认的GsonBuilderAttributeSetter于是,GsonCreator类就变成:
public class GsonCreator { //需要使用的时候自己设置GsonBuilder属性 public static Gson createGson(GsonBuilderAttributeSetter gsonBuilderAttributeSetter) { GsonBuilder builder = new GsonBuilder(); gsonBuilderAttributeSetter.setAttribute(builder); Gson gson = builder.create(); return gson; } //重写一个无参的createGson方法,使用默认的GsonBuilderAttributeSetter public static Gson createGson() { return createGson(new DefaultGsonBuilderAttributeSetter()); } public static interface GsonBuilderAttributeSetter { public void setAttribute(GsonBuilder gsonBuilder); } //默认的GsonBuilderAttributeSetter public static class DefaultGsonBuilderAttributeSetter implements GsonBuilderAttributeSetter { public void setAttribute(GsonBuilder gsonBuilder) { if (null == gsonBuilder) return; gsonBuilder.setDateFormat("yyyy-MM-dd"); } } } //如果使用默认的GsonBuilderAttributeSetter的使用场景 Gson gson = GsonCreator.createGson(); String json = gson.toJson(obj);
【场景4】有的人又认为,在我的项目中,不仅要使用Gson做json的解析,有的地方还需要使用其他的json解析工具,比如Jackson,因为Gson序列化时并不是调用对象的getter方法,这会导致很多不爽。甚至有的地方需要使用json-lib自己解析json。当然了,实际上并不提倡项目里实现一个功能用多种不同的技术,尽量要做到统一,这儿只是为了举例子而举例子,假想的业务需求。可能不大恰当,不管了。总之,就是有的人项目中需要使用不同的第三方工具或者自己写的工具解析Json。那么我就需要自己封装一个接口,以便在项目中统一使用自己封装的接口。
//自定义解析接口,简单起见就没有提供别的方法 public interface JsonBuilder { /** * 将一个Object对象转换成json字符串 */ public String toJson(Object object); /** * 将一个json字符串转换成指定Class类型的对象 */ public <T> T toObject(String json, Class<T> clazz); }
Gson解析方式的实现类,设计成单例。
public class Gson4JsonBuilder implements JsonBuilder { //私有构造方法 private Gson4JsonBuilder() {} /** * 获取单实例 */ public static JsonBuilder getInstance() { return Gson4JsonBuilderGenerateor.JSON_BUILDER; } public String toJson(Object object) { return gson().toJson(object); } public <T> T toObject(String json, Class<T> clazz) { return gson().fromJson(json, clazz); } //新建一个Gson 基于GsonBuilder private static Gson gson() { return new GsonBuilder().setDateFormat("MM/dd/yyyy HH:mm:ss").create(); } //静态内部类产生单例实例 private static class Gson4JsonBuilderGenerateor { private final static JsonBuilder JSON_BUILDER = new Gson4JsonBuilder(); } }
Jackson解析方式的实现类:
public class ObjectMapper4JsonBuilder implements JsonBuilder { private static final org.slf4j.Logger logger = org.slf4j.LoggerFactory.getLogger(ObjectMapper4JsonBuilder.class); private ObjectMapper objectMapper; //私有构造方法 private ObjectMapper4JsonBuilder() { objectMapper = new ObjectMapper(); objectMapper.configure(JsonParser.Feature.ALLOW_SINGLE_QUOTES, true); objectMapper.disable(DeserializationConfig.Feature.FAIL_ON_UNKNOWN_PROPERTIES); objectMapper.configure(SerializationConfig.Feature.WRITE_DATES_AS_TIMESTAMPS, false);//关闭时间戳输出,此时是ISO格式 objectMapper.setDateFormat(new SimpleDateFormat("MM/dd/yyyy HH:mm:ss"));//设置自己的格式 } public String toJson(Object object) { try { return objectMapper.writeValueAsString(object); } catch (Exception e) { logger.error(e.getMessage(), e); } return null; } public <T> T toObject(String json, Class<T> clazz) { try { return objectMapper.readValue(json, clazz); } catch (Exception e) { logger.error(e.getMessage(), e); } return null; } /** * 获取单实例 */ public static JsonBuilder getInstance() { return ObjectMapper4JsonBuilderGenerateor.JSON_BUILDER; } //静态内部类产生单例实例 private static class ObjectMapper4JsonBuilderGenerateor { private final static JsonBuilder JSON_BUILDER = new ObjectMapper4JsonBuilder(); }
使用方式如下:
//使用Gson解析 String json = Gson4JsonBuilder.getInstance().toJson(obj); //使用Jackson解析 String json = ObjectMapper4JsonBuilder.getInstance().toJson(obj);
很明显,上述的设计是有一个问题的,那就是每一个JsonBuilder的实现内部都可能使用了自己的API,比如GsonBuilder,ObjectMapper,甚至自己用json-lib实现的话也是要使用其特有的API。那么如果我们的接口(如上述)隐藏了内部实现细节,那么意味着接口将不提供方法操作其实现细节,因为接口并不关心实现细节,这就导致了一个问题,那就是我们使用接口无法修改GsonBuilder或者ObjectMapper所设置的属性。以上两个实现都是默认的设置了属性,接口并没有提供方法对其修改,也无法提供,因为接口并不知道你的实现类的一切细节,换句话说就是定义接口的时候你根本不知道用户怎么去实现你的接口,更别说用什么API了。
当然我们可以在我们自己的实现类中暴露自己的一些特有的方法,比如设置GsonBuilder或者ObjectMapper的属性。在使用的时候通过强转成自己的实现类就行设置属性。
【场景5】有的人又认为了,其实项目中只需要一直方式解析json,但是我需要非常灵活的切换,从一种方式换到另一种方式游刃有余。如果是【场景4】的方式,虽然客户端使用还是很简单,但是需要切换的时候还是需要将每一个Gson4JsonBuilder换成ObjectMapper4JsonBuilder,
反之亦然,当然有强大的IDE全文替换也不是什么难事,但是个人觉得这始终不是解决问题的方式。所以再写一个统一的JsonBuilder封装一下就可以了,有一点点代理的意思:
public final class JsonBuilderExecutor implements JsonBuilder { //使用指定的JsonBuilder,要切换就换一种实现方式,客户端调用不用变化 private JsonBuilder jsonBuilder = ObjectMapper4JsonBuilder.getInstance(); private JsonBuilderExecutor() {} public String toJson(Object object) { return jsonBuilder.toJson(object); } public <T> T toObject(String json, Class<T> clazz) { return jsonBuilder.toObject(json, clazz); } private static class JsonExecutorGenerateor { private final static JsonBuilder JSON_BUILDER = new JsonBuilderExecutor(); } public static JsonBuilder getInstance() { return JsonExecutorGenerateor.JSON_BUILDER; }
客户端使用:
String json = JsonBuilderExecutor.getInstance().toJson(obj);
扯了这么多犊子,从来都没有说哪一种方式好与不好,我的观点是什么方式能够更好的解决你的问题哪种方式就是好的方式。当然,还是那句老话,软件开发设计是一个很灵活的工作,留给程序员的创造空间很大,我一向都认为编码是一项富有想象力,创造力和艺术气息的工作,关键在于我们程序员自己怎么去很好的利用这其中的创造空间,既能很好的解决问题,又能让它变成一项富有乐趣的事情。要做到这一点,唯有不断的提高自己,不断的Coding,不断的总结,不断的问问自己还有还有更好,这是不是最好,这样有什么缺点,这样做是为什么。总之,不断的学习总结交流,不怕不懂,就怕不学,不问,不思考。
所以,我们都应该祝福自己是一个程序员,少吐槽,少抱怨,少自我贬低,每一项工作都有它的乐趣,关键是你自己怎么看,而不是元芳怎么看。
- json.zip (3.9 KB)
- 下载次数: 8
评论
28 楼
该用户名已经存在
2014-03-28
panduozhi 写道
请教个问题
//静态内部类产生单例实例
private static class ObjectMapper4JsonBuilderGenerateor {
private final static JsonBuilder JSON_BUILDER = new ObjectMapper4JsonBuilder();
}
为什么要用静态内部类产生单例实例,在外部类直接写一个静态变量有什么问题吗?
//静态内部类产生单例实例
private static class ObjectMapper4JsonBuilderGenerateor {
private final static JsonBuilder JSON_BUILDER = new ObjectMapper4JsonBuilder();
}
为什么要用静态内部类产生单例实例,在外部类直接写一个静态变量有什么问题吗?
当然没有什么问题。
只是有一点点区别,在外部类直接写静态变量,就意味着该静态变量(也就是该类的实例)会在该类第一次被使用的时候初始化(第一次使用你可能并不是想获取该类的单实例),这样的话就没有延迟加载的效果。
比如:
public class Single { public final static Single instance = new Single(); //在外部调用Single.XXOO的时候,也会初始化instance,如果instance的初始化 //很耗时的话,这可能会造成浪费 public final static String XXOO = "xxoo"; public static Single getInstance() { return instance; } }
如果使用静态内部类的话,同理,静态内部类的静态变量也是该静态内部类第一次被使用的时候被初始化,因为我们的静态内部类是private的,所以外部其他类也访问不到,外部类只有在getInstance()的时候会访问静态内部类,然后第一次初始化instance,这样就保证了,instance的初始化发生在外部类第一次getInstance()的时候。
当然,一般情况下一个设计成单例的对象也就值提供静态的getInstance()方法,不会提供像XXOO这样的静态变量或者其他静态方法,所以呢也能保证只要使用该类就只会调用getInstance()方法,就是想获取其单实例,也不存在浪费初始化实例的说法。
另一方面,一般情况下如果我们初始化该类的实例没有特别繁琐和复杂,这也完全可以忽略不计。
所以,大多数情况下,上面的的写法只是一个习惯。一方面很好的保证了多线程安全,只会初始化一个instance,以为它是一个类(静态内部类)的一个静态变量。一方面呢就是上面所说的延迟加载。
当然,还是那句话,这只是编程的习惯问题,直接在外部类写静态变量也没什么问题,甚至在getInstance里面用同步锁实例化也没什么问题,getInstance如果只同步一次,也会有线程安全的问题,但是概率几乎可以忽略。
我的原则是:如果不知道,做不到最好影响也不大。如果知道了,尽量做到更好。
27 楼
panduozhi
2014-03-27
请教个问题
//静态内部类产生单例实例
private static class ObjectMapper4JsonBuilderGenerateor {
private final static JsonBuilder JSON_BUILDER = new ObjectMapper4JsonBuilder();
}
为什么要用静态内部类产生单例实例,在外部类直接写一个静态变量有什么问题吗?
//静态内部类产生单例实例
private static class ObjectMapper4JsonBuilderGenerateor {
private final static JsonBuilder JSON_BUILDER = new ObjectMapper4JsonBuilder();
}
为什么要用静态内部类产生单例实例,在外部类直接写一个静态变量有什么问题吗?
26 楼
walkaka
2014-03-26
white_crucifix 写道
不断的去优化出现黄色警告的地方,能不用规避警告的注解就尽量不要用,才能让代码越来越严谨。
以前玩eclipse,后来玩intelliJ,发现做的更好,不仅对简单语法有优化提醒,对诸如写的冗余的for循环都能智能优化为foreach等等。无论如何,代码质量就是一点一滴提高的。
以前玩eclipse,后来玩intelliJ,发现做的更好,不仅对简单语法有优化提醒,对诸如写的冗余的for循环都能智能优化为foreach等等。无论如何,代码质量就是一点一滴提高的。
eclipse 也有foreach
25 楼
JonathanWang
2014-03-26
对于第4条,大家有没有好的文章推荐一下?我已经被送进医院一次了
24 楼
white_crucifix
2014-03-26
yidao620c 写道
sswh 写道
引用
2. 纯代码派
好处:保密性高,可以很好的搞晕对手。
好处:保密性高,可以很好的搞晕对手。
这个比较搞笑
还有一派,姑且称之为完美主义派吧。
看见IDE中任何黄色小三角图标(警告)就不爽,喜欢看一片SVN受控的清清爽爽的小图标。
CTRL+SHIFT+O CTRL+SHIFT+F CTRL+S 几个快捷键习惯性不停的敲..
还有很多习惯..
阁下一看就是eclipse派啊,哈哈,idea派表示看不懂啊。
哈哈,import format save
对应idea是ctrl+alt+o, ctrl+alt+L, auto.....
23 楼
yidao620c
2014-03-26
sswh 写道
引用
2. 纯代码派
好处:保密性高,可以很好的搞晕对手。
好处:保密性高,可以很好的搞晕对手。
这个比较搞笑
还有一派,姑且称之为完美主义派吧。
看见IDE中任何黄色小三角图标(警告)就不爽,喜欢看一片SVN受控的清清爽爽的小图标。
CTRL+SHIFT+O CTRL+SHIFT+F CTRL+S 几个快捷键习惯性不停的敲..
还有很多习惯..
阁下一看就是eclipse派啊,哈哈,idea派表示看不懂啊。
22 楼
leobluewing
2014-03-26
写的不错,所以这个世界上才有"重构"这个词。
21 楼
white_crucifix
2014-03-26
不断的去优化出现黄色警告的地方,能不用规避警告的注解就尽量不要用,才能让代码越来越严谨。
以前玩eclipse,后来玩intelliJ,发现做的更好,不仅对简单语法有优化提醒,对诸如写的冗余的for循环都能智能优化为foreach等等。无论如何,代码质量就是一点一滴提高的。
以前玩eclipse,后来玩intelliJ,发现做的更好,不仅对简单语法有优化提醒,对诸如写的冗余的for循环都能智能优化为foreach等等。无论如何,代码质量就是一点一滴提高的。
20 楼
pml346680914
2014-03-26
例子不错,值得学习。
19 楼
该用户名已经存在
2014-03-26
nick.s.ni 写道
1.拿來主义,当拿来不适用,出第2、3、4招,先把功能完成,功能完成之后,再用后面几招调整代码,主要不是节俭,可以在修改代码的时候调整,把重复的代码提到一起,还是为了偷懒
对,勤快的程序员不是好程序员!!!
18 楼
nick.s.ni
2014-03-26
1.拿來主义,当拿来不适用,出第2、3、4招,先把功能完成,功能完成之后,再用后面几招调整代码,主要不是节俭,可以在修改代码的时候调整,把重复的代码提到一起,还是为了偷懒
17 楼
forchase
2014-03-26
leixbo 写道
JonathanWang 写道
alding123 写道
该用户名已经存在 写道
sswh 写道
引用
2. 纯代码派
好处:保密性高,可以很好的搞晕对手。
好处:保密性高,可以很好的搞晕对手。
这个比较搞笑
还有一派,姑且称之为完美主义派吧。
看见IDE中任何黄色小三角图标(警告)就不爽,喜欢看一片SVN受控的清清爽爽的小图标。
CTRL+SHIFT+O CTRL+SHIFT+F CTRL+S 几个快捷键习惯性不停的敲..
还有很多习惯..
我也有轻微的这方面的强迫症
有的人说黄色的警告又不是错误,不用理会,
我则认为,无缘无故的人家也不会警告你,既然人家都警告你了你还恬不知耻的不管不问,岂不是太不人道了。。。
大家说我是不是有病啊。。。。
我一直以为这样的强迫症比较少,原来同伴大有人在!
关键是要搞清楚warning的含义,有些真可以不用管,或者说是IDE的设计人员根据标准语法来warning的,但实际不用考虑,比如有时候使用泛型。
我也强迫症,看着黄色警告感觉不爽~~
我也有点,大家有没有对现实生活的事物也追求完美啊
16 楼
leixbo
2014-03-25
JonathanWang 写道
alding123 写道
该用户名已经存在 写道
sswh 写道
引用
2. 纯代码派
好处:保密性高,可以很好的搞晕对手。
好处:保密性高,可以很好的搞晕对手。
这个比较搞笑
还有一派,姑且称之为完美主义派吧。
看见IDE中任何黄色小三角图标(警告)就不爽,喜欢看一片SVN受控的清清爽爽的小图标。
CTRL+SHIFT+O CTRL+SHIFT+F CTRL+S 几个快捷键习惯性不停的敲..
还有很多习惯..
我也有轻微的这方面的强迫症
有的人说黄色的警告又不是错误,不用理会,
我则认为,无缘无故的人家也不会警告你,既然人家都警告你了你还恬不知耻的不管不问,岂不是太不人道了。。。
大家说我是不是有病啊。。。。
我一直以为这样的强迫症比较少,原来同伴大有人在!
关键是要搞清楚warning的含义,有些真可以不用管,或者说是IDE的设计人员根据标准语法来warning的,但实际不用考虑,比如有时候使用泛型。
我也强迫症,看着黄色警告感觉不爽~~
15 楼
JonathanWang
2014-03-25
alding123 写道
该用户名已经存在 写道
sswh 写道
引用
2. 纯代码派
好处:保密性高,可以很好的搞晕对手。
好处:保密性高,可以很好的搞晕对手。
这个比较搞笑
还有一派,姑且称之为完美主义派吧。
看见IDE中任何黄色小三角图标(警告)就不爽,喜欢看一片SVN受控的清清爽爽的小图标。
CTRL+SHIFT+O CTRL+SHIFT+F CTRL+S 几个快捷键习惯性不停的敲..
还有很多习惯..
我也有轻微的这方面的强迫症
有的人说黄色的警告又不是错误,不用理会,
我则认为,无缘无故的人家也不会警告你,既然人家都警告你了你还恬不知耻的不管不问,岂不是太不人道了。。。
大家说我是不是有病啊。。。。
我一直以为这样的强迫症比较少,原来同伴大有人在!
关键是要搞清楚warning的含义,有些真可以不用管,或者说是IDE的设计人员根据标准语法来warning的,但实际不用考虑,比如有时候使用泛型。
14 楼
alding123
2014-03-25
该用户名已经存在 写道
sswh 写道
引用
2. 纯代码派
好处:保密性高,可以很好的搞晕对手。
好处:保密性高,可以很好的搞晕对手。
这个比较搞笑
还有一派,姑且称之为完美主义派吧。
看见IDE中任何黄色小三角图标(警告)就不爽,喜欢看一片SVN受控的清清爽爽的小图标。
CTRL+SHIFT+O CTRL+SHIFT+F CTRL+S 几个快捷键习惯性不停的敲..
还有很多习惯..
我也有轻微的这方面的强迫症
有的人说黄色的警告又不是错误,不用理会,
我则认为,无缘无故的人家也不会警告你,既然人家都警告你了你还恬不知耻的不管不问,岂不是太不人道了。。。
大家说我是不是有病啊。。。。
我一直以为这样的强迫症比较少,原来同伴大有人在!
13 楼
chaipenghui
2014-03-25
12 楼
loogson
2014-03-25
该用户名已经存在 写道
sswh 写道
引用
2. 纯代码派
好处:保密性高,可以很好的搞晕对手。
好处:保密性高,可以很好的搞晕对手。
这个比较搞笑
还有一派,姑且称之为完美主义派吧。
看见IDE中任何黄色小三角图标(警告)就不爽,喜欢看一片SVN受控的清清爽爽的小图标。
CTRL+SHIFT+O CTRL+SHIFT+F CTRL+S 几个快捷键习惯性不停的敲..
还有很多习惯..
我也有轻微的这方面的强迫症
有的人说黄色的警告又不是错误,不用理会,
我则认为,无缘无故的人家也不会警告你,既然人家都警告你了你还恬不知耻的不管不问,岂不是太不人道了。。。
大家说我是不是有病啊。。。。
我也是这样。。。
11 楼
该用户名已经存在
2014-03-25
sswh 写道
引用
2. 纯代码派
好处:保密性高,可以很好的搞晕对手。
好处:保密性高,可以很好的搞晕对手。
这个比较搞笑
还有一派,姑且称之为完美主义派吧。
看见IDE中任何黄色小三角图标(警告)就不爽,喜欢看一片SVN受控的清清爽爽的小图标。
CTRL+SHIFT+O CTRL+SHIFT+F CTRL+S 几个快捷键习惯性不停的敲..
还有很多习惯..
我也有轻微的这方面的强迫症
有的人说黄色的警告又不是错误,不用理会,
我则认为,无缘无故的人家也不会警告你,既然人家都警告你了你还恬不知耻的不管不问,岂不是太不人道了。。。
大家说我是不是有病啊。。。。
10 楼
sswh
2014-03-25
引用
2. 纯代码派
好处:保密性高,可以很好的搞晕对手。
好处:保密性高,可以很好的搞晕对手。
这个比较搞笑
还有一派,姑且称之为完美主义派吧。
看见IDE中任何黄色小三角图标(警告)就不爽,喜欢看一片SVN受控的清清爽爽的小图标。
CTRL+SHIFT+O CTRL+SHIFT+F CTRL+S 几个快捷键习惯性不停的敲..
还有很多习惯..
9 楼
该用户名已经存在
2014-03-25
小鱼不爱水 写道
if else,但没楼主那么夸张,我一般能抽出来的都抽出来写,要不非得让二次开发的人进医院
对对,纯属调侃。。。
发表评论
-
mybatis如何配置使用多个数据源(environment)?
2014-04-22 23:57 63732mybatis如何配置使用多个数据源? 一、数据库连接prop ... -
Java获取网络RSS源并使用SAXParser解析
2014-04-02 15:48 12371最近在项目中有一个需 ... -
封装使用HttpClient客户端
2014-04-02 14:33 5915HttpClient 是 Apache Jakarta Com ... -
Java 删除html文本中的注释内容
2014-04-01 21:07 3538最近项目中有一个功能 ... -
Java删除html文本中的注释内容
2014-04-01 21:05 2最近项目中有一个功能 ... -
谈谈ThreadLocal和解决线程安全的关系
2014-03-11 02:55 24038在这篇文章中我粗略的就我的理解谈了一下ThreadLocal。 ... -
另一个角度理解java的ThreadLocal
2014-03-09 15:10 7716关于Java的ThreadLocal网上 ... -
谈谈Java的匿名内部类
2014-02-26 23:50 21757在很多时候,我们需要 ... -
通过mark和reset方法重复利用InputStream
2014-02-26 00:24 39912在这篇博客中我们已经 ... -
重复读取InputStream的方法
2014-02-25 23:14 22068在这篇博客中我们已经知道了Java的InputStream是不 ... -
InputStream为什么不能被重复读取?
2014-02-25 21:45 13736首先,熟悉Java的人可能 ...
相关推荐
在设计程序时,存在多种竞争的设计流派,这些流派往往与特定的编程语言集合相关联。由于Java是一种面向对象的编程语言,因此,教授Java的人应该强调面向对象的设计方法。Felleisen和Friedman展示了通过功能驱动的...
高质量的 J2EE/Java EE 系统标准实际就是 OO 设计的标准,松耦合是 OO 设计的主要追求目标之一,那么无疑解耦性成为衡量 J2EE/JEE 质量的首要标准。实际选择中,还需要兼顾可伸缩性/性能/开发效率等方面综合考虑。 ...
其他可能的文件包括应用程序的jar文件(Java Archive),这是Java程序的主要组成部分,以及资源文件如图片、音频和配置文件等。用户在解压后,按照提示步骤运行安装程序即可在电脑上安装并使用天天动听 PC Java ...
项目不仅适合作为计算机专业学生的毕业设计,也适合Java学习者进行实战练习。 在技术栈方面,后端采用了Spring框架来管理业务逻辑和依赖注入,SpringMVC用于处理Web请求,而MyBatis则负责数据库操作。这种组合确保...
Java播放器是一种基于Java编程语言开发的多媒体播放软件,它允许用户在计算机上播放音频和视频文件。Java作为跨平台的编程语言,使得Java播放器能在多种操作系统上运行,包括Windows、Mac OS以及Linux等。这使得Java...
“工具”一词在这里可能是泛指各种帮助开发者或用户完成特定任务的软件或程序,包括编程工具、设计工具、版本控制工具等。 而“经典古文学.xlsx”这个文件名,根据其扩展名.xlsx,我们可以推断这是一个Excel电子...
Java语言的稳定性与可靠性,以及开发中精心设计的测试环节,为这款工具的实用性提供了坚实保障。对于那些对音乐管理和欣赏有高要求的用户来说,Mp3_java_forthy1c_无疑是一个不可多得的好帮手。
该压缩包文件“实用的音乐软件微信小程序的设计与开发源码.zip”包含了关于构建一个实际应用的音乐软件微信小程序的相关资源。以下是对其中涉及的主要知识点的详细解释: 1. **微信小程序开发**:微信小程序是一种...
基于SSM框架的音乐播放器是一个旨在提供在线音乐播放和管理功能的Java项目。结合了后端的SSM(Spring+Spring MVC+MyBatis)框架和前端的Vue.js技术,该系统实现了音乐资源的上传、管理、在线播放以及用户个性化推荐...
最后,作为JAVA程序,Automatizacion_Directorios利用了JAVA的跨平台特性,可以在Windows、Mac OS X或Linux等操作系统上运行。这使得用户无需担心平台兼容性问题,只需确保系统安装了Java运行环境(JRE)即可。 总...
音乐格里莫尔是一个专为音乐爱好者设计的Java程序,它提供了强大的功能,让用户能够方便地管理自己的音乐收藏。这个程序的核心目标是帮助用户记录他们所拥有的音乐,包括专辑、艺术家、歌曲等详细信息,从而让音乐...
【基于Java实现的音乐推荐系统】是一个以Java编程语言为核心技术构建的应用程序,它旨在为用户提供个性化的音乐推荐服务。这个系统背后的核心理念是利用数据挖掘、机器学习以及算法优化来理解用户的音乐偏好,从而...
【标题】"yinxiangdian(java).rar" 是一个基于Java编程语言开发的网上音像店管理系统,主要用于管理CD的销售与会员服务。这个系统涵盖了基础的会员管理功能和CD库存管理功能,提供了图形用户界面(GUI)以便用户更...
【音乐播放器微信小程序】是一个综合性的项目,它...总结来说,"音乐播放器微信小程序"项目涵盖了前后端开发、数据库设计、API接口设计、用户体验等多个方面,是全面实践和学习现代互联网应用开发技术的一个良好案例。
SerapeumLibrary是一个基于Java开发的应用程序,专为管理个人书籍、电影和音乐收藏而设计。作为一个高效且用户友好的工具,它允许用户轻松地组织和跟踪他们的媒体库,同时提供了一种便捷的方式去监控借用情况,确保...
通过这款小程序,用户可以欣赏到丰富多样的戏曲剧目,包括京剧、豫剧、越剧等经典流派。项目主要功能涵盖戏曲剧目展示、精彩片段点播、戏曲知识普及以及在线互动交流等,为用户提供了一个全方位的戏曲文化体验平台。...
这篇毕业设计论文主要探讨了如何构建一个基于JSP(JavaServer Pages)和Servlet技术的音乐网站。这是一个典型的Web应用程序开发项目,旨在展示如何利用Java技术栈来实现动态网页功能,提供用户友好的音乐资源访问和...
Ajou大学的面向对象程序设计项目。 (2015年) 使用 语言:Java 项目目标 该项目是基于这样的思想而开发的:数字音乐文件不仅应该给听音乐带来乐趣,而且应该给听音乐带来乐趣。 用户可以轻松地整理各种音乐文件的...