国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

【譯】軟件設(shè)計(jì)原則

jsdt / 2020人閱讀

摘要:軟件設(shè)計(jì)一直是開(kāi)發(fā)周期中最重要的階段,在設(shè)計(jì)彈性和靈活的體系結(jié)構(gòu)的花費(fèi)的時(shí)間越多,在將來(lái)出現(xiàn)變更時(shí)就越節(jié)省時(shí)間。在本文中,我們將討論有助于創(chuàng)建易于維護(hù)和可擴(kuò)展的軟件的關(guān)鍵設(shè)計(jì)原則。

翻譯: 瘋狂的技術(shù)宅
來(lái)源: Programmer Gate
原文標(biāo)題: Software design principles
英文原文: http://programmergate.com/sof...
說(shuō)明:本專欄文章首發(fā)于公眾號(hào):jingchengyideng 。

軟件設(shè)計(jì)一直是開(kāi)發(fā)周期中最重要的階段,在設(shè)計(jì)彈性和靈活的體系結(jié)構(gòu)的花費(fèi)的時(shí)間越多,在將來(lái)出現(xiàn)變更時(shí)就越節(jié)省時(shí)間。需求總是變化的,如果不定期添加或維護(hù)功能,軟件將出現(xiàn)為遺留問(wèn)題,并且變更成本是根據(jù)系統(tǒng)的結(jié)構(gòu)和體系結(jié)構(gòu)來(lái)確定的。在本文中,我們將討論有助于創(chuàng)建易于維護(hù)和可擴(kuò)展的軟件的關(guān)鍵設(shè)計(jì)原則。

1. 一個(gè)實(shí)際的場(chǎng)景

假設(shè)老板要求你寫一個(gè)將word文檔轉(zhuǎn)換成PDF的程序。這個(gè)任務(wù)看起來(lái)很簡(jiǎn)單,只需找到一個(gè)可靠的庫(kù),它可以將word文檔轉(zhuǎn)換成PDF,并把它集成到你的程序中。在做了一些研究之后,你最終決定使用 Aspose.words 框架并創(chuàng)建了以下類:

代碼:PDFConverter.java

/**
 * A utility class which converts a word document to PDF
 * @author Hussein
 *
 */
public class PDFConverter {
 
    /**
     * This method accepts as input the document to be converted and 
     * returns the converted one.
     * @param fileBytes
     * @throws Exception 
     */
    public byte[] convertToPDF(byte[] fileBytes) throws Exception
    {
        // We"re sure that the input is always a WORD. So we just use 
        //aspose.words framework and do the conversion.
        
        InputStream input = new ByteArrayInputStream(fileBytes);
        com.aspose.words.Document wordDocument = new com.aspose.words.Document(input);
        ByteArrayOutputStream pdfDocument = new ByteArrayOutputStream();
        wordDocument.save(pdfDocument, SaveFormat.PDF);
        return pdfDocument.toByteArray();
    }
}

生活很簡(jiǎn)單,一切都很順利!!

需求總是變化

幾個(gè)月后,一些用戶要求支持也 excel 文檔,所以你又做了一些研究,決定使用ascell.cell 。然后你找到你原來(lái)的類,并添加了一個(gè)名為 documentType 的新字段,并修改了你的方法,代碼如下:

代碼:PDFConverter.java

public class PDFConverter {
    // we didn"t mess with the existing functionality, by default 
    // the class will still convert WORD to PDF, unless the client sets 
    // this field to EXCEL.
    public String documentType = "WORD";
 
    /**
     * This method accepts as input the document to be converted and 
     * returns the converted one.
     * @param fileBytes
     * @throws Exception 
     */
    public byte[] convertToPDF(byte[] fileBytes) throws Exception
    {
        if(documentType.equalsIgnoreCase("WORD"))
        {
            InputStream input = new ByteArrayInputStream(fileBytes);
            com.aspose.words.Document wordDocument = new com.aspose.words.Document(input);
            ByteArrayOutputStream pdfDocument = new ByteArrayOutputStream();
            wordDocument.save(pdfDocument, SaveFormat.PDF);
            return pdfDocument.toByteArray();
        }
        else
        {
            InputStream input = new ByteArrayInputStream(fileBytes);
            Workbook workbook = new Workbook(input);
            PdfSaveOptions saveOptions = new PdfSaveOptions();
            saveOptions.setCompliance(PdfCompliance.PDF_A_1_B);
            ByteArrayOutputStream pdfDocument = new ByteArrayOutputStream();
            workbook.save(pdfDocument, saveOptions);
            return pdfDocument.toByteArray();
        }
    }
}

該代碼可以為新用戶正常正常,而且仍然可以按照預(yù)期的方式為現(xiàn)有的用戶工作,但是一些糟糕的設(shè)計(jì)氣味開(kāi)始出現(xiàn)在代碼中,這樣做是不完美的,當(dāng)再一個(gè)新的文檔類型時(shí),我們將無(wú)法輕松修改這個(gè)類。

代碼重復(fù):正如你所看到的,在if/else塊存在類似的代碼,如果有一天再添加不同的擴(kuò)展,那么將會(huì)出現(xiàn)大量的重復(fù)。如果我們決定返回一個(gè)文件而不是一個(gè) byte[] 那么就必須在所有的塊中做相同的修改。

剛性:所有的轉(zhuǎn)換算法都是在同一種方法中進(jìn)行耦合的,所以如果你改變了一些算法,其他的算法也會(huì)隨之受到影響。

固定:上面的方法直接依賴于documentType字段,假如一些用戶在調(diào)用convertToPDF()之前忘記了設(shè)置這個(gè)字段,那將得不到預(yù)期的結(jié)果,我們也不能在任何其他項(xiàng)目中重用該方法,因?yàn)樗蕾囉谧侄巍?/p>

高級(jí)模塊與框架之間的耦合:如果將來(lái)我們決定用更可靠的方式替換 Aspose 框架,那么最終修將會(huì)改整個(gè) PDFConverter 類,并且會(huì)有許多用戶受到影響。

正確的方式

通常情況下,并不是所有的開(kāi)發(fā)人員都能夠預(yù)見(jiàn)未來(lái)的變化。因此,他們中的大多數(shù)人將會(huì)像我們第一次實(shí)現(xiàn)的那樣,完全實(shí)現(xiàn)程序,但是在第一次改變之后,情況就會(huì)變得很明顯,將來(lái)會(huì)發(fā)生類似的變化。所以,好的開(kāi)發(fā)人員將會(huì)為了盡可能減少將來(lái)變更的成本使用正確的方式,而不是用if / else塊實(shí)現(xiàn)。所以我們?cè)诒┞兜墓ぞ撸≒DFConverter)和低級(jí)轉(zhuǎn)換算法之間創(chuàng)建一個(gè)抽象層,并將每個(gè)算法移動(dòng)到一個(gè)多帶帶的類中,如下所示:

代碼:Converter.java

/**
 * This interface represents an abstract algorithm for converting
 * any type of document to PDF.
 * @author Hussein
 *
 */
public interface Converter {
 
    public byte[] convertToPDF(byte[] fileBytes) throws Exception;
}

代碼:ExcelPDFConverter.java

/**
 * This class holds the algorithm for converting EXCEL
 * documents to PDF.
 * @author Hussein
 *
 */
public class ExcelPDFConverter implements Converter{
 
    public byte[] convertToPDF(byte[] fileBytes) throws Exception {
        InputStream input = new ByteArrayInputStream(fileBytes);
        Workbook workbook = new Workbook(input);
        PdfSaveOptions saveOptions = new PdfSaveOptions();
        saveOptions.setCompliance(PdfCompliance.PDF_A_1_B);
        ByteArrayOutputStream pdfDocument = new ByteArrayOutputStream();
        workbook.save(pdfDocument, saveOptions);
        return pdfDocument.toByteArray();
    };
}

代碼:WordPDFConverter.java

/**
 * This class holds the algorithm for converting WORD 
 * documents to PDF.
 * @author Hussein
 *
 */
public class WordPDFConverter implements Converter {
 
    @Override
    public byte[] convertToPDF(byte[] fileBytes) throws Exception {
        InputStream input = new ByteArrayInputStream(fileBytes);
        com.aspose.words.Document wordDocument = new com.aspose.words.Document(input);
        ByteArrayOutputStream pdfDocument = new ByteArrayOutputStream();
        wordDocument.save(pdfDocument, SaveFormat.PDF);
        return pdfDocument.toByteArray();
    }
}

代碼:PDFConverter.java

public class PDFConverter {
 
    /**
     * This method accepts as input the document to be converted and 
     * returns the converted one.
     * @param fileBytes
     * @throws Exception 
     */
    public byte[] convertToPDF(Converter converter, byte[] fileBytes) throws Exception
    {
        return converter.convertToPDF(fileBytes);
    }
}

當(dāng)調(diào)用convertToPDF()時(shí),我們強(qiáng)制用戶決定應(yīng)該使用哪種轉(zhuǎn)換算法。

2. 這樣做的好處是什么?!

關(guān)注點(diǎn)分離(高內(nèi)聚/低耦合): 現(xiàn)在 PDFConverter 類對(duì)程序中使用的轉(zhuǎn)換算法一無(wú)所知,它主要關(guān)注的是為用戶提供各種轉(zhuǎn)換特性,而關(guān)心轉(zhuǎn)換是如何進(jìn)行的?,F(xiàn)在,我們可以隨時(shí)替換底層轉(zhuǎn)換框架,只要我們能夠返回預(yù)期的結(jié)果,就不會(huì)人會(huì)知道。

單一職責(zé): 創(chuàng)建抽象層并將每個(gè)動(dòng)態(tài)行為移到多帶帶的類之后,我們實(shí)際上刪除了 convertToPDF() 方法在以前初始設(shè)計(jì)中的的多重職責(zé),現(xiàn)在它只有一個(gè)職責(zé),就是將用戶的請(qǐng)求委托給抽象的轉(zhuǎn)換層。此外,轉(zhuǎn)換器接口的每個(gè)實(shí)現(xiàn)類現(xiàn)在都有一個(gè)單一的責(zé)任,即將某些文檔類型轉(zhuǎn)換為PDF。因此,每個(gè)組件都有一個(gè)被修改的理由,因此沒(méi)有回歸。

打開(kāi)/關(guān)閉程序: 我們的程序現(xiàn)在對(duì)擴(kuò)展開(kāi)放,并且對(duì)修改關(guān)閉,當(dāng)我們?cè)谖磥?lái)想要支持一些新的文檔類型時(shí),只需要從 Converter 接口創(chuàng)建一個(gè)新的實(shí)現(xiàn)類,并且不需要修改 PDFConverter 工具,因?yàn)楝F(xiàn)在我們的工具依賴于抽象。

3. 從這篇文章中學(xué)到的設(shè)計(jì)原則

以下是構(gòu)建應(yīng)用程序架構(gòu)時(shí)要遵循的最佳設(shè)計(jì)實(shí)踐:

將程序劃分為幾個(gè)模塊,并在每個(gè)模塊的頂部添加一個(gè)抽象層。

有利于抽象實(shí)現(xiàn):一定要依賴抽象層,這將有利于程序?qū)?lái)的擴(kuò)展,抽象應(yīng)該應(yīng)用于程序的動(dòng)態(tài)部分(最有可能經(jīng)常改變的部分),不一定在所有的部分,因?yàn)樵谶^(guò)度使用的情況下是你的代碼變得非常復(fù)雜。

確定程序的不同方面,并將它們與保持不變的部分分開(kāi)。

不要重復(fù)自己:永遠(yuǎn)把重復(fù)的功能在一些工具類中,并使其通過(guò)整個(gè)程序訪問(wèn),這會(huì)使你的修改變得容易得多。

通過(guò)抽象層隱藏低級(jí)實(shí)現(xiàn):低級(jí)模塊有很高的可能性會(huì)定期更改,因此將其與高級(jí)模塊分開(kāi)。

每個(gè)類/方法/模塊應(yīng)該有一個(gè)理由去改變,所以為了減少回歸,總是給每一個(gè)類單一的責(zé)任。

關(guān)注點(diǎn)分離:每個(gè)模塊都知道其他模塊做什么,但是它自己不知道該怎么做。

作者簡(jiǎn)介:
HUSSEINTEREK: programmergate.com的創(chuàng)始人,對(duì)軟件工程和所有與java相關(guān)的東西都充滿激情。

歡迎掃描二維碼關(guān)注公眾號(hào),每天推送我翻譯的技術(shù)文章。

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://specialneedsforspecialkids.com/yun/67515.html

相關(guān)文章

  • []每位開(kāi)發(fā)者都應(yīng)該知道SOLID原則

    摘要:開(kāi)閉原則軟件實(shí)體類,模塊,函數(shù)應(yīng)該是可以擴(kuò)展的,而不是修改。函數(shù)并不符合開(kāi)閉原則,因?yàn)橐坏┯行聞?dòng)物出現(xiàn),它需要修改代碼。 By Chidume Nnamdi | Oct 9, 2018 原文 面向?qū)ο蟮木幊填愋蜑檐浖_(kāi)發(fā)帶來(lái)了新的設(shè)計(jì)。 這使開(kāi)發(fā)人員能夠在一個(gè)類中組合具有相同目的/功能的數(shù)據(jù),來(lái)實(shí)現(xiàn)單獨(dú)的一個(gè)功能,不必關(guān)心整個(gè)應(yīng)用程序如何。 但是,這種面向?qū)ο蟮木幊踢€是會(huì)讓開(kāi)發(fā)者困惑或...

    go4it 評(píng)論0 收藏0
  • Design Pattern – Overview(

    摘要:設(shè)計(jì)模式是軟件開(kāi)發(fā)人員在整個(gè)軟件開(kāi)發(fā)的過(guò)程中面臨普遍問(wèn)題的解決方案。這些作者被統(tǒng)稱為四人幫。根據(jù)這些作者的觀念,設(shè)計(jì)模式主要是基于一下幾種面向?qū)ο蟮脑O(shè)計(jì)原則。例如,單例模式表示使用單一對(duì)象。我們還將討論另外一個(gè)類別的設(shè)計(jì)模式。 原文鏈接譯者:smallclover個(gè)人翻譯,水平有限,如有錯(cuò)誤歡迎指出,謝謝! 設(shè)計(jì)模式-概述 設(shè)計(jì)模式體現(xiàn)了經(jīng)驗(yàn)豐富的面向?qū)ο筌浖_(kāi)發(fā)人員的最佳實(shí)踐。設(shè)計(jì)模...

    WilsonLiu95 評(píng)論0 收藏0
  • PHPer書(shū)單

    摘要:想提升自己,還得多看書(shū)多看書(shū)多看書(shū)下面是我收集到的一些程序員應(yīng)該看得書(shū)單及在線教程,自己也沒(méi)有全部看完。共勉吧當(dāng)然,如果你有好的書(shū)想分享給大家的或者覺(jué)得書(shū)單不合理,可以去通過(guò)進(jìn)行提交。講師溫銘,軟件基金會(huì)主席,最佳實(shí)踐作者。 想提升自己,還得多看書(shū)!多看書(shū)!多看書(shū)!下面是我收集到的一些PHP程序員應(yīng)該看得書(shū)單及在線教程,自己也沒(méi)有全部看完。共勉吧!當(dāng)然,如果你有好的書(shū)想分享給大家的或者...

    jimhs 評(píng)論0 收藏0
  • ELSE 技術(shù)周刊(2017.10.16期)

    摘要:前端中的計(jì)算機(jī)領(lǐng)域的通常認(rèn)為起源于。并對(duì)其主要內(nèi)容作了自己的解讀。搬到另一個(gè)地區(qū)會(huì)導(dǎo)致名氣降低。年度報(bào)告,年最受歡迎的編程語(yǔ)言年上最流行的種編程語(yǔ)言及前十最火熱的項(xiàng)目排行榜,分別由及登頂。技術(shù)周刊由小組出品,匯聚一周好文章,周刊原文。 showImg(https://segmentfault.com/img/bVWHC4?w=1000&h=710); 本期推薦 反擊爬蟲(chóng),前端工程師的腦...

    0xE7A38A 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<