編寫更少BUG 程序的一個技巧是: 切分大型邏輯爲可以容易處理的小邏輯塊; 儘量複用通過嚴格測試的可靠成熟的公共庫。 java
當實現可複用的目標時, 一般是但願儘量少的代碼可以表達更強的複用性, 而不要受到與問題無關因素的制約。 語言的設計會對可複用性的實現有較大影響。靜態類型語言一般會施加更多與問題域無關的類型限制,以加強運行時的可靠性; 而動態語言則經過類型推導機制,使得編程者儘量少地受到類型的約束,而在運行時的可靠性由程序員本身去保證。python
例子: 取出任意對象列表中的指定字段的值集合。程序員
使用 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; } }
因爲 Java 對類的元信息【成員、方法、包等】進行了良好的抽象,所以能夠編寫一個通用的方法來實現對象列表指定字段的值集合。程序中, 使用了反射機制來獲取對象字段的值, 同時, 須要與 Java 類型系統打交道,必要時進行強制類型轉換,在實現的時候必須考慮與問題域無關的語言類型系統的約束和類型安全。 編程
再看看 Javascript 的實現。 Javascript 是一門「無類」的基於原型的面嚮對象語言。使用 Javascript 時,就沒必要要編寫類的定義了,直接針對對象操做,而對象可使用 JSON 格式來簡潔地表達,針對對象取屬性值也有簡潔的支持; 美中不足的是, Javascript 沒有提供對列表的 map 映射,須要本身去實現。代碼以下:瀏覽器
cats = [{"name":"mimi", "age":2}, {"name":"nini", "age":1}];
persons = [{"name":"qin", "age":30}, {"name":"shu", "age":29}]; Array.prototype.map = function(handleElem) { if (this == null || this.length == 0) { return []; } values = []; for (var i=0; i< this.length; i++) { values.push(handleElem(this[i])); } return values; } Array.prototype.getFieldValues = function(fieldName) { return this.map(function(obj) { return obj[fieldName]} ); } console.log("using prototype to extend array's ability"); console.log(cats.getFieldValues('name')); console.log(cats.getFieldValues('age')); console.log(persons.getFieldValues('name')); console.log(persons.getFieldValues('age'));
實際上, 在這個需求中, 只須要關心三個概念: 列表、 對象字段、 遍歷值。 即: 遍歷列表, 取出對象的指定字段值。 不須要去關心是什麼對象, 值是什麼類型。 使用 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 能實現相同的目標, 只是拐彎抹角要繞一些圈兒, 寫起來有點費力, 代碼也不夠優雅, 難以自由表達咱們所思定的概念及交互, 不過做爲大型服務端應用系統的工程語言 Java 作得是很不錯的; Javascript 做爲面向終端的瀏覽器端語言,則顯得更加「時尚」一點, JSON, 基於原型的對象思想,略帶函數式的編程, 使得其在表達力上有較大的靈活性,而在工程性上略遜一籌; Python 做爲簡潔的動態語言以及擁有成熟的面向對象特性, 表達力更加靈活, 工程性也很不錯。編程語言
語義理解
當咱們在複用他人的工做成果時, 須要準確理解開發領域內各類概念、現有技術的邏輯語義。 編程語言提供的語言特性, 好比 Synchronized 的語義; API 語義,好比 map(lambda, list) ; 技術點的適用語義 , 好比數據庫讀寫事務 ; 應用框架中自定義實現的語義,好比 Spring 裏的攔截器, AOP; 開發工具中的模型語義, 好比 POM 的生命週期管理。程序員所作的事情, 就是準確理解和應用這些語義來搭建與現實世界銜接良好的趨於精確完美的邏輯系統。軟件開發,從技術角度來講,是語言與邏輯的藝術。
編程的本質是簡明天然地表達和維護大型邏輯。