<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    2008年10月25日

    不止一次我們的項(xiàng)目在靠開發(fā)人員硬扛著,bug來不及修改,文檔還在猛補(bǔ),項(xiàng)目經(jīng)理又在催著出版本,每修改一個(gè)bug都要在代碼的泥沼中摸爬滾打半天,卻又在制造著另外的bug,為了文檔而制造著根本沒有參考價(jià)值的文檔。每發(fā)布一個(gè)版本都要瞻前顧后并且總要無休止的加班,似乎開發(fā)人員永遠(yuǎn)有干不完的活。

    我們不禁問自己,為什么會(huì)有那么多失敗的軟件,軟件開發(fā)我們到底還需要什么? 

    工具?我們不乏偉大的工具,IDE我們有eclipse、intelliJ、VC++等等,建模我們有Rose、together、Visio等等,配置管理我們Subversion、CVS、ClearCase等等,bug管理我們有ClearQuest、bugzilla等等,文檔我們word、wps等,還有集成、測(cè)試甚至生成代碼等等我們都有偉大的工具,工具我們不缺。流程?瀑布模型、迭代模型、UP、XP我們不缺流程管理的理論。知識(shí)?軟件開發(fā)算是一項(xiàng)知識(shí)型的工作,我們的開發(fā)人員一般都是本科碩士畢業(yè),況且搜索引擎如此發(fā)達(dá)的今天,知識(shí)根本不是問題,況且我們的軟件開發(fā)需要多么高深的知識(shí)嗎?

     優(yōu)秀的理論支持、有能力的人員、先進(jìn)的工具,這些我們都具備,我們所缺的只是一種軟件開發(fā)的理念,缺少軟件開發(fā)的情商。我們一開始學(xué)習(xí)編程知識(shí)接觸到的就是C語(yǔ)言和數(shù)據(jù)結(jié)構(gòu),慢慢的一些結(jié)構(gòu)化的思想就扎根于大腦,其實(shí)在商業(yè)軟件中數(shù)據(jù)結(jié)構(gòu)、算法很少涉及,我們所需要的僅僅是一種設(shè)計(jì)、開發(fā)的理念。比如用面向?qū)ο蟊緛硎且环N簡(jiǎn)單的思想,目的是為了降低軟件的復(fù)雜性而出現(xiàn)的,可是讓熟悉了結(jié)構(gòu)化編程的人去搞反而覺得很難。一些好的實(shí)踐經(jīng)驗(yàn)我們也經(jīng)常提到,比如模塊化、松散耦合、面向接口編程、類應(yīng)只關(guān)注本職工作等等開發(fā)設(shè)計(jì)理念以及規(guī)范命名、詳盡使用的注釋、清晰的結(jié)構(gòu)等代碼規(guī)范以及每日構(gòu)建、有效溝通、配置管理、bug管理等一些管理理念,這些做起來都非常容易,關(guān)鍵是懶惰是人的本性,不知不覺中我們就會(huì)犯著大家都在重復(fù)的錯(cuò)誤。如果在項(xiàng)目開工之初就充分貫徹這些優(yōu)秀的理念,在項(xiàng)目進(jìn)行中無論時(shí)間多緊都持之以恒,并且項(xiàng)目進(jìn)行中不斷的反思代碼中的壞味道,一經(jīng)發(fā)現(xiàn)立即重構(gòu),相信我們的開發(fā)過程會(huì)進(jìn)入一個(gè)良性的循環(huán)中去,我們的開發(fā)人員將會(huì)體會(huì)到什么是快樂開發(fā)。

    posted @ 2008-11-17 23:09 徐辛波 閱讀(352) | 評(píng)論 (0)編輯 收藏
    徐辛波,西安,從事軟件開發(fā)設(shè)計(jì)工作,熟悉Java語(yǔ)言,愛好開發(fā)工作,特別是java相關(guān)的編程,業(yè)余關(guān)注開源項(xiàng)目,誠(chéng)心結(jié)識(shí)志同道合之士組建開源團(tuán)隊(duì),共同學(xué)習(xí)、進(jìn)步、協(xié)作、為中國(guó)開源事業(yè)貢獻(xiàn)微薄之力。
    徐辛波 sinpo.xu@gmail.com
    posted @ 2008-10-31 21:00 徐辛波 閱讀(359) | 評(píng)論 (1)編輯 收藏

    JDOM因其簡(jiǎn)潔易用易懂的API而被廣泛的使用。JDOM常用的核心類及它們間的關(guān)系如下圖所示:

    Document代表了文檔對(duì)象,抽象類Content表示文檔中的內(nèi)容元素,各種內(nèi)容組成了文檔對(duì)象。常用的內(nèi)容元素有xml元素Element、xml注釋Comment、文本Text。下面以如下片段來說明各類的含義。

    <?xml version="1.0" encoding="UTF-8"?>

    <customers>

    <customer>

    <name>徐辛波</name>

    <occupation>developer</occupation>

    <!-- comment:following is contact info -->

    <contact>

    <email>sinpo.xu@hotmail.com</email>

    <mobile>15029357227</mobile>

    <fix-phone>02985457683</fix-phone>

    </contact>

    </customer>

    </customers>

    上述文檔用Document來抽象;customers為文檔的根元素(root element ),Element即一個(gè)封閉起來的元素,element元素可以有子元素,如<mobile>15029357227</mobile>是一個(gè)元素,而<contact>...</contact>也是一個(gè)元素,甚至<customers>...</customers>也是一個(gè)大元素;<!-- ... -->代表了xml中注釋,注釋在JDOM中用Comment類來抽象;Text代表了xml中的文本值,如元素屬性的值、元素的值、注釋的內(nèi)容等,父元素的Text為子元素和值組成的串,使用Text類可以方便的表示一些特殊字符,如:

    Element element = new Element("name");

    Text text = new Text("AAA.<、BBB/>.<CCC>");

    element.addContent(text);

    值得一提的是Element的方法addContent(Content content),因參數(shù)是抽象父類Content,所以可以添加Text、Element和Comment等,如果添加的是Text則自動(dòng)作為element的文本值,如果是Element則作為element的子元素,如果是Comment則作為element的注釋,使用十分方便。元素的值如<name>徐辛波</name>中的“徐辛波”也是一個(gè)和元素平行的Content對(duì)象(Text對(duì)象),當(dāng)使用Element的getDescendants()方法時(shí)將返回一個(gè)該元素所有后代的迭代器,這些后代包括Element、Comment、Text等,如元素<contact>的后代包括email、mobile、fix-phone三個(gè)元素以及這三個(gè)元素的Text共6個(gè)后代,如果計(jì)算后代時(shí)有父子嵌套則應(yīng)注意,父元素作為一個(gè)后代,其嵌套的子元素作為另一個(gè)后代。

    剛才提到核心類都包含在org.jdom包下,jdom還包含了org.jdom.input和org.jdom.output兩個(gè)包分別來處理xml內(nèi)容的輸入輸出。當(dāng)要讀取xml資源時(shí)我們通常使用input包下的SAXBuilder類從輸入流構(gòu)建dom對(duì)象,當(dāng)資源加載后常用的做法是在內(nèi)存中緩存,這樣后續(xù)的查找修改等操作就非常快。文檔加載后內(nèi)存的中各個(gè)元素是記錄有各自的位置和關(guān)系的,即保持有上下文環(huán)境的。如果想要?jiǎng)h除一段內(nèi)容(Element Comment Text),只用調(diào)用該內(nèi)容的detach方法即可,這樣元素即和文檔脫離關(guān)系了,再對(duì)文檔進(jìn)行遍歷或者持久化到磁盤上時(shí)游離的元素就不可見了。Jdom的輸出類包括XMLOutputter、DOMOutputter、SAXOutputter。最常用的是XMLOutputter,通過它可以將dom對(duì)象輸出到指定的輸出流,并且可以指定所輸出xml文件的格式,比如縮進(jìn)的樣式等。DOMOutputter輸出org.w3c.dom.Document對(duì)象,用于JDOM對(duì)象同w3c dom對(duì)象轉(zhuǎn)換,SAXOutputter可以注冊(cè)回調(diào)函數(shù)來處理相應(yīng)的sax事件。


    一下示例代碼實(shí)現(xiàn)一個(gè)常用的讀取配置文件并且允許更改后同步到磁盤的操作:
    package sinpo.usagedemo;

    import java.io.File;
    import java.io.FileOutputStream;
    import java.io.IOException;
    import java.io.InputStream;
    import java.io.OutputStream;
    import java.net.URL;
    import java.util.List;

    import org.jdom.Document;
    import org.jdom.Element;
    import org.jdom.input.SAXBuilder;
    import org.jdom.output.Format;
    import org.jdom.output.XMLOutputter;

    /**
     * 讀取配置文件,并且修改后及時(shí)同步到磁盤
     @author 徐辛波(sinpo.xu@hotmail.com) 
     * Oct 23, 2008
     */
    public class Configuration {

        private Element root = null;

        private Document dom = null;

        private static final String resourceName = "/config.xml";

        private static Configuration _INSTANCE = null;

        public static synchronized Configuration getInstance() {
            if (_INSTANCE == null) {
                _INSTANCE = new Configuration();
            }

            return _INSTANCE;
        }

        private Configuration() {
            load();
        }

        public String getConfig(String configName) {
            String configValue = null;
            Element found = findRecursively(configName, root);
            if (found != null) {
                configValue = found.getText();
            }
            return configValue;
        }

        public void updateConfig(String configName, String newValue)
                throws IOException {
            Element found = findRecursively(configName, root);
            if (found != null) {
                found.setText(newValue);
            else {
                Element configNode = new Element(configName);
                configNode.addContent(newValue);
                // also: configNode.setText(newValue);
                root.addContent(configNode);
            }
            sync();
        }

        public void deleteConfig(String configNamethrows IOException {
            Element found = findRecursively(configName, root);
            if (found != null) {
                found.detach();
            }
            sync();
        }
        
        private void load() {
            SAXBuilder builder = new SAXBuilder();
            InputStream source = getClass().getResourceAsStream(resourceName);
            try {
                dom = builder.build(source);
                root = dom.getRootElement();
            catch (Exception e) {
                e.printStackTrace();
            }
        }

        // 遞歸查找. 在指定的父節(jié)點(diǎn)下查找葉子元素
        private Element findRecursively(String name, Element parent) {
            Element found = null;
            List<Element> children = parent.getChildren();
            if (children != null) {
                for (int i = 0; i < children.size(); i++) {
                    Element element = children.get(i);
                    String tmpName = element.getName();
                    if ((name.equals(tmpName)) && (!hasChild(element))) {
                        return element;
                    }
                }

                for (int i = 0; i < children.size(); i++) {
                    Element element = children.get(i);
                    if (hasChild(element)) {
                        found = findRecursively(name, element);
                        if (found != null) {
                            return found;
                        }
                    }
                }
            }

            return found;
        }

        private boolean hasChild(Element element) {
            boolean hasChild = false;
            List children = element.getChildren();
            if ((children != null&& (children.size() 0)) {
                hasChild = true;
            }

            return hasChild;
        }

        private void sync() throws IOException {
            Format format = Format.getPrettyFormat();
            XMLOutputter outputter = new XMLOutputter(format);
            File file = null;
            URL url = getClass().getResource(resourceName);
            if (url == null) {
                file = new File(resourceName);
            else {
                file = new File(url.getPath());

                OutputStream out = null;
                try {
                    out = new FileOutputStream(file);
                    outputter.output(dom, out);
                    out.close();
                    out = null;
                catch (Exception e) {
                    e.printStackTrace();
                    if (out != null) {
                        out.close();
                    }
                }
            }
        }
    }
    posted @ 2008-10-25 21:02 徐辛波 閱讀(794) | 評(píng)論 (0)編輯 收藏

    導(dǎo)航

    <2008年10月>
    2829301234
    567891011
    12131415161718
    19202122232425
    2627282930311
    2345678

    統(tǒng)計(jì)

    常用鏈接

    留言簿(1)

    隨筆分類

    隨筆檔案

    最新隨筆

    最新評(píng)論

    閱讀排行榜

    評(píng)論排行榜

    主站蜘蛛池模板: 羞羞视频免费网站日本| 97无码人妻福利免费公开在线视频| 亚洲情侣偷拍精品| 一级成人a毛片免费播放| 亚洲午夜无码久久久久小说| 国产一级高清视频免费看| 国产一区二区三区免费| 亚洲精品综合在线影院| 不卡精品国产_亚洲人成在线| 免费福利在线播放| 免费看黄网站在线看 | 四虎精品亚洲一区二区三区| 视频免费在线观看| 亚洲日韩一区二区一无码| 亚洲国产精彩中文乱码AV| 精品少妇人妻AV免费久久洗澡| 99视频免费在线观看| 亚洲人成欧美中文字幕| 亚洲精品乱码久久久久66| 永久免费视频v片www| 人妻无码久久一区二区三区免费| 精品无码专区亚洲| 亚洲欧洲国产成人精品| 中文字幕亚洲无线码a| 精品熟女少妇AV免费观看| 桃子视频在线观看高清免费视频| 色吊丝免费观看网站| 亚洲一区二区三区在线网站| 亚洲日韩av无码| 亚洲成人影院在线观看| 在线看片免费不卡人成视频| 日韩电影免费在线观看| 日韩在线视频免费| 亚洲色大成WWW亚洲女子| 亚洲精品人成电影网| 久久精品国产99精品国产亚洲性色| avtt亚洲天堂| 国产精品色午夜免费视频| 成年女人色毛片免费看| 免费看污成人午夜网站| 久操视频在线免费观看|