乡下人产国偷v产偷v自拍,国产午夜片在线观看,婷婷成人亚洲综合国产麻豆,久久综合给合久久狠狠狠9

  • <output id="e9wm2"></output>
    <s id="e9wm2"><nobr id="e9wm2"><ins id="e9wm2"></ins></nobr></s>

    • 分享

      三層式開(kāi)發(fā)中的層次劃分討論 - 遐想的未來(lái) - 博客園

       xnet 2006-08-12
      先舉一個(gè)曾經(jīng)在哪本書(shū)上看到的例子:現(xiàn)在你想在1米寬的小溪上建一座橋,你會(huì)在上面放塊木板就完了。如果想在寬一點(diǎn)的小河上建這橋,你就需要計(jì)算木材用料,價(jià)格等,如果需要?jiǎng)e人幫忙,你還要多一些圖紙什么的讓別人理解你的想法?,F(xiàn)在你要在大江上面建橋,你需要有整體的計(jì)劃,包括各個(gè)方面,比如將來(lái)可能的收費(fèi)和利益分配等問(wèn)題。
      這里講3層式,其實(shí)是針對(duì)“大江上面建橋”來(lái)的,對(duì)于1米寬的小溪,在實(shí)際中可能一點(diǎn)用都沒(méi)有。不過(guò)現(xiàn)在我不可能去拿個(gè)長(zhǎng)江大橋作例子來(lái)講,所以這里還是用這條簡(jiǎn)單的小溪,講講怎么建橋。之所以講這么多廢話,是為了防止部分人看完此文之后“小小一個(gè)東西,搞那么麻煩干什么。。”其實(shí)這里講的不是具體的這個(gè)例子,而是分層的思想,理解這點(diǎn)非常重要。
      下面我就我們大家日常見(jiàn)最多的例子來(lái)講,就是“用戶(hù)登錄”的例子。這個(gè)例子很簡(jiǎn)單,但是麻雀雖小五臟俱全。從數(shù)據(jù)訪問(wèn)到業(yè)務(wù)規(guī)則到界面全有了。
      本文分2個(gè)部分,如果只想研究面向?qū)ο蟮乃枷?,?duì)實(shí)現(xiàn)已經(jīng)熟悉,可以跳過(guò)第一部分。
      第一部分
      新建一個(gè)空白解決方案。然后:
      “添加”-“新建項(xiàng)目”-“其他項(xiàng)目”-“企業(yè)級(jí)模版項(xiàng)目”-“C#生成塊”-“數(shù)據(jù)訪問(wèn)”(數(shù)據(jù)層,下簡(jiǎn)稱(chēng)D層)
      “添加”-“新建項(xiàng)目”-“其他項(xiàng)目”-“企業(yè)級(jí)模版項(xiàng)目”-“C#生成塊”-“業(yè)務(wù)規(guī)則”(業(yè)務(wù)層,下簡(jiǎn)稱(chēng)C層)
      “添加”-“新建項(xiàng)目”-“其他項(xiàng)目”-“企業(yè)級(jí)模版項(xiàng)目”-“C#生成塊”-“Web用戶(hù)界面”(界面層,下簡(jiǎn)稱(chēng)U層)
      右鍵點(diǎn)“解決方案”-“項(xiàng)目依賴(lài)項(xiàng)”,設(shè)置U依賴(lài)于D、C,C依賴(lài)于D。
      對(duì)U添加引用D、C,對(duì)C添加引用D。
      到此為止,一個(gè)三層的架子建立起來(lái)了。我上面說(shuō)的很具體很“傻瓜”,知道的人覺(jué)得我廢話,其實(shí)我這段時(shí)間很強(qiáng)烈的感覺(jué)到非常多的人其實(shí)對(duì)這個(gè)簡(jiǎn)單的過(guò)程完全不了解。雖然不反對(duì)建2個(gè)“空項(xiàng)目”和1個(gè)“Asp net Web應(yīng)用程序項(xiàng)目”也可以作為3層的框架,而且相當(dāng)多的人認(rèn)為其實(shí)這些“企業(yè)級(jí)模板項(xiàng)目”其實(shí)就是個(gè)空項(xiàng)目,這是一個(gè)誤區(qū)。沒(méi)錯(cuò),企業(yè)級(jí)模板項(xiàng)目你從解決方案資源管理器里看它是個(gè)什么也沒(méi)有的,但是你可以用記事本打開(kāi)項(xiàng)目文件,看見(jiàn)不同了吧??有些東西在背后,你是看不見(jiàn)的,不過(guò)系統(tǒng)已經(jīng)做好了。也就是說(shuō),如果你在C層里的某個(gè)類(lèi)里“using System Data SqlClineit”,或者使用一個(gè)SqlConnection對(duì)象,編譯時(shí)候不會(huì)出錯(cuò),但是會(huì)在“任務(wù)列表”里生成一些“策略警告”,警告你在C層里不要放應(yīng)該放在D層的東西(雖然就程序來(lái)說(shuō)沒(méi)錯(cuò),但是可讀性可維護(hù)性就打了折扣)而這種功能,空項(xiàng)目是無(wú)法給你的。
      我們知道建橋需要磚塊,應(yīng)該是先準(zhǔn)備好磚再來(lái)建橋,不過(guò)為了講解上的順序性和連貫性,簡(jiǎn)單性。我們先建橋,建的過(guò)程中需要磚塊再現(xiàn)做,這樣就不會(huì)多出來(lái)“橋不需要的東西”。注意在實(shí)際中,還是應(yīng)該先準(zhǔn)備磚塊。
      U層其實(shí)就是橋,C層是磚塊,D層是原料(石頭、沙子)。這也解釋前面為什么U層要引用、依賴(lài)D層(而不是U對(duì)C,C對(duì)D的層次),因?yàn)闃虺诵枰u頭,其實(shí)也需要石頭沙子。
      我們?cè)赨層建一個(gè)Login aspx(這里插入一句,我不喜歡去把系統(tǒng)自動(dòng)生成的WebForm1 aspx拿來(lái)改成login或index或直接刪除,我一般留著它當(dāng)測(cè)試代碼用,等到整個(gè)系統(tǒng)凍結(jié)再把它移除就可以了。)添加1個(gè)TextBox(id=txt),一個(gè)DropDownList(id=ddl),一個(gè)Button(id=btn)。其中DropDownList用來(lái)選擇用戶(hù)名,button是提交按鈕, TextBox用來(lái)輸入密碼。
      現(xiàn)在我們必須要添加的代碼分為2部分: 1、Page_load時(shí)對(duì)ddl的初始化。2、btn的click處理。
      1:
      private void Page_Load(object sender, System.EventArgs e)
      {
      if(!IsPostBack)
      {
      this.ddl.DataSourse=DataManager.GetOneColunm(“User”,”uid”); //講解1
      this.ddl.DataBind();
      }
      }
      2:
      private void Btn_Click(object sender, System.EventArgs e)
      {
       string uid=this.ddl.SelectedValue;
       string psw=this.txt.Text;
       if(psw =””)
        MessageBox(“空密碼!”);
       else
       {
        User theUser;
        try
        {
         theUser=new User(uid); //講解2
        }
        catch(Exception e)
        {
       MessageBox(e. Message);//講解2
       return;
      }
      if(theUser.CheckPsw(psw)) //講解3
      {
       theUser.SetSessions();
       Response.Redirect(“……………..”);  //登錄成功! 
      }
      else
      {
       MessageBox(“密碼錯(cuò)誤!”); 
      }
       }
      }
      講解1:DataManager 是D層中的一個(gè)類(lèi),提供常見(jiàn)的數(shù)據(jù)操作。GetOneColunm(string Table,string Colunm)方法返回一個(gè)只有1列的DataTable,值為數(shù)據(jù)庫(kù)中表名為T(mén)able,的Colunm列。
      public class DataManager
      {
       public DataManager()
       {
       }
       public static DataTable GetOneColunm(string Table,string Colunm)
       {
        //此處省略相關(guān)代碼。返回指定表指定列
       }
      }
      其實(shí)這個(gè)地方演示的是在U層直接繞過(guò)C層訪問(wèn)D層的例子,因?yàn)樵摻Y(jié)構(gòu)邏輯上很簡(jiǎn)單,而且獲取用戶(hù)名并不是現(xiàn)實(shí)社會(huì)中的業(yè)務(wù)邏輯的一部分(僅僅是界面需要,因?yàn)樵谶@里其實(shí)用成2個(gè)TextBox的話完全不需要這一步)
      講解2:定義一個(gè)User類(lèi)的實(shí)例。User類(lèi)的定義可能如下:
      public class User
      {
       public User(string uid)
       {
        if(DataManager.IsIn(“user”,”uid=’"+uid+”’”))
         throw "用戶(hù)不存在";
        else
         //User()其他初始化;
       }
       public bool CheckPsw(string psw)
       {
        if(DataManager.IsIn(“user”,”uid=’"+uid+”’ and psw=’”+psw+”’”))
         return true;
        else
         return false;
       }
      }
      注意到用戶(hù)類(lèi)構(gòu)造函數(shù)中用了個(gè)throw來(lái)拋出用戶(hù)不存在的異常,在下面catch的時(shí)候用MessageBox(e. Message);來(lái)彈出“用戶(hù)不存在”的錯(cuò)誤。這里其實(shí)也是為了演示一個(gè)層間傳遞信息的手段,異常也是一種手段,雖然在這里其實(shí)可以有其他方式比如返回值,引用參數(shù)之類(lèi)的直接用一個(gè)方法來(lái)獲得用戶(hù)是否存在的信息,沒(méi)必要放在構(gòu)造里,我這么做只是為了演示傳遞過(guò)程,在后面的有討論這種用法在分層模式下某種特殊情況的應(yīng)用以解決一些問(wèn)題。這個(gè)類(lèi)里又用了DataManager類(lèi)的一個(gè)靜態(tài)方法IsIn(string Table,string str)該方法其實(shí)其實(shí)是執(zhí)行 “select * from Table where str”
      這個(gè)Sql語(yǔ)句并在返回空的時(shí)候方法返回false,否則返回true。一個(gè)很簡(jiǎn)單的方法。這里演示了C層對(duì)D層的調(diào)用。
      順便說(shuō)一句,因?yàn)樵赩S.Net中,項(xiàng)目的名稱(chēng)會(huì)默認(rèn)地成為項(xiàng)目中的namespace,可以通過(guò)把所有自動(dòng)生成的代碼中的namespace改為“解決方案名稱(chēng)”來(lái)使3個(gè)層可以無(wú)縫地自由調(diào)用?;蛘咴谡{(diào)用的地方using一下其他層的空間名,看個(gè)人喜歡了。比如上面的Login.aspx.cs里需要using2個(gè),而User.cs里要using一個(gè)。
      講解3:這里的檢查用戶(hù)密碼同樣用到User類(lèi)的一個(gè)方法CheckPsw()而這個(gè)方法 又用到了IsIn()這里就不多說(shuō)了。
      大家注意到我們?cè)赨層的頁(yè)面里用MessageBox()方法來(lái)彈出對(duì)話框,其實(shí)這個(gè)方法寫(xiě)在PageBase.cs里,是U層的另外一個(gè)文件,繼承Page類(lèi),Login類(lèi)又繼承它,這個(gè)方法其實(shí)是把Response.Write(“<script>alert(\“”+ msg+“\”)</script>”)封裝起來(lái)了。
      到此為止,登錄結(jié)束,例子的實(shí)現(xiàn)也說(shuō)完了。不過(guò)只講了“然”,沒(méi)有講“所以然”。下面開(kāi)始講“所以然”。
      第二部分
      作為對(duì)比,我們使用一個(gè)不面向?qū)ο蟮?,不分層的Asp式的Aspx相同登錄作為對(duì)比。具體的Asp代碼我就不寫(xiě)了,反正登錄哪都有。先來(lái)看看他們2者發(fā)生的遭遇(這是不幸的,卻偏偏是經(jīng)常發(fā)生的):
      1、  項(xiàng)目經(jīng)理突然說(shuō)“不用SqlServer了,換成Access”(正版費(fèi)用問(wèn)題)??纯?邊分別發(fā)生什么:3層這邊(A),把DataManager類(lèi)里的連接改改(在實(shí)際情況下,極可能其實(shí)是改它的基類(lèi),它本身不用改),Web.config中把字符串換掉就完了。Asp式那邊(B),同樣要改Web.config,同樣要改連接什么的,修改量在這個(gè)具體的“小溪”例子上幾乎相同,在“大橋”例子上B應(yīng)該會(huì)稍微多改點(diǎn),不過(guò)也不會(huì)多很多。但是!請(qǐng)注意一點(diǎn),我們?cè)谛薷拇a的時(shí)候,主要時(shí)間和精力不是花在“改”這個(gè)動(dòng)作上,而是花在“要改什么地方”上和“尋找需要改的地方”上。在“大橋”上,B需要花費(fèi)多的多的時(shí)間,對(duì)大部分文件進(jìn)行查找和替換。A則僅僅在數(shù)據(jù)層里,另外2個(gè)層不需要任何修改。從這個(gè)角度出發(fā)我們想到2點(diǎn)原則:
      a)    數(shù)據(jù)層必須要能夠保證數(shù)據(jù)庫(kù)的變動(dòng)(任何結(jié)構(gòu)變動(dòng)、類(lèi)型變動(dòng))對(duì)其余各層的不透明性。也就是數(shù)據(jù)庫(kù)怎么變,其他層絕對(duì)不應(yīng)該變哪怕1行代碼?。╳eb.config是整個(gè)應(yīng)用程序的配置,雖然在物理上存在于U層的文件夾中,但個(gè)人更愿意認(rèn)為它是獨(dú)立的不屬于任何層的,所以這里不計(jì)它)
      b)    數(shù)據(jù)層越小越好(如果沒(méi)有這點(diǎn)原則,我們把整個(gè)所有的東西都放在數(shù)據(jù)層,那當(dāng)然數(shù)據(jù)庫(kù)變動(dòng)對(duì)外面無(wú)影響――因?yàn)橥饷鎺缀鯖](méi)東西――但是這顯然不可行)。而且因?yàn)榍懊嫖覀冋f(shuō)了,大部分時(shí)間花在“找”上面,你小點(diǎn),找起來(lái)也容易點(diǎn)。
      2、  客戶(hù)突然提出B/S版的不好,要換成C/S版的。對(duì)于(B)來(lái)說(shuō),這是晴天霹靂!!他的所有工作都要重新做,(或者幾乎所有工作),雖然他有很多代碼還可以用,不過(guò)他在未來(lái)一小段時(shí)間就必須不斷在“復(fù)制-粘貼”中使用以前的代碼。(A)發(fā)生了什么??如果你細(xì)心看會(huì)發(fā)現(xiàn)(A)之需要新建個(gè)項(xiàng)目“Windows用戶(hù)界面”(和前面一樣,添加引用,項(xiàng)目依賴(lài)),拖幾個(gè)控件到上面,把控件名字起成txt,ddl,btn,然后把click代碼和Pageload代碼復(fù)制過(guò)去,(居然。。。)連1行代碼都不需要修改!?。?!當(dāng)然,這是比較極端的例子(win和web都有TextBox,DropDownList,Button3種控件,而且我們?cè)赑ageBase里定義的方法MessageBox()又剛好和win里面方法同名。。。)不過(guò)盡管有這么多巧合我們?nèi)匀豢梢砸苍敢庀嘈牛?#8220;大橋”上,(A)將比(B)少做很多工作。從這個(gè)角度出發(fā)我們又想到2點(diǎn)類(lèi)似原則:
      a)    界面層應(yīng)該保證界面的任何變化都不需要修改其他層的內(nèi)容(不管這個(gè)具體的例子把ddl改為另外一個(gè)TextBox,或是把B/S改為C/S)
      b)    界面層越小越好(理由同上。)
      3、  除開(kāi)了界面層和數(shù)據(jù)層,(如果你的方案中只有3個(gè)層的話)剩下的就都是邏輯層的內(nèi)容了。所以和前面的相對(duì)應(yīng),我們可以得出結(jié)論:
      a)    邏輯層應(yīng)當(dāng)不受數(shù)據(jù)庫(kù)和界面變動(dòng)的影響而需要修改。
      b)    邏輯層越大越好(因?yàn)榱硗?層越小越好。。。)
      有了最基本的原則,我們應(yīng)該來(lái)討論下,根據(jù)原則,要怎么分層的問(wèn)題:
      1、  PageBase.cs 應(yīng)該放在哪個(gè)層?根據(jù)上面的原則,應(yīng)該放在C層。但是實(shí)際上我習(xí)慣放在U層,或者放在另外一個(gè)(第4個(gè)層,通用底層,在比數(shù)據(jù)層還低的位置)層里。到底放在什么地方,我最開(kāi)始的做法是在C層,因?yàn)榘瓷厦鏆w納的原則,就應(yīng)該放在C,但是后來(lái)一段時(shí)間我習(xí)慣于“四層式”之后就把它放在通用底層(下簡(jiǎn)稱(chēng)B層,該層同時(shí)也放如本來(lái)在D層中的SqlHelper類(lèi)等,包括原來(lái)3層中所有“通用”的類(lèi),這里通用的意思是說(shuō)其他系統(tǒng)也可以用的到而不需要修改,這個(gè)層通常不用解決方案名稱(chēng)而用公司、小組名稱(chēng)等作為namespace,在有新項(xiàng)目的時(shí)候在建解決方案的時(shí)候就可以“添加現(xiàn)有項(xiàng)目”,簡(jiǎn)單的加進(jìn)去并不斷積累,實(shí)踐中對(duì)提高效率和代碼重用有比較大作用。)不過(guò)如果只有3層,我現(xiàn)在傾向于把PageBase放在U層。主要因?yàn)樽罱欢螡撔难芯棵嫦驅(qū)ο蟮姆治鲈O(shè)計(jì)的心得。說(shuō)起來(lái)又是一大匹布沒(méi)完,不過(guò)我又在前面的“原則”上加1條:“如果某個(gè)類(lèi),僅為了某層的某種特殊實(shí)現(xiàn)而存在,那么它必須放在該層”,比如PageBase是為了U層的特殊實(shí)現(xiàn)(B/S實(shí)現(xiàn))而存在,又比如SqlHelper是為了D層的特殊實(shí)現(xiàn)(SqlServer數(shù)據(jù)庫(kù))而存在。所以對(duì)應(yīng)的,它們必須分別放在U層和D層(如果不加這條的話按前面他們都該放在C層,因?yàn)镃層越大越好,而且數(shù)據(jù)庫(kù)和界面的變動(dòng)不需要改動(dòng)這2個(gè)類(lèi)-雖然它們可能因改動(dòng)而沒(méi)有用了,不過(guò)還是不需要去修改它們)
      2、  Oldjacky曾經(jīng)和我談到一個(gè)問(wèn)題:Datagrid中允許作刪除操作,但是如果當(dāng)前僅余下最后一條記錄,則不允許這個(gè)刪除操作!那么該刪除應(yīng)該放在C層還是D層還是U層?我覺(jué)得應(yīng)該從另外一個(gè)角度來(lái)考慮:
      a)    這種“不允許”是“業(yè)務(wù)規(guī)則的不允許”(比如表內(nèi)的數(shù)據(jù)表示當(dāng)前在店里的職員,刪除表示職員離開(kāi)店里-可能去拿貨什么的,添加表示職員回來(lái),當(dāng)柜臺(tái)只有一名職員時(shí),顯然他絕對(duì)不能離開(kāi)去送貨),這個(gè)時(shí)候,此“禁止刪除”的操作應(yīng)該產(chǎn)生在C層。
      b)    這種“不允許”是“程序?qū)崿F(xiàn)的不允許”(比如當(dāng)這里為空的時(shí)候會(huì)引起其他地方比如ToString()方法產(chǎn)生“未將對(duì)象的引用設(shè)置到對(duì)象的實(shí)例……”的錯(cuò)誤,或程序設(shè)計(jì)者或項(xiàng)目經(jīng)理的主觀愿望希望它“不允許”以此來(lái)減少工作量或簡(jiǎn)化程序)。這個(gè)時(shí)候,此“禁止刪除”可以放在U層(比如上面說(shuō)的ToString)或D層(比如違反數(shù)據(jù)庫(kù)約束)
      3、  細(xì)心的人可能會(huì)發(fā)現(xiàn),前面的登錄例子里,用戶(hù)一共可以獲得3種彈出錯(cuò)誤分別是“空密碼”“密碼錯(cuò)誤”“用戶(hù)不存在”,而其中前2個(gè)是在U層里做的,“用戶(hù)不存在”卻是在C層里做的(我是指這個(gè)字符串)還是開(kāi)始說(shuō)的建橋,我這里是用“小溪建橋”來(lái)講解“大江建橋”所以故意在這里轉(zhuǎn)了個(gè)沒(méi)用的圈,就像在計(jì)算小溪上這塊木板到底夠用多少年,其實(shí)對(duì)小溪沒(méi)什么意義,只是為了講解大橋需要而加上去的,畢竟大橋需要這種考慮。我這里假設(shè)“用戶(hù)不存在需要彈出提示”是一種業(yè)務(wù)邏輯上的需要,而“未輸入密碼需要提示”則不是業(yè)務(wù)規(guī)則需要(比如實(shí)際業(yè)務(wù)中可以允許空密碼,但是項(xiàng)目經(jīng)理不同意,說(shuō)一定要密碼)在這個(gè)登錄例子中其實(shí)根本沒(méi)有什么問(wèn)題,但是在大項(xiàng)目里,如果這個(gè)東西不是業(yè)務(wù)規(guī)則的需要,就不應(yīng)該放在業(yè)務(wù)層,如果是一種業(yè)務(wù)規(guī)則,就要放在業(yè)務(wù)層。有助于業(yè)務(wù)模型與現(xiàn)實(shí)實(shí)體的銜接,也有益于業(yè)務(wù)邏輯更好地表現(xiàn)現(xiàn)實(shí)實(shí)體的特征。
      到此為止,我再次歸納出我們的最終的原則:
      1、  如果某個(gè)類(lèi),僅為了某層的某種特殊實(shí)現(xiàn)而存在,那么它必須放在該層。
      2、  數(shù)據(jù)層應(yīng)當(dāng)在保證數(shù)據(jù)庫(kù)變化對(duì)其他層不可見(jiàn)的前提下盡量小。
      3、  界面層應(yīng)當(dāng)在保證界面變化對(duì)業(yè)務(wù)邏輯層不影響的前提下盡量小。
      4、  如果某個(gè)類(lèi)不是業(yè)務(wù)規(guī)則的需要,就不應(yīng)該放在業(yè)務(wù)層,反之亦然。
      5、  邏輯層應(yīng)當(dāng)在保證數(shù)據(jù)庫(kù)或界面變化不會(huì)造成自身影響的前提下盡量大。
      以上5點(diǎn)如果發(fā)生沖突,在找平衡點(diǎn)的時(shí)候,前面的要高于后面的。比如1和3沖突的時(shí)候更傾向于使用規(guī)則1。
      第二部分結(jié)束
      有一點(diǎn)應(yīng)該是“編程代碼習(xí)慣”和“面向?qū)ο?#8221;的范疇,不過(guò)因?yàn)楹头謱佑行╆P(guān)系,所以也說(shuō)一下。“如果你的代碼,自己把它翻譯成中文并加必要的標(biāo)點(diǎn)符號(hào)后,其他不懂程序的人看了仍然覺(jué)得很亂,那么你很可能層沒(méi)分好”。比如前面的btn的click:

      字符串 用戶(hù)名是 下拉框 選擇值;
      字符串 密碼是 輸入框 值;
      如果 密碼是 空
       對(duì)話框(密碼空!);
      否則

       用戶(hù) 這用戶(hù);
       嘗試

       這用戶(hù) 是 新的 用戶(hù)(用戶(hù)名);

      捕捉(錯(cuò)誤)

       對(duì)話框(錯(cuò)誤 消息);
       返回;

      如果 這用戶(hù)檢查密碼(密碼)
      {
       這用戶(hù) 設(shè)置狀態(tài);
       響應(yīng) 重定位(“。。。。。”);
      }
      否則
      {
       對(duì)話框(密碼錯(cuò)誤)
      }

      代碼最好能讓不懂的人也能看懂到底在干什么。
      最后,oldjacky的Datagrid刪除的例子“刪除”顯然在D層,但是不允許卻可能在C或U,如果在U沒(méi)什么說(shuō)的了,如果在C,那么這種“不允許”的一個(gè)比較合理的實(shí)現(xiàn)方法就是在C層里遇到這種情況throw一下。當(dāng)U層里catch到該throw的時(shí)候,禁止刪除操作,這樣當(dāng)2個(gè)層同時(shí)有原因引起禁止時(shí),可以從代碼一眼看出這種禁止的來(lái)源。類(lèi)似于前面的2種彈出錯(cuò)誤。
      注:本文為原創(chuàng),甚至在寫(xiě)本文的時(shí)候,并沒(méi)有看任何網(wǎng)頁(yè)文章和書(shū),完全是一時(shí)之作,錯(cuò)誤難免,而且連代碼也是在寫(xiě)字板上打出來(lái)的,所以不見(jiàn)得可以運(yùn)行,大小寫(xiě)也可能有錯(cuò)。一口氣寫(xiě)這么多,行文很亂,廢話也多,請(qǐng)見(jiàn)諒!

        本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶(hù)發(fā)布,不代表本站觀點(diǎn)。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購(gòu)買(mǎi)等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊一鍵舉報(bào)。
        轉(zhuǎn)藏 分享 獻(xiàn)花(0

        0條評(píng)論

        發(fā)表

        請(qǐng)遵守用戶(hù) 評(píng)論公約

        類(lèi)似文章 更多