呆羊在曬太陽(yáng)  
          公告
          • Y:哦,是你呀。
            X:我現(xiàn)在正在忙。
            Y:忙什么?
            X:呵呵,今天出太陽(yáng)了,我把錢(qián)搬出來(lái)曬一曬。
            ***********************
            abc
            小叉
            很高興能結(jié)識(shí)大家!
            ***********************
          日歷
          <2006年4月>
          2627282930311
          2345678
          9101112131415
          16171819202122
          23242526272829
          30123456
          統(tǒng)計(jì)
          • 隨筆 - 164
          • 文章 - 2
          • 評(píng)論 - 196
          • 引用 - 0

          導(dǎo)航

          常用鏈接

          留言簿(7)

          隨筆分類(lèi)(158)

          文章分類(lèi)(2)

          相冊(cè)

          log

          搜索

          •  

          積分與排名

          • 積分 - 71010
          • 排名 - 779

          最新評(píng)論

          閱讀排行榜

           
          作者:軟件的信雅達(dá) 來(lái)源:北京火龍果軟件工程技術(shù)中心 http://www.csai.cn 2006年3月21日

            所謂單一職責(zé)原則,就是就一個(gè)類(lèi)而言,應(yīng)該僅有一個(gè)引起它的變化的原因。換句話說(shuō),一個(gè)類(lèi)的功能要單一,只做與它相關(guān)的事情。
          這個(gè)原則是最簡(jiǎn)單、最容易理解,卻是最不容易做到的事情。這個(gè)原則的道理誰(shuí)都理解,可是在實(shí)踐中呢?

            我們來(lái)看一個(gè)例子:

          if(action.equals("load")&&tab.equals("1")){
          request.setAttribute("tabId",tab);
          form.set("tabId",tab);
          speciManager.loadIncrement(actionForm, request, tab);
          }
          if(action.equals("Save")&&tab.equals("1")){
          System.out.println("inter increment save action");
          ……
          request.setAttribute("tabId",tab);
          }
          if(action.equals("load")&&tab.equals("2")){
          request.setAttribute("tabId",tab);
          form.set("tabId",tab);
          speciManager.loadMeasureMent(actionForm, request, tab);
          }
          if(action.equals("Save")&&tab.equals("2")){
          ……
          System.out.println("inter increment save action");
          speciManager.loadIncrement(actionForm, request, tab);
          form.set("tabId",tab);
          request.setAttribute("tabId",tab);

          }

            一看就知道這個(gè)類(lèi)做了太多的工作,它既要load一個(gè)tab為1的頁(yè)面和一個(gè)tab為2的頁(yè)面;又要save一個(gè)tab為1頁(yè)面和一個(gè)tab為2的頁(yè)面。這個(gè)類(lèi)的代碼我只截取了里面很少的一部分,絕大部分的代碼我都省略掉了。這段代碼寫(xiě)到最后是越來(lái)越混亂,直到最后失敗。

            對(duì)照著這個(gè)例子,我們?cè)賮?lái)分析一下為什么要遵守單一職責(zé)愿則:

            第一、有助于我們分析和編碼的思路的清晰。當(dāng)你的代碼里有了三層或以上的if語(yǔ)句或for語(yǔ)句的嵌套的時(shí)候,你不要跟我說(shuō),你已經(jīng)把問(wèn)題分析得很清楚了。多層嵌套的if或for語(yǔ)句只能說(shuō)明你還沒(méi)有把問(wèn)題分析清楚。

            第二、使我們的編碼、測(cè)試和維護(hù)變得簡(jiǎn)單。

            第三、將一個(gè)個(gè)復(fù)雜的問(wèn)題簡(jiǎn)單化以后,易于代碼的重用。當(dāng)你的代碼的多個(gè)功能攪和在一起的時(shí)候,你是沒(méi)辦法考慮代碼的重用的,因?yàn)槟愕拿恳惶幋a都有不同。

            第四、易于系統(tǒng)的擴(kuò)展。

            好了,在這里一二三四的列舉單一職責(zé)的原則不管用,我們需要看看實(shí)際的效果才好?,F(xiàn)在我們就來(lái)看看模式是怎么來(lái)遵守這一原則的:
          首先,我們來(lái)看簡(jiǎn)單工廠模式。工廠類(lèi)只有一個(gè)功能,就是產(chǎn)生一個(gè)個(gè)的對(duì)象產(chǎn)品。就這么一個(gè)簡(jiǎn)單的功能,但如果我們不把它拿出來(lái),在客戶(hù)端就會(huì)出現(xiàn)這樣的代碼:

          if(type.equals(“apple”))
          {
          Apple apple = new Apple();
          ……
          }
          else if(type.equals(“orange”))
          {
          Orange orange = new Orange();
          ……
          }
          else if(type.equals(“Banana”))
          {
          Banana banana = new Banana();
          ……
          }

            有了工廠,我們的客戶(hù)端就變成這樣:

          Fruit fruit = Factory.getInstance(type);
          ……

            我們的客戶(hù)端調(diào)用起來(lái)多么的簡(jiǎn)單,而且系統(tǒng)擴(kuò)展起來(lái)也與客戶(hù)端無(wú)關(guān)。

            我們?cè)賮?lái)看模板方法模式。

          public abstract class Template {

          public void totalAction()
          {
          commonAction();
          differentAction();
          }
          private void commonAction()
          {
          //......
          }
          public abstract void differentAction();

          }

            這是一個(gè)模板類(lèi),它只做了一件事,就是所有子類(lèi)的共同行為;然后去由它的子類(lèi)單獨(dú)完成自己的不同的行為。

            這樣的蓄意讓類(lèi)的職責(zé)單一,擁有的好處是:第一、所有的子類(lèi)的共同行為,只在模板類(lèi)里構(gòu)造一次,實(shí)現(xiàn)了代碼的重用。第二、將各子類(lèi)不同的行為分配到各子類(lèi)里去,使得子類(lèi)極為簡(jiǎn)單,易于實(shí)現(xiàn)。

            命令模式和策略模式的原理都相同,命令模式是對(duì)行為的封裝,而策略模式是對(duì)算法的封裝。兩者都是要把相同的關(guān)注點(diǎn)和對(duì)他們的調(diào)用分離開(kāi),如命令模式是將行為和對(duì)它們的調(diào)用分離開(kāi),而策略模式是將算法和對(duì)它們的調(diào)用分離開(kāi)。這里我們只以命令模式來(lái)說(shuō)明問(wèn)題。

          If(condition1)
          {
          //condition1下的行為
          doThing1();
          }
          else if(condition2)
          {
          //condition2下的行為
          doThing2();
          }
          else if(condition3)
          {
          //condition3下的行為
          doThing3();
          }
          ……

            命令模式可以方便的對(duì)上面的代碼進(jìn)行優(yōu)化:

          public interface Common
          {
          public void doThing();
          }
          public class Common1 implements Common
          {
          public void doThing()
          {
          //condition1下的行為
          doThing1();
          }
          }
          public class Common2 implements Common
          {
          public void doThing()
          {
          //condition2下的行為
          doThing2();
          }
          }
          public class Common13implements Common
          {
          public void doThing()
          {
          //condition3下的行為
          doThing3();
          }

          }

            客戶(hù)端:

          Common common;
          If(condition1) common = new Common1();
          else if(condition2) common = new Common2();
          else if(condition3) common = new Common3();
          common.doThing();

            命令模式通過(guò)將行為從調(diào)用者那里分離出來(lái),達(dá)到了下面幾個(gè)目的:第一,分離關(guān)注,對(duì)各個(gè)行為進(jìn)行單獨(dú)的關(guān)注,減少錯(cuò)誤的出現(xiàn)。不管是對(duì)行為類(lèi)還是它的調(diào)用者,都變得簡(jiǎn)單。第二,行為類(lèi)通過(guò)對(duì)接口的實(shí)現(xiàn),使得它們的調(diào)用者可以對(duì)它們進(jìn)行動(dòng)態(tài)綁定,增加了程序的靈活性和擴(kuò)展性。

            代理模式將一個(gè)類(lèi)的核心功能和它的附加功能區(qū)別開(kāi)來(lái),分別放在不同的類(lèi)里面,從而使每一個(gè)類(lèi)的功能更加單一。

          Public interface ProxyInterface
          {
          public void doing();
          }
          public class MainClass implements ProxyInterface
          {
          public void doing()
          {
          //core function
          ……
          }
          }
          public class ProxyClass implements ProxyInterface
          {
          private ProxyInterface core = new MainClass();
          public void doing()
          {
          //appending to do
          ……
          //main function
          core.doing();
          }
          }

            我們可以看到,通過(guò)代理模式,上面的MainClass類(lèi)用來(lái)實(shí)現(xiàn)核心功能,而ProxyClass類(lèi)用來(lái)實(shí)現(xiàn)附加功能,這樣使得兩個(gè)類(lèi)的功能都非常簡(jiǎn)單,易于實(shí)現(xiàn)。

            總之,單一職責(zé)原則是一個(gè)既簡(jiǎn)單又實(shí)用的原則。我們遵守了這一原則,可能會(huì)多寫(xiě)一些類(lèi)和代碼,但磨刀不誤砍柴工。該原則既有利于我們編碼思路的清晰,又大大增強(qiáng)了代碼的可維護(hù)性和擴(kuò)展性。
          還等什么呢?

          posted on 2006-04-21 10:00 小叉 閱讀(179) 評(píng)論(0)  編輯  收藏 所屬分類(lèi): work
           
          Copyright © 小叉 Powered by: 博客園 模板提供:滬江博客
          主站蜘蛛池模板: 隆昌县| 闽侯县| 临汾市| 平凉市| 留坝县| 海兴县| 潞西市| 绥芬河市| 友谊县| 金山区| 万载县| 盐池县| 海淀区| 凤台县| 偃师市| 开平市| 远安县| 米易县| 合水县| 托里县| 华阴市| 留坝县| 天等县| 明溪县| 洪洞县| 红河县| 临颍县| 长汀县| 张掖市| 枝江市| 外汇| 贵阳市| 徐汇区| 荥经县| 岱山县| 晋城| 新野县| 习水县| 小金县| 临沧市| 南充市|