Java 桌面程序设计经验谈

用 java 写了不少东西了,也积累了一点儿经验,下面就分享一下吧!

1.版本管理

良好的程序不是一蹴而就的,而是一个迭代渐进的过程,所以说对工程做项目管理是必不可少的。

刚学习 java 看的是尚学堂马士兵的视频教程,老马可能是担心小菜菜们接受能力差,所以做版本管理都是 “复制+改名” 的。

这个有点儿坑爹,因为我在后续很长一段时间里都未能摆脱这一团阴影。

“复制+改名”方案让我管理的项目看起来乱起八糟,工作空间下面满是 Game1.0 Game1.1... 这种东西,

现在而言,去整理吧又浪费时间,不整理吧看着又心烦,删除吧又觉得可惜(好歹还是挺有纪念价值的),反正就是各种蛋疼。

在这一点上面,我建议新手把版本管理的概念弄清楚,直接上 svn 或  git,保你受益无穷,省却众多烦恼。


2.自动构建(eclipse 自带的打包工具对引入大外部 jar 包不友好,FatJar 和 Ant 在这方面做了弥补)

这个我用的是 Ant,因为我做 java 开发用的是 eclipse,而 eclipse 天生就对 ant 做了集成。

另外,ant 用来打 jar 包真心很方便,而且打出来的 jar 包结构清晰,自己在内心里会很有掌控感。

以前经验不足的时候用的是 FatJar,后来学会使用 Ant 以后就没再用它了,完全不是一个档次的东西。

还有最重要的一点,Ant 使用简单方便,一旦掌握,build 文件很容易就能跨工程使用(复制粘贴后修剪一下就能用)。


3.note 文件是必不可少的

note 文件用于配合版本管理软件,以日前开头,对程序新增功能,修正bug,设计构想,都可以记录在里面。

好处就是,即使你很久都没有接触这个工程,也能很快地熟悉回来,这对一个需要长期维护和升级的工程而言是非常重要的。

据我所知,很多 c/c++ 库都是这么做的,大多数情况下你都能找到一个类似 README 的文本文件,这个文件记录了库开发的来龙去脉。


4.合理统一的工程目录结构

我的工程大抵是遵循这样一种结构(工程根目录下):

目录:src(源码),

目录:tests(与工程主题相关的代码示例,api 测试我会集中放在这个 source folder 里面),

目录:bin(编译生成的 class),

目录:libs(依赖的jar 包全丢里面),

目录:notes(有用的文本资料我全丢里面),

目录:snapshots(如果是桌面应用,把程序长什么样截个图放里面,这看起来不错)

文件:build.properties(ant 生成文件所依赖的一些变动常量我回抽离出来放在属性文件中)

文件:build.xml(ant 生成文件)

文件:README.md(用过 github 的人都会懂的)


5.真实地 “跨平台”

Java 的可执行文件是能够跨平台的,但具体实施起来也还是有诸多要注意的地方。

譬如说 mouseDragged 事件,在windows 下无论你按哪个鼠标键,取 e.getButton(),它的值都为 0,

但是在 OS X 系统下面,则能够区分出到底按下的是哪个键(左键1,中键2,右键3)。

另外,mac 和 windows 中窗口的标题栏和边框栏的厚度是不一致的,有时候会给开发带来一些麻烦,

如何避免这个问题?下面给一种解决方案(自识别系统类型,区分地定义标题栏和边框栏的厚度):

package org.bruce.locator.config;

import java.awt.event.KeyEvent;

/**
 * @author kodeyang
 * 自识别系统类型,区分地定义标题栏和边框栏的厚度
 */
public class Config {
	
	// 操作系统名
	public static final String OS_NAME;
	// windows
	public static final String WINDOWS = "Windows";
	// OS X
	public static final String MAC_OS_X = "Mac OS X";
	
	// 辅助键~
	public static final int ASIST_KEY;
	// 窗口标题栏的高度
	public static final int JFRAME_TITLE_HEIGHT;
	// 窗口除标题栏外其他边框的宽度
	public static final int JFRAME_BORDER_WIDTH;
	
	// 根据平台的不同选择相应的参数配置
	static {
		String osName = System.getProperty("os.name");
		if (osName.startsWith(WINDOWS)) {
			// WindowsXP (classic-display-mode)
			System.out.println(WINDOWS);
			OS_NAME = WINDOWS;
			ASIST_KEY = KeyEvent.VK_CONTROL;
			JFRAME_TITLE_HEIGHT = 23;	// 标题栏 + 底部边框的高度和为 27
			JFRAME_BORDER_WIDTH = 4;	// 用放大镜看过,确实是 8 个像素~
		} else if (osName.equals(MAC_OS_X)) {
			// Mac OS X
			System.out.println(MAC_OS_X);
			OS_NAME = MAC_OS_X;
			ASIST_KEY = KeyEvent.VK_META;
			JFRAME_TITLE_HEIGHT = 22;	// 标题栏的高度为 22~
			JFRAME_BORDER_WIDTH = 0;
		} else {
			// windows 是一朵奇葩,其他操作系统沿用 mac 的配置~
			System.out.println("unkown system");
			OS_NAME = "unkown system";
			ASIST_KEY = KeyEvent.VK_CONTROL;
			JFRAME_TITLE_HEIGHT = 22;
			JFRAME_BORDER_WIDTH = 0;
		}
	}
}

6.谨遵 MVC 设计模式,科学合理的分包

这点很重要,网上的资料也很多,就不多做展开了。


7.人性化的细节设计

就拿 “功能的完成提示” 来说,譬如说做一个 GBK->UTF-8 转码的功能(windows 迁移到 mac 时这是必不可少的),

处理完毕之后怎么告知用户呢?以我自身的经验来看,我大致想到了以下三种比较简洁的方案:

一、JOptionPane.showMessageDialog() 弹出对话框;

二、弹出一个呈现为图片文字的不规则窗口,该窗口不能被点击且会在很短的时间内淡出。

三、抖动窗口告知处理已经完成。

以我个人的品味来看,第一种方案不友好(需要手动点击关闭),第二种方案有所增强但稍显麻烦,

第三种方案直观、利索(启发自 qq 聊天窗口的抖动功能)。

以上为例,人性化的设计就是尽可能为用户着想,竭尽可能地方便用户

(这是有回报的,作为一个自娱自乐的码农,“用户” 很可能就是作者自己)。


8.善用 Thread.interrupt() 方法,勇敢地使用 java 多线程。

interrupt() 配合多线程的 sleep(),能获得比较高的效率。

(线程处于闲置状态时,让它睡几天;需要它的时候,就用 interrupt 把它唤醒,用完了以后继续让它睡)。

我之前的博文里面有篇和 ShakeThread 相关的,对该点所陈述的内容不明确的可以去看一下帮助理解。


9.不断累积、改善自己的可重用类。

我的每一个 java 工程里面都有一个叫 *.utils 的包,我会将该工程所用到的可重用类都丢在这个包里面。

诸如 PathUtil(根据文件名(hello.png)获取其完整类路径(/org/bruce/test/res/hello.png),获取可执行 jar 包当前所在的路径),

IOBridge(简化自 commons-io,提供了 文件<->字符串<->流<->字节数组 间的便利转换),

JarUtil(用于更改 jar 包中的文件内容),ImageUtil(用来读取,转换,放缩,获取图片尺寸),CompUtil(方便快捷的使窗口居中) 等等。

可重用类就相当于内功,积累的越多越精炼,功力就越深厚,构建软件就越便利,开发效率就越高。

可重用类不一定要完全是自己写的,看到好而重用性不强的东西,改造之后也能变成属于自己的东西。


10.设计出来的东西不管是自留用还是给别人用,都要把 “使用说明” 这一点做到位

我试过好些方案,比如在 mac 上用富文本格式书写说明,然后导出为 pdf,再将 pdf P 成一张很长的 jpg 图,

在 java 工具中呈现这张 “说明图” 来阐述程序如何使用。分析一下此种方案的利弊:

美观到是挺美观,弊端也比较明显 —— 制作流程复杂且让可执行文件的尺寸大大地增加了。

最近闲暇的时候找到了一种更优的替代方案:

使用说明模块用 JDialog + JScrollPane + JTextPane + setContentType("text/html") + 单例模式来做,

说明文档在 html 编辑器中撰写(csdn 的博文编辑器是个不错的选择),然后将 JTextPane 的内容设置为 html 字符串,

优点很明显:html 保留了文档的丰富格式却让所占据的存储空间少了十倍不止。


11.“可拖拽的画布”

在制作描点、定位工具的时候,可拖拽的画布能极大地扩展零件的摆放空间。


12.善用 AWTEventListener 全局监听

如果能让自己写出来的东西像 photoshop,3dmarks 这些巨头一样具有丰富易用的快捷键,你会不会觉得这是一件很酷的事情?

AWTEventListener 就是来帮我们完成这项艰巨任务的不二之选。

当然凡事有利便有弊,如果处理的不好很容易就会导致一些蛋疼的问题

(在 JTextField 中输入文字时可能不合时宜地触发快捷键功能)。

设置一个bool 类型的标志量放置在 eventDispatched() 方法的靠前部分做拦截是个不错的想法。


你可能感兴趣的:(java)