标签:
编写更少BUG 程序的一个技巧是, 尽可能复用经过严格测试的可靠成熟的公共库。
当我们实现可复用的目标时, 通常是希望尽可能少的代码能够表达更强的复用性, 而不要受到与问题无关因素的制约。 有时, 语言的设计会对可复用性的实现有很大影响。
例子: 取出对象列表中指定字段的值集合。
使用 Java 实现是这样的:
package com.qinshuq.zk.study; import java.lang.reflect.Field; import java.util.ArrayList; import java.util.List; public class GettingFieldValues { public static void main(String[] args) { printAllNamesAndAges(); printAllNamesAndAges2(); } public static void printAllNamesAndAges() { // Get all ages of persons List<Person> persons = createPersons(); List<Integer> ages = new ArrayList<Integer>(); for (Person p: persons) { ages.add(p.getAge()); } System.out.println(ages); // Get all name of cats List<Cat> cats = createCats(); List<String> names = new ArrayList<String>(); for (Cat c: cats) { names.add(c.getName()); } System.out.println(names); } public static void printAllNamesAndAges2() { List<Person> persons = createPersons(); List<Cat> cats = createCats(); System.out.println(getAllFieldValues(persons, Person.class, "age")); System.out.println(getAllFieldValues(cats, Cat.class, "name")); } private static <T> List<Object> getAllFieldValues(List<T> objList, Class c, String objFieldName) { List<Object> values = new ArrayList<Object>(); try { for (Object obj: objList) { Field f = null; f = c.getDeclaredField(objFieldName); f.setAccessible(true); values.add(f.get(obj)); f.setAccessible(false); } return values; } catch (SecurityException e) { return new ArrayList<Object>(); } catch (NoSuchFieldException e) { return new ArrayList<Object>(); } catch (IllegalArgumentException e) { return new ArrayList<Object>(); } catch (IllegalAccessException e) { return new ArrayList<Object>(); } } public static List<Person> createPersons() { List<Person> persons = new ArrayList<Person>(); persons.add(new Person("qin", 30)); persons.add(new Person("shu",29)); return persons; } public static List<Cat> createCats() { List<Cat> cats = new ArrayList<Cat>(); cats.add(new Cat("mimi", 2)); cats.add(new Cat("nini", 1)); return cats; } } class Person { private String name; private int age; public Person(String name, int age) { this.name = name; this.age = age; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } } class Cat { private String name; private int years; public Cat(String name, int years) { this.name = name; this.years = years; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getYears() { return years; } public void setYears(int years) { this.years = years; } }
程序中, 使用了反射机制来获取对象字段的值, 同时, 受到了对象类型的很大约束。 要么需要写多段 for 循环逻辑, 要么需要在类型之中艰难地行走。
实际上, 在这个需求中, 只需要关心三个问题: 列表、 对象字段、 遍历值集。 即: 遍历列表, 取出对象字段值。 不需要去关心是什么对象, 值是什么类型。 动态语言对此有更好的支持。 使用 Python 的实现如下:
#!/usr/bin/env python # -*- coding: utf-8 -*- # ------------------------------------------------------------------------------- # Name: GetSpecFieldValues.py # Purpose: extract all values from specified field of object in a list. # # Author: qin.shuq # # Created: 2015-03-12 #------------------------------------------------------------------------------- def getSpecFieldValues(objlist, fieldName): return map(lambda obj: obj.__dict__[fieldName], objlist) class Person(object): def __init__(self, name, age): self.name = name self.age = age class Cat(object): def __init__(self, name, years): self.name = name self.years = years if __name__ == ‘__main__‘: persons = [Person(‘qin‘, 30), Person(‘shu‘, 29)] cats = [Cat(‘mimi‘, 2), Cat(‘nini‘, 1)] print getSpecFieldValues(persons, ‘age‘) print getSpecFieldValues(cats, ‘name‘)
其中 getSpecFieldValues(objlist, fieldName) 只需要一行代码, 就能适应各种对象的各种字段的值类型 !
Java 也能实现相同的目标, 只是拐弯抹角要绕一些圈儿, 写起来有点费力, 可复用性不佳, 并且代码也不够优雅, 难以表达我们所预定的概念及交互。 除了框架、技术和平台, 其实程序员也希望能够编程编得爽心, 能够使用编程语言无碍地表达自己的想法和实现方式, 而不仅仅是追求软件工程中的“团体生产力”。
编程的本质是表达和维护大型逻辑。
标签:
原文地址:http://www.cnblogs.com/lovesqcc/p/4333392.html