如何提高代码质量4

近日有人问起,“你认为如何能提高代码的质量”,虽然都说出来了,但缺乏条理,特总结于此。

首先,应明确什么样的代码算是质量高的。然后才能知道如何去做。

我觉得,高质量的代码应该至少包括:

1.可读性。

2.可维护性。

代码的可读性同样有助于代码的可维护性。有时候在一个项目里,你修改的代码未必是自己写的,如果代码写的可读性很差,那将是非常痛苦的。

一、可读性

1.包名、类名、成员变量名、方法名、局部变量名等的命名应仔细斟酌。尽量做到读一段代码,就像是读一句话一样,在阅读的过程中就能理解其中的逻辑。

2.包下面应包含哪些类,这也是有讲究的。不能太随意。从包中应该可以大概看出类的功能或所在层次。

3.一个方法只要实现一个功能。这一点很重要,首先利于阅读,方法的名字可以告诉你它的功能。

4.方法的实现不宜过长,个人写代码的习惯是,一个方法的长度不会超过电脑的一屏。也就是不用拖动滚动条便可把实现尽收眼底。

二、可维护性

1.代码写的要灵活,尤其是一些配置文件。比如写一个下载程序,文件的放置路径就不能在代码中写死。因为一来以后要变动的话,还要来改程序,并重新部署;二来开发的环境与正式的环境有所不同,写死也不利于部署。

最典型的例子就是数据库的连接信息,url、用户名、密码等,开发环境与正式环境一般不会相同,把这些信息写在配置文件里为好。

2.提高的代码复用,以提高代码的维护性。

举个反例吧。我们的系统中有很多生成Excel文件并在浏览器端下载的功能要求,由于这些功能由不同的人来完成,结果类似的程序写了二十几份,都是互相拷贝而来。

当时我们用的是POI的低版本,后来进行了POI的升级,有一些API不能使用了,于是改了二十几个类。如果把这些功能复用一些,也许只要修改一个类文件就搞定了。

3.多用一些设计模式,提高代码的层次感。使得修改代码的时候,影响范围达到尽量的小。这个就有难度了。平时要慢慢积累才行。

常用的模式 工厂模式、模板模式、适配器模式、策略模式、代理模式(动态代理) 等。这些模式在平时的工作中经常用到,应该熟练运用才行。

下面是一些代码片段:

1 private void checkJob(JobConfig job) {  
2    JobConfig original = find(job);  
3    if (original != null) { // 已存在的任务 进行替换  
4        if (original.equals(job)) { // 任务没有变更  
5        }
else if (replace(original, job)) { // 替换作业成功 则加入到新作业列表中  
6            allJobs.remove(original);  
7        }
  
8    }
else if (schedule(job)) { // 新添加的任务  
9        log.info(Log4jHelper.getLogMain(job) + "派发成功。");  
10    }
  
11}
  
12  
13 private JobConfig find(JobConfig job) {  
14    for (JobConfig j : allJobs) {  
15        // 找到相同作业ID的任务  
16        if (j.getJobId().equals(job.getJobId())) {  
17            return j;  
18        }
  
19    }
  
20    return null;  
21}
  
22  
23 private boolean replace(JobConfig original, JobConfig job) {  
24    return remove(original) && schedule(job);  
25}
  
26  
27 private boolean remove(JobConfig job) {  
28    try {  
29        return schedulerService.remove(job);  
30    }
  
31    catch (SchedulerException e) {  
32        e.printStackTrace();  
33        log.error(Log4jHelper.getLogMain(job) + "移除失败。");  
34    }
  
35    return false;  
36}
  
37  
38 private boolean schedule(JobConfig job) {  
39    try {  
40        schedulerService.schedule(job);  
41    }
  
42    catch (Exception e) {  
43        e.printStackTrace();  
44        log.error(Log4jHelper.getLogMain(job) + "派发失败。");  
45        return false;  
46    }
  
47    return true;  
48}

49

  1 import java.io.IOException;  
  2 import java.io.InputStream;  
  3 import java.lang.reflect.Constructor;  
  4 import java.lang.reflect.Field;  
  5 import java.lang.reflect.InvocationTargetException;  
  6 import java.lang.reflect.Method;  
  7 import java.lang.reflect.ParameterizedType;  
  8 import java.net.MalformedURLException;  
  9 import java.net.URL;  
10 import java.util.ArrayList;  
11 import java.util.List;  
12  
13 import org.apache.commons.collections.Predicate;  
14 import org.springframework.core.io.ClassPathResource;  
15 import org.springframework.core.io.Resource;  
16 import org.springframework.core.io.support.PathMatchingResourcePatternResolver;  
17 import org.springframework.core.type.classreading.CachingMetadataReaderFactory;  
18 import org.springframework.core.type.classreading.MetadataReader;  
19 import org.springframework.core.type.classreading.MetadataReaderFactory;  
20  
21 import com.lim.base.exception.AppException;  
22  
23 /** */ /** 
24 * A collection of class management utility methods. 
25 *  
26 */
 
27 @SuppressWarnings( " unchecked " )  
28 public class ClassUtils {  
29 
30    /** *//** 
31     * 获得泛型类泛型参数类型. 
32     * 例如: 
33     * getGenericArgumentsType(List<String>.class)返回Class<String>. 
34     * @param <T> 
35     * @param cls 
36     * @return 
37     */
 
38    public static <T> Class<T> getGenericArgsType(Class<?> cls) {  
39        return getGenericArgumentsType(cls, 0);  
40    }
  
41 
42    /** *//** 
43     * 获得泛型类泛型参数类型. 
44     * @param <T> 
45     * @param cls 
46     * @param pos 
47     * @return 
48     */
 
49    public static <T> Class<T> getGenericArgumentsType(Class<?> cls, int pos) {  
50        return (Class<T>) ((ParameterizedType) cls.getGenericSuperclass()).getActualTypeArguments()[pos];  
51    }
  
52 
53    /** *//** 
54     * 在指定的类路径查找符合条件的类.<br/> 
55     * @param classPathPattern 
56     * @param predicate 
57     * @return 
58     */
 
59    public static Class<?>[] getClasses(String classPathPattern, Predicate predicate) {  
60        PathMatchingResourcePatternResolver resolver = null;  
61        resolver = new PathMatchingResourcePatternResolver();  
62        MetadataReaderFactory metaFactory = null;  
63        metaFactory = new CachingMetadataReaderFactory(resolver);  
64        try {  
65            Resource[] resources = resolver.getResources("classpath*:" + classPathPattern);  
66            ArrayList<Class<?>> clazzArr = new ArrayList<Class<?>>();  
67            for (Resource res : resources) {  
68                if (!res.isReadable()) {  
69                    continue;  
70                }
  
71 
72                MetadataReader metadataReader = metaFactory.getMetadataReader(res);  
73                String className = metadataReader.getClassMetadata().getClassName();  
74                Class<?> clazz = ClassUtils.loadClass(className);  
75                if (predicate.evaluate(clazz)) {  
76                    clazzArr.add(clazz);  
77                }
  
78            }
  
79            return clazzArr.toArray(new Class<?>[0]);  
80        }
  
81        catch (IOException e) {  
82            throw new AppException(e);  
83        }
  
84        catch (LinkageError e) {  
85            throw new AppException(e);  
86        }
  
87    }
  
88 
89    /** *//** 
90     * 在指定的类路径查找指定父类/接口类的所有子类. 
91     * Example: 
92     * Class<ITagChecker>[] checkerClz = ClassUtils.getSubClasses("com/linkage/ess/**<pre>/*</pre>.class", ITagChecker.class); 
93     * @param <T> 
94     * @param classPathPattern 
95     * @param superClass 
96     * @return 
97     */
 
98    public static <T> Class<? extends T>[] getSubClasses(String classPathPattern,  
99            final Class<T> superClass) {  
100 
101        return (Class<? extends T>[]) getClasses(classPathPattern, new Predicate() {  
102            @Override 
103            public boolean evaluate(Object arg0) {  
104                Class<?> clazz = (Class<?>) arg0;  
105                return !clazz.isInterface() && superClass.isAssignableFrom(clazz);  
106            }
  
107        }
);  
108    }
  
109 
110    /** *//** 
111     * Create a new instance given a class name(要求有默认构造函数). 
112     *  
113     * @param className 
114     *            A class name 
115     * @return A new instance 
116     * @throws ClassNotFoundException 
117     * @throws IllegalAccessException 
118     * @throws InstantiationException 
119     * @exception Exception 
120     *                If an instantiation error occurs 
121     */
 
122    public static <T> T newInstance(Class<T> clz) {  
123        try {  
124            return clz.newInstance();  
125        }
  
126        catch (InstantiationException e) {  
127            e.printStackTrace();  
128            throw new AppException(e);  
129        }
  
130        catch (IllegalAccessException e) {  
131            e.printStackTrace();  
132            throw new AppException(e);  
133        }
  
134 
135    }
  
136 
137    /** *//** 
138     * 带有参数的实例创建. 
139     * @param <T> 
140     * @param impl 
141     * @param param 
142     * @param params 
143     * @return 
144     */
 
145    public static <T> T newInstance(Class<T> impl, Object params) {  
146        List<Class<?>> lstClass = new ArrayList<Class<?>>(params.length + 1);  
147        for (Object obj : params) {  
148            lstClass.add(obj.getClass());  
149        }
  
150        Class<?> paramClasses[] = lstClass.toArray(new Class<?>[0]);  
151 
152        return newInstance(impl, paramClasses, params);  
153    }
  
154 
155    /** *//** 
156     * 带有参数的实例创建. 
157     * @param <T> 
158     * @param impl 
159     * @param paramClasses 
160     * @param params 
161     * @return 
162     */
 
163    public static <T> T newInstance(Class<T> impl, Class<?> paramClasses[], Object params[]) {  
164        try {  
165            Constructor<T> constructor = impl.getConstructor(paramClasses);  
166            return constructor.newInstance(params);  
167        }
  
168        catch (InstantiationException e) {  
169            e.printStackTrace();  
170            throw new AppException(e);  
171        }
  
172        catch (IllegalAccessException e) {  
173            e.printStackTrace();  
174            throw new AppException(e);  
175        }
  
176        catch (IllegalArgumentException e) {  
177            throw new AppException(e);  
178        }
  
179        catch (InvocationTargetException e) {  
180            throw new AppException(e);  
181        }
  
182        catch (SecurityException e) {  
183            throw new AppException(e);  
184        }
  
185        catch (NoSuchMethodException e) {  
186            throw new AppException(e);  
187        }
  
188    }
  
189 
190    /** *//** 
191     * 使用类型的实例创建.(要求有默认构造函数). 
192     * @param className 
193     * @return 
194     */
 
195    public static Object newInstance(String className) {  
196        try {  
197            return loadClass(className).newInstance();  
198        }
  
199        catch (InstantiationException e) {  
200            e.printStackTrace();  
201            throw new AppException(e);  
202        }
  
203        catch (IllegalAccessException e) {  
204            e.printStackTrace();  
205            throw new AppException(e);  
206        }
  
207    }
  
208 
209    /** *//** 
210     * Load a class given its name. BL: We wan't to use a known 
211     * ClassLoader--hopefully the heirarchy is set correctly. 
212     *  
213     * @param className 
214     *            A class name 
215     * @return The class pointed to by <code>className</code> 
216     * @exception ClassNotFoundException 
217     *                If a loading error occurs 
218     */
 
219    public static Class<?> loadClass(String className) {  
220        try {  
221            return getClassLoader().loadClass(className);  
222        }
  
223        catch (ClassNotFoundException e) {  
224            throw new AppException(e);  
225        }
  
226    }
  
227      
228    public static Method getMethod(String className,  String name, Class<?> parameterTypes) {  
229        return getMethod(loadClass(className), name, parameterTypes);  
230    }
  
231      
232    public static Method getMethod(Class<?> cls, String name, Class<?> parameterTypes) {  
233        try {  
234            return cls.getMethod(name, parameterTypes);  
235        }
  
236        catch (SecurityException e) {  
237            throw new AppException(e);  
238        }
  
239        catch (NoSuchMethodException e) {  
240            throw new AppException(e);  
241        }
  
242    }
  
243 
244    /** *//** 
245     * Return a resource URL. BL: if this is command line operation, the 
246     * classloading issues are more sane. During servlet execution, we 
247     * explicitly set the ClassLoader. 
248     *  
249     * @return The context classloader. 
250     * @exception MalformedURLException 
251     *                If a loading error occurs 
252     */
 
253    public static URL getResource(String resource) {  
254        return getClassLoader().getResource(resource);  
255    }
  
256 
257    public static InputStream loadResource(String path) {  
258        try {  
259            return new ClassPathResource(path).getInputStream();  
260        }
  
261        catch (IOException e) {  
262            e.printStackTrace();  
263            throw new AppException(e);  
264        }
  
265    }
  
266 
267    /** *//** 
268     * Return the context classloader. BL: if this is command line operation, 
269     * the classloading issues are more sane. During servlet execution, we 
270     * explicitly set the ClassLoader. 
271     *  
272     * @return The context classloader. 
273     */
 
274    public static ClassLoader getClassLoader() {  
275        return Thread.currentThread().getContextClassLoader();  
276    }
  
277 
278    public static Field getDeclaredField(Class<?> cls, String fieldName) {  
279        try {  
280            return cls.getDeclaredField(fieldName);  
281        }
  
282        catch (Exception e) {  
283            throw new AppException(e);  
284        }
  
285    }
  
286 
287    public static Object invokeQuietly(Object target, Method m) {  
288        try {  
289            return m.invoke(target);  
290        }
  
291        catch (IllegalArgumentException e) {  
292            e.printStackTrace();  
293        }
  
294        catch (IllegalAccessException e) {  
295            e.printStackTrace();  
296        }
  
297        catch (InvocationTargetException e) {  
298            e.printStackTrace();  
299            if (e.getTargetException() instanceof RuntimeException) {  
300                throw (RuntimeException) e.getTargetException();  
301            }
  
302        }
  
303 
304        return null;  
305    }
  
306}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值