劣质代码的产生原因(2)编程语言知识不足 (续3)

6.空对象模型

    当需要访问一个对象有可能是空的时候,需要进行空校验。

    比如,下面的例子。

1 public class User {
2     int id;
3     String name;
4     public void save() {
5         System.out.println("Save user");
6     }
7 }

 

1 public void saveUser(int id, String name) {
2     User user = findUserById(id);
3     if (user == null) {
4         return;
5     }
6     user.name = name;
7     user.save();
8 }

但是当这样的空校验代码变多的时候,它会降低理解代码的速度。

1 public class NullUser extends User{
2     public void save() {
3         //什么也不干
4     }
5 }
1 public void saveUser (int id, String name) {
2     User user = findUserById(id);
3     user.name = name;
4     user.save();
5 }

*上述代码中findUserById需要经过改造,确保当原来返回null的情形,现在返回NullUser。这样调用的代码就会变得十分简练。
像这样,能够把多处调用的空判定合并在底层处理,上层不用关心对象是否为空的方式叫做空对象模式。

7.常量的若干种形式

软件开发不可避免的要用到常量。常见的常量形式为:

1 public static final int VERSION = 1;

但是常量却不止这一种形式。
    a.常量的类型不仅仅可以为基本类型

1 public static final Keyboard SOFT_KEYBOARD = new SoftKeyboard();
2 public static final Keyboard HARD_KEYBOARD = new HardKeyboard();


   b.常量的表现形式还可以是枚举

1 public enum KeyboardState {
2     INVISIBLE, VISIBLE, UNAVAILABLE;
3 }

8. Map的作用

    Map是按照键-值对的形式存放数据的一种数据结构。Map在书写代码中广为利用,但是除了简单的存储数据之外,Map还有一些奇妙的使用方法。

   a. 去掉重复

    例如,在发送邮件的时候去掉重复的地址

 1 public List<String> removeDuplicatedMails(List<String> addresses) {
 2     Map<String, String> instinctMails = new HashMap<String, String>();
 3     for (String a : addresses) {
 4         if (!instinctMails.containsKey(a)) {
 5             instinctMails.put(a, a);
 6         }
 7     }
 8 
 9     List<String> instinctMailList = new ArrayList<String>();
10     Set keys = instinctMails.keySet();
11     Iterator i = keys.iterator();
12     while(i.hasNext()) {
13         instinctMailList.add((String)i.next());
14     }
15     return instinctMailList;
16 }

   b.按组统计数据
 例如,有这样一组数据:

      商店,销售额,月份
      商店,销售额,月份

     希望将数据按照商店进行合并统计总销售额

 1 public Map<Integer, Float> makeSalesReport(List<SalesInfo> sales) {
 2     Map<Integer, Float> report = new HashMap<Integer, Float>();
 3     for (SalesInfo si : sales) {
 4         if (report.containsKey(si.shop)) {
 5             report.put(si.shop, repot.get(si.shop) + si.price);
 6         } else {
 7             report.put(si.shop, si.price);
 8         }
 9     }
10     return report;
11 }

这种算法比通过若干个嵌套循环,找到key,再进行对比相加来说结构上简单的多。

posted @ 2012-10-29 23:06  史蒂芬.王  阅读(373)  评论(0编辑  收藏  举报