選擇結構(if..else..,switch,try..catch..)的拆分

來源:互聯網
上載者:User

編程中經常遇到很多條件,以及條件套條件的情況,以至於一個方法會寫得非常地長。有多種方法可以規避這個問題。比如反射,策略模式,表驅動等等。先拋開這些方法不講,從根本需求來探索這個過程。

 

一個switch結構可能是這樣:

swicth(case)

  case 1:

    //do1

    break;

  case 2:

    //do2

    break;

  .....

這裡注釋的do部分代碼可能會是很多很多行,以及嵌套switch,if結構。

進一步,這個模型演化成

swicth(case)

  case 1:

    do1();

    break;

  case 2:

    do2();

    break;

  .....

 

do1(){}

do2(){}

 

也就是將裡面的代碼模組化。這個方法有效減小了一個方法的代碼長度。實際上這就是一個映射關係的調用。建立映射關係,用Hash結構和delegate就可以避免使用switch了。

 

delegate void funtionptr();

 

Dictionary<int, funtionptr> dict = new Dictionary<int, funtionptr>();

dict.Add(1,do1);

dict.Add(2,do2);

 

int parm = 0;

if(dict.ContainKey(parm)){

  dict[parm].Invoke();

 

do1(){}

do2(){}

 

這個方法實際上就是表驅動,因為C#中一般不用指標,因此用delegate代替了指標的作用。而java中既沒有指標也沒有delegate怎麼辦呢?那就用介面類比指標。

(這裡就用C#的文法了,不使用JAVA了)

interface FactionFace{

  void do();

class FactionFaceImpl1 : FactionFace{

  public void do(){}

class FactionFaceImpl2 : FactionFace{

  public void do(){}

Dictionary<int, FactionFace> dict = new Dictionary<int, FactionFace>();

dict.Add(1,new FactionFaceImpl1());

dict.Add(2,new FactionFaceImpl2());

 

int parm = 0;

if(dict.ContainKey(parm)){

  dict[parm].do();

可以看出,實際上,上面的代碼就是策略模式的簡單實現了。(OH~~原理策略模式這麼就來的~~)

 

可以看出,這裡實際上是依靠一個字典來維護條件和調用的關係的。那如果沒有這個字典來維護怎麼辦呢?代碼再次演化:

interface FactionFace{

  void do();

class FactionFaceImpl1 : FactionFace{

  public void do(){}

class FactionFaceImpl2 : FactionFace{

  public void do(){}

 

 

string parm = "FactionFaceImpl2";

FactionFace ff = Type.GetType(parm) as FactionFace;

ff.do();

 

OH~~這就是簡單的反射了。再複雜一些就可以搞成原廠模式,外掛程式模式了。

 

可以看出,用字典來維護映射關係就可以避免使用反射。(這個是不是一般規律,貧道沒本事證明,起碼這裡是適應的。)

 

 

再來看try...catch...

delegate void forException(Exception ex);

 

public void forAException(Exception ex) {Console.WriteLine("AException");}
public void forAAException(Exception ex) {Console.WriteLine("AAException");}
public void forBException(Exception ex) {Console.WriteLine("BException");}

 

public void test() {

  Dictionary<int, forException> dict = new Dictionary<int, forException>();

  dict.Add(0, forAException);

  dict.Add(1, forAException);

  dict.Add(11, forAAException);

  dict.Add(2, forBException);

  try {

    throw new AAException();

  } catch (Exception ex) 

  {

    if (ex is OException) {

      OException eex = ex as OException;

      if (dict.ContainsKey(eex.Index)) {

         dict[eex.Index].Invoke(ex);

      }

    }

  }

}

 

public class OException : Exception {public virtual int Index { get { return 0; } }}
public class AException : OException {public override int Index {get {return 1;}}}
public class AAException : AException {public override int Index {get {return 11;}}}
public class BException : OException {public override int Index {get {return 2;}}

 

這裡為啥要有個Index屬性呢?其實就是建立個對應的關係,而不是靠名字去維護。去掉這個屬性,直接使用ex.GeType()然後擷取名字類名也一樣可以建立對應關係。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.