日本好好热aⅴ|国产99视频精品免费观看|日本成人aV在线|久热香蕉国产在线

  • <cite id="ikgdy"><table id="ikgdy"></table></cite>
    1. 西西軟件園多重安全檢測(cè)下載網(wǎng)站、值得信賴的軟件下載站!
      軟件
      軟件
      文章
      搜索

      首頁(yè)編程開發(fā)C#.NET → 關(guān)于用C#實(shí)現(xiàn)B/S與C/S平臺(tái)之間功能通用性的設(shè)計(jì)思路

      關(guān)于用C#實(shí)現(xiàn)B/S與C/S平臺(tái)之間功能通用性的設(shè)計(jì)思路

      相關(guān)軟件相關(guān)文章發(fā)表評(píng)論 來(lái)源:liping13599168時(shí)間:2010/3/1 17:28:40字體大。A-A+

      作者:admin點(diǎn)擊:1172次評(píng)論:0次標(biāo)簽: C/S

      • 類型:備份還原大小:46.7M語(yǔ)言:英文 評(píng)分:6.6
      • 標(biāo)簽:
      立即下載

      設(shè)計(jì)場(chǎng)景

      1. 有A,B兩組開發(fā)人員進(jìn)行某個(gè)系統(tǒng)的開發(fā),其中A組開發(fā)人員負(fù)責(zé)B/S平臺(tái)的功能設(shè)計(jì)與開發(fā),B組開發(fā)人員負(fù)責(zé)C/S平臺(tái)的功能設(shè)計(jì)與開發(fā)。

      2. 在當(dāng)時(shí)的項(xiàng)目背景下,B/S端的項(xiàng)目是先啟動(dòng)的,而A組的開發(fā)人員還沒有意識(shí)到將來(lái)需要配合C/S端來(lái)做功能協(xié)作,因此產(chǎn)生的問(wèn)題就是,前期的系統(tǒng)架構(gòu)設(shè)計(jì)沒有過(guò)多地考慮以適應(yīng)多個(gè)平臺(tái)下的功能適應(yīng)性。當(dāng)然,從B/S端的設(shè)計(jì)角度上看,系統(tǒng)架構(gòu)還算比較清晰。接著A組的開發(fā)人員就在這樣的情況下,完成了系統(tǒng)功能的實(shí)現(xiàn)。

      3. 接著高層領(lǐng)導(dǎo)告訴項(xiàng)目經(jīng)理需要做一套C/S架構(gòu)的軟件來(lái)配合B/S端平臺(tái)的使用,而這時(shí)候B/S端的功能實(shí)現(xiàn)已經(jīng)基本完成,B組開發(fā)人員成立。

      4. 在B組架構(gòu)人員開始設(shè)計(jì)架構(gòu)的時(shí)候,并沒有衍用B/S端的開發(fā)架構(gòu),很多基礎(chǔ)架構(gòu)(如分層模式、數(shù)據(jù)庫(kù)結(jié)構(gòu)、數(shù)據(jù)實(shí)體類等等)都存在很大的差異(C/S端項(xiàng)目在初期的要求沒有那么高,有的功能能削減掉就削減掉),后來(lái)B組架構(gòu)人員發(fā)現(xiàn)需求文檔上的有個(gè)功能和B/S平臺(tái)上的某個(gè)功能是一樣的,于是他和A組架構(gòu)人員進(jìn)行交流,希望負(fù)責(zé)B/S平臺(tái)上這個(gè)功能的開發(fā)人員能夠幫助C/S平臺(tái)幫助完成這一功能。于是A組的Leepy就匆匆忙忙地上陣了。

      5. 最初Leepy同學(xué)因?yàn)樵贐/S平臺(tái)上也有大量的任務(wù)需要完成,任務(wù)趕得狠,又收到這樣一個(gè)“功能復(fù)制”的任務(wù),心想:“那么就先把功能復(fù)制一份上去,然后如果B/S平臺(tái)上的功能有更新,就同步修改C/S平臺(tái)就好”。于是打開C/S平臺(tái)的項(xiàng)目,發(fā)現(xiàn)和B/S平臺(tái)項(xiàng)目的差異性比較大,包括數(shù)據(jù)庫(kù)結(jié)構(gòu)和數(shù)據(jù)實(shí)體類等等,更頭疼的是這里采用的是.net framework 2.0進(jìn)行開發(fā),而B/S端采用的是.net framework 3.5進(jìn)行開發(fā),而且從功能上,Leepy使用大量的3.5的屬性。要直接復(fù)用是不可能的,還需要調(diào)整相應(yīng)的代碼。

      6. 于是C/S平臺(tái)該功能出來(lái)了,運(yùn)行得還行,F(xiàn)在才是郁悶的開始,因?yàn)樵摴δ軐儆谄脚_(tái)的核心模塊,于是B/S平臺(tái)上要時(shí)刻調(diào)整得比較大,所以同步的C/S端的功能也要相應(yīng)的調(diào)整,然后又運(yùn)行完好。于是問(wèn)題出來(lái)了,這樣反復(fù)地修改導(dǎo)致系統(tǒng)(C/S和B/S)維護(hù)成本很高,架構(gòu)間的設(shè)計(jì)耦合度太大。剛開始Leepy抱怨為什么C/S端沒有和B/S端統(tǒng)一架構(gòu),至少底層基礎(chǔ)平臺(tái)能夠設(shè)計(jì)得具有可擴(kuò)展性,光光抱怨無(wú)法解決問(wèn)題,因?yàn)檫@是項(xiàng)目的人員配置的問(wèn)題。于是,Leepy想到了必須對(duì)該功能進(jìn)重構(gòu),使用一個(gè)通用的組件進(jìn)行抽象,而實(shí)際實(shí)現(xiàn)的,如C/S、B/S端具體應(yīng)用,只要維護(hù)相應(yīng)的業(yè)務(wù)代碼。

       

      設(shè)計(jì)思路

      1. 說(shuō)完場(chǎng)景,現(xiàn)在說(shuō)說(shuō)動(dòng)手的部分。以一個(gè)中學(xué)生教育平臺(tái)591up的網(wǎng)站為例,以及教育平臺(tái)客戶端的輔助軟件。

      這一功能實(shí)現(xiàn)一份Word文檔試卷的導(dǎo)入保存并分解文檔中的試題,將試題逐個(gè)保存入庫(kù)(解析出來(lái)的試題部分還包括很多屬性,如答案、知識(shí)點(diǎn)、解題關(guān)鍵點(diǎn)等很多屬性)。現(xiàn)在B/S平臺(tái)和C/S平臺(tái)都需要這個(gè)功能,但是B/S平臺(tái)和C/S平臺(tái)下的相關(guān)數(shù)據(jù)庫(kù)實(shí)體類,設(shè)計(jì)不很統(tǒng)一,導(dǎo)致維護(hù)系統(tǒng)的成本很高。于是,考慮是否能將解析器的設(shè)計(jì)與業(yè)務(wù)功能分開,將試卷解析器設(shè)計(jì)成通用的組件,而與B/S端和C/S端的業(yè)務(wù)代碼徹底分開,對(duì)于解析的邏輯代碼(基礎(chǔ)代碼)在兩端都可以引用到,而B/S端和C/S端所需要做得就是調(diào)整業(yè)務(wù)代碼,并不需要關(guān)解析的基礎(chǔ)代碼是什么,組件與業(yè)務(wù)代碼解耦。如下圖所示:

       

      2. 現(xiàn)在講講具體設(shè)計(jì)思路,先從試卷解析器基礎(chǔ)組件開始(為了簡(jiǎn)化,該范例是削弱版的),創(chuàng)建一個(gè).net 2.0的類庫(kù)(為了適應(yīng)客戶端.net 2.0的配置)聲明一個(gè)試卷解析器范型接口:

      代碼
      /// <summary>
      /// 試卷轉(zhuǎn)換器泛型接口
      /// </summary>
      public interface IPaperConvertor<TIn, TOut>
      {
      /// <summary>
      /// 轉(zhuǎn)換方法
      /// </summary>
      /// <param name="tIn">轉(zhuǎn)換輸入類型</param>
      /// <param name="helper">Word處理接口</param>
      /// <returns>轉(zhuǎn)換輸出類型</returns>
      TOut Convert(TIn tIn, IWordHelper helper);
      }
      其中TIn類型作為輸入類型,TOut類型作為輸出類型(TIn將來(lái)作為業(yè)務(wù)代碼中實(shí)際的輸入類型,如WordInfo類;TOut作為實(shí)際輸出類型,如PaperInfo類;IWordHelper為一個(gè)Word處理接口,這里的實(shí)現(xiàn)是Microsoft.Office.Interop.Word)

      考慮到轉(zhuǎn)換器在轉(zhuǎn)換過(guò)程Convert中,會(huì)產(chǎn)生一系列的步驟,首先對(duì)于轉(zhuǎn)換這個(gè)過(guò)程進(jìn)行細(xì)化,分解成各個(gè)步驟:

      代碼
      public abstract class BasePaperConvertor<TIn, TOut> : IPaperConvertor<TIn, TOut>
      where TIn : class, new()
      where TOut : class, new()
      {
      //成員

      /// <summary>
      /// 輸出試卷實(shí)體
      /// </summary>
      protected TOut Paper { get; set; }

      /// <summary>
      /// 輸入Word條件
      /// </summary>
      protected TIn WordInfo { get; set; }

      #region Word操作實(shí)體屬性
      /// <summary>
      /// Word操作實(shí)體屬性
      /// </summary>
      protected IWordHelper WordHelper { get; set; }
      #endregion

      //公共方法

      /// <summary>
      /// 轉(zhuǎn)換方法
      /// </summary>
      /// <param name="tIn"></param>
      /// <returns></returns>
      public virtual TOut Convert(TIn tIn, IWordHelper helper)
      {
      WordHelper = helper;
      WordInfo = tIn;
      Paper = Initialize(tIn);

      if (Prepare())
      Execute();

      Finished();

      return Paper;
      }

      //抽象方法

      /// <summary>
      /// 初始化
      /// </summary>
      /// <param name="tIn"></param>
      /// <returns></returns>
      protected abstract TOut Initialize(TIn tIn);

      /// <summary>
      /// 預(yù)裝載
      /// </summary>
      /// <param name="tOut"></param>
      /// <returns></returns>
      protected abstract bool Prepare();

      /// <summary>
      /// 執(zhí)行
      /// </summary>
      /// <param name="tOut"></param>
      protected abstract void Execute();

      /// <summary>
      /// 完成
      /// </summary>
      protected abstract void Finished();
      }
      從代碼中,我們可以看到Convert方法中調(diào)用了一系列的抽象方法,首先對(duì)于輸入類型進(jìn)行初始化(Initialize),接著通過(guò)輸入類型預(yù)裝載(Prepare),如果預(yù)裝載成功,并開始執(zhí)行。最后完成(Finished)所有的工作。

      接著,需要定義一個(gè)包含Word解析邏輯代碼的抽象類,這里使用Microsoft.Office.Interop.Word進(jìn)行Office編程,于是創(chuàng)建名為

      OfficeWordPaperConvertor.cs的類:

      OfficeWordPaperConvertor
      /// <summary>
      /// 試卷解析器泛型抽象類
      /// </summary>
      public abstract class OfficeWordPaperConvertor<TIn, TQuestion, TOut> : BasePaperConvertor<TIn, TOut>
      where TIn : class, new()
      where TQuestion : class, new()
      where TOut : class, new()
      {

      #region 試卷Word結(jié)構(gòu)信息
      /// <summary>
      /// 試卷Word結(jié)構(gòu)信息
      /// </summary>
      protected PaperWordInfo PaperWordInfo { get; private set; }
      #endregion

      #region Word操作輔助類屬性
      private OfficeWordHelper _OfficeWordHelper;
      /// <summary>
      /// Word操作輔助類屬性
      /// </summary>
      protected OfficeWordHelper OfficeWordHelper
      {
      get
      {
      if (_OfficeWordHelper == null)
      _OfficeWordHelper = GetWordHelper();
      return _OfficeWordHelper;
      }
      }
      #endregion

      #region 預(yù)處理試卷
      /// <summary>
      /// 預(yù)處理試卷
      /// </summary>
      /// <param name="tOut"></param>
      /// <returns></returns>
      protected override bool Prepare()
      {
      //過(guò)濾試卷無(wú)效信息
      FilterPaper();

      //解析試卷
      ParsePaper();

      return true;
      }
      #endregion

      #region 執(zhí)行試卷
      /// <summary>
      /// 執(zhí)行試卷
      /// </summary>
      /// <param name="tOut"></param>
      protected override void Execute()
      {
      for (int i = 0; i < PaperWordInfo.Count; i++)
      {
      QuestionWordInfo questionWordInfo = PaperWordInfo[i];

      //執(zhí)行試題
      ExcuteQuestion(questionWordInfo);
      }
      }
      #endregion

      #region 完成時(shí)調(diào)用
      /// <summary>
      /// 完成時(shí)調(diào)用
      /// </summary>
      protected override void Finished()
      {
      //這里進(jìn)行完成時(shí)調(diào)用的實(shí)現(xiàn)

      //..
      }
      #endregion

      //虛方法

      /// <summary>
      /// 過(guò)濾試卷無(wú)效信息
      /// </summary>
      protected virtual void FilterPaper()
      {

      }

      /// <summary>
      /// 解析試卷
      /// </summary>
      protected virtual void ParsePaper()
      {
      PaperWordInfo = new PaperWordInfo();

      //通過(guò)計(jì)算 OfficeWordHelper.Document.Text 得到文本中的題目數(shù),這里省去這段邏輯
      PaperWordInfo.AddQuestion(new QuestionWordInfo { StartIndex = 0, EndIndex = 0 });
      PaperWordInfo.AddQuestion(new QuestionWordInfo { StartIndex = 1, EndIndex = 1 });
      PaperWordInfo.AddQuestion(new QuestionWordInfo { StartIndex = 2, EndIndex = 2 });
      }

      /// <summary>
      /// 執(zhí)行試題
      /// </summary>
      /// <param name="questionWordInfo"></param>
      protected virtual void ExcuteQuestion(QuestionWordInfo questionWordInfo)
      {
      string[] array = OfficeWordHelper.Document.Text.Split(new string[] { "\r\n" }, StringSplitOptions.RemoveEmptyEntries);

      //創(chuàng)建試題解析器實(shí)體
      TQuestion question = CreateQuestionConvertor(WordInfo, array[questionWordInfo.StartIndex]);

      //將試題添加到試卷中
      if (question != null) AddQuestion(question);
      }

      #region 獲取Word工具類
      /// <summary>
      /// 獲取Word工具類
      /// </summary>
      /// <returns></returns>
      protected OfficeWordHelper GetWordHelper()
      {
      return WordHelper as OfficeWordHelper;
      }
      #endregion

      //抽象方法

      /// <summary>
      /// 創(chuàng)建試題解析器實(shí)體
      /// </summary>
      /// <param name="subject"></param>
      protected abstract TQuestion CreateQuestionConvertor(TIn tIn, string wordContent);

      /// <summary>
      /// 將試題添加到試卷中
      /// </summary>
      /// <param name="tPart"></param>
      /// <param name="tQuestion"></param>
      protected abstract void AddQuestion(TQuestion tQuestion);
      }
      為何這里沒有重寫Initialize方法呢?由于這里需要將Initialize暴露于業(yè)務(wù)代碼中,可以通過(guò)業(yè)務(wù)代碼來(lái)重寫該方法,如果業(yè)務(wù)組件沒有調(diào)用Initialize,將報(bào)錯(cuò)。

      這里Prepare方法主要完成一份Word文檔的信息過(guò)濾,并且將文檔中按照試題題號(hào)進(jìn)行拆分試題,形成試題列表。

      Execute方法完成一份試卷的執(zhí)行,通過(guò)試題列表將題目逐題入庫(kù)。

      Finshed方法在Execute之后,可通過(guò)事件委托告訴用戶解析已經(jīng)完成。

      在后面附加的例子中,我會(huì)引用OfficeWordHelper.Document.Text 等于“1.試題1\r\n2.試題2\r\n3.試題3”的文本字符串來(lái)模擬Word文檔中的文字(實(shí)際情況更

      加復(fù)雜,Word文檔中包括圖片,符號(hào),OLE對(duì)象等等,一切為了簡(jiǎn)化說(shuō)明,這里省略該步驟),說(shuō)明它拆分出來(lái)的試題有3道。QuestionWordInfo 類的

      StartIndex,EndIndex對(duì)應(yīng)試題所在行數(shù)索引。

      接著注意ExcuteQuestion這個(gè)方法,調(diào)用了CreateQuestionConvertor和AddQuestion兩個(gè)抽象方法。該兩個(gè)抽象方法將在業(yè)務(wù)組件中實(shí)現(xiàn)。

       

      試卷解析器基本設(shè)計(jì)實(shí)現(xiàn)了,現(xiàn)在看下試題解析器該如何實(shí)現(xiàn):

      聲明一個(gè)試題解析器范型接口:

      /// <summary>
      /// 試題轉(zhuǎn)換器泛型接口
      /// </summary>
      public interface IQuestionConvertor<TIn, TOut>
      {
      TOut Convert(TIn tIn, string wordContent);
      }
      其中TIn類型作為輸入類型,TOut類型作為輸出類型(TIn將來(lái)作為業(yè)務(wù)代碼中實(shí)際的輸入類型,如WordInfo類;TOut作為實(shí)際輸出類型,如QuestionInfo類)

      考慮到轉(zhuǎn)換器在轉(zhuǎn)換過(guò)程Convert中,會(huì)產(chǎn)生一系列的步驟,首先對(duì)于轉(zhuǎn)換這個(gè)過(guò)程進(jìn)行細(xì)化,分解成各個(gè)步驟:

      代碼
      public abstract class BaseQuestionConvertor<TIn, TOut> : IQuestionConvertor<TIn, TOut> where TIn : class, new()
      {
      //成員

      #region 輸出試卷屬性
      /// <summary>
      /// 輸出試卷實(shí)體
      /// </summary>
      protected TOut Question { get; set; }
      #endregion
      #region 輸入Word實(shí)體屬性
      /// <summary>
      /// 輸入Word實(shí)體屬性
      /// </summary>
      protected TIn WordInfo { get; set; }
      #endregion

      //公共方法

      #region 轉(zhuǎn)換方法
      /// <summary>
      /// 轉(zhuǎn)換方法
      /// </summary>
      /// <param name="tIn"></param>
      /// <param name="helper"></param>
      /// <returns></returns>
      public virtual TOut Convert(TIn tIn, string wordContent)
      {
      WordInfo = tIn;
      Question = Initialize(tIn);

      //解析試題
      TOut tOut = Execute(wordContent);

      //完成
      Finished();

      return tOut;
      }
      #endregion

      //抽象方法

      #region 初始化
      /// <summary>
      /// 初始化
      /// </summary>
      /// <param name="tIn"></param>
      /// <returns></returns>
      protected abstract TOut Initialize(TIn tIn);
      #endregion

      #region 執(zhí)行
      /// <summary>
      /// 執(zhí)行
      /// </summary>
      /// <param name="tOut"></param>
      protected abstract TOut Execute(string wordContent);
      #endregion

      #region 完成
      /// <summary>
      /// 完成
      /// </summary>
      protected abstract void Finished();
      #endregion
      }


      接著,需要定義一個(gè)包含Word解析邏輯代碼的抽象類,這里使用Microsoft.Office.Interop.Word進(jìn)行Office編程,于是創(chuàng)建名為

      OfficeWordQuestionConvertor.cs的類:

      OfficeWordQuestionConvertor /// <summary>
      /// 試題解析器泛型抽象類
      /// </summary>
      public abstract class OfficeWordQuestionConvertor<TIn, TOut> : BaseQuestionConvertor<TIn, TOut>
      where TIn : class, new()
      where TOut : class, new()
      {
      protected override TOut Execute(string wordContent)
      {
      ParseQuestionContent(wordContent);
      ParseDifficultyCode(wordContent);

      //...其他解析屬性,這里省略

      return Question;
      }

      #region 解析試題題干
      /// <summary>
      /// 解析試題題干
      /// </summary>
      /// <returns></returns>
      protected virtual void ParseQuestionContent(string questionText)
      {
      //通過(guò)questionText解析出試題提干,這里省略
      string content = questionText;
      SetQuestionContent(content);
      }
      #endregion

      #region 解析試題難度
      /// <summary>
      /// 解析試題難度
      /// </summary>
      /// <param name="questionText"></param>
      /// <returns></returns>
      protected virtual void ParseDifficultyCode(string questionText)
      {
      //通過(guò)questionText解析出難度文本,這里省略
      string difficulty = "A";
      SetDifficultyCode(difficulty);
      }
      #endregion

      //抽象方法

      /// <summary>
      /// 設(shè)置試題標(biāo)題
      /// </summary>
      /// <param name="text"></param>
      protected abstract void SetQuestionContent(string text);

      /// <summary>
      /// 設(shè)置試題難度
      /// </summary>
      /// <param name="difficulty"></param>
      protected abstract void SetDifficultyCode(string difficulty);
      }


      Execute方法通過(guò)Word文本內(nèi)容解析相應(yīng)試題的屬性(如題干、難度、是否系統(tǒng)試題等)。

      于是這里抽象出了兩個(gè)方法(按照需求來(lái)進(jìn)行方法擴(kuò)展),SetQuestionContent和SetDifficultyCode將在業(yè)務(wù)組件中實(shí)現(xiàn)。

       

      3. 現(xiàn)在開始創(chuàng)建其他項(xiàng)目,如下圖所示:

       

      其中WebApp為B/S平臺(tái)項(xiàng)目,WebApp.Lib為B/S平臺(tái)業(yè)務(wù)類庫(kù),兩個(gè)項(xiàng)目均采用.net framework 3.5;WinApp為C/S平臺(tái)項(xiàng)目,WinApp.Lib為C/S業(yè)務(wù)類庫(kù);

      注意到,WebApp.Lib和WinApp.Lib在數(shù)據(jù)實(shí)體類上存在差異(實(shí)際情況差異更大,不僅僅數(shù)據(jù)實(shí)體類上,這里為了簡(jiǎn)化),兩個(gè)項(xiàng)目均采用.net framework 2.0;

      WordConvertor即為上面說(shuō)的解析器組件。

      以WebApp.Lib為例,實(shí)現(xiàn)業(yè)務(wù)試卷和試題解析器:

      WebPaperConvertor .cs:

      代碼
      /// <summary>
      /// Web端試卷解析器
      /// </summary>
      public class WebPaperConvertor : OfficeWordPaperConvertor<WordInfo, QuestionInfo, PaperInfo>
      {
      /// <summary>
      /// 初始化試卷
      /// </summary>
      protected override PaperInfo Initialize(WordInfo wordInfo)
      {
      Paper = new PaperInfo();
      Paper.Title = wordInfo.PaperTitle;
      return Paper;
      }

      /// <summary>
      /// 創(chuàng)建試題解析器
      /// </summary>
      protected override QuestionInfo CreateQuestionConvertor(WordInfo wordInfo, string wordContent)
      {
      WebQuestionConvertor convertor = new WebQuestionConvertor();
      return convertor.Convert(wordInfo, wordContent);
      }

      /// <summary>
      /// 增加試題
      /// </summary>
      protected override void AddQuestion(QuestionInfo tQuestion)
      {
      if(Paper.QuestionInfoList == null)
      Paper.QuestionInfoList = new List<QuestionInfo>();
      Paper.QuestionInfoList.Add(tQuestion);
      }

      //其他業(yè)務(wù)擴(kuò)展...
      }

      WebQuestionConvertor .cs:

      代碼
      /// <summary>
      /// Web端試題解析器
      /// </summary>
      public class WebQuestionConvertor : OfficeWordQuestionConvertor<WordInfo, QuestionInfo>
      {
      /// <summary>
      /// 根據(jù)條件初始化試題
      /// </summary>
      protected override QuestionInfo Initialize(WordInfo wordInfo)
      {
      QuestionInfo questionInfo = new QuestionInfo();
      questionInfo.IsSystem = wordInfo.IsSystem;
      return questionInfo;
      }

      /// <summary>
      /// 完成解析后觸發(fā)
      /// </summary>
      protected override void Finished()
      {
      }

      /// <summary>
      /// 設(shè)置試題題干
      /// </summary>
      protected override void SetQuestionContent(string text)
      {
      Question.QuestionContent = text;
      }

      /// <summary>
      /// 設(shè)置試題難度
      /// </summary>
      protected override void SetDifficultyCode(string difficulty)
      {
      switch (difficulty)
      {
      case "A":
      Question.DifficultyCode = 1;
      break;
      case "B":
      Question.DifficultyCode = 2;
      break;
      case "C":
      Question.DifficultyCode = 3;
      break;
      }
      }

      //其他業(yè)務(wù)擴(kuò)展...
      }

      從類中可以看出,它們分別繼承于OfficeWordPaperConvertor和OfficeWordQuestionConvertor類,這里實(shí)現(xiàn)的只是和平臺(tái)相關(guān)的業(yè)務(wù)邏輯,至于如何對(duì)一份Word文檔解析,交給解析器組件去做,平臺(tái)上無(wú)需知道。
      同理,C/S平臺(tái)也用了類似的方法,不同的只是個(gè)別類型通過(guò)泛型抽象類得到實(shí)現(xiàn)。并且能夠使B/S平臺(tái)和C/S平臺(tái)擁有各自的業(yè)務(wù)邏輯。

      這樣,維護(hù)兩個(gè)平臺(tái)的這個(gè)功能成本降低了,如果解析器組件需要改動(dòng),只要更動(dòng)基礎(chǔ)組件的設(shè)計(jì),而不會(huì)影響業(yè)務(wù)上的邏輯。

       

      這是Leepy同學(xué)在開發(fā)項(xiàng)目的時(shí)候遇到的問(wèn)題,可以說(shuō)是提供了一種思路吧,也可以算是經(jīng)驗(yàn)之談吧:)

      在591up以及客戶端的功能效果如下圖所示:

       

      591up 客戶端軟件

      最后附上該范例的Demo
       

        相關(guān)評(píng)論

        閱讀本文后您有什么感想? 已有人給出評(píng)價(jià)!

        • 8 喜歡喜歡
        • 3 頂
        • 1 難過(guò)難過(guò)
        • 5 囧
        • 3 圍觀圍觀
        • 2 無(wú)聊無(wú)聊

        熱門評(píng)論

        最新評(píng)論

        發(fā)表評(píng)論 查看所有評(píng)論(0)

        昵稱:
        表情: 高興 可 汗 我不要 害羞 好 下下下 送花 屎 親親
        字?jǐn)?shù): 0/500 (您的評(píng)論需要經(jīng)過(guò)審核才能顯示)