- 由客戶取得原始需求。如下之A.B.C
- A
- B
- C
- 由原始需求發展 use case。如下之 a, b, c , d
- a
- b
- c
- d
- 再發展 alternate path。如下之 b.1, b.2
- a
- b
- b.1
- b.2
- c
- d
- 根據上一步的 use case,與原始需求比對,看看需求是否完整。如果不完整,就向客戶確認並取得更完整的需求
- 重複2到4,直到需求完整為止。
一個好的 Use Case,必須有三個部份
每個 use case必須有非常明顯的起點與終點。某個東西(Actor)必須開始這個 use case,而在某個狀況下結束這個流程。
每個 use case必須被系統外的「外來初始者」來起動。通常是個「人」。
在OOAD中,物件的應當負什麼責任是相當重要的。
因此,在寫完的程式中,要如何一個object中找出不適當的責任呢?
雖然是老掉牙的原則,但要在每個物件中遵守卻也是相當難的了。
物件(object, an instance of class)方法(method)的命名,應該是
最近在讀一本書。
以此當作筆記
第一步驟即規格,或 functionality。在軟體建置的過程中,這是最重要,也是我們的目的。即使其他兩個步驟寫的再好,不是客戶要的,也都沒有用了。所以規格必須放在第一步。
收到客戶這樣的需求,原本以為是相當簡單的一件任務。
當按 print 時,會跳出 arcobat pdf reader 專用的列印對話框。
範例下載
get-command | 取得所有的 command 說明 |
get-help get-service | 取得 get-service 這個 cmdlet 的說明 |
get-help get-service -detailed | 取得 get-service 這個 cmdlet 的詳細說明 |
get-service | where-object {$.Status -eq "Running"} | 取得狀態等於Running的服務 |
get-service | where-object {$_.Name -eq "dns"} | stop-service | 1 取得所有的服務 2 其中名稱為 dns 3 停止符合條件的服務 |
get-process | get-member | 取得 get-process 回傳物件的member |
get-PSDrive | 取得 PS的 drives |
使用 XElement 或 XDocument 來載入 xml 時,到底有什麼不同的地方呢?
string xml = @"結果如下"; XElement el = XElement.Parse(xml); var q = from e in el.Elements() select e; Console.WriteLine("Load in XElement"); foreach (var item in q) { Console.WriteLine(item); } XDocument doc = XDocument.Parse(xml); q = from e in doc.Elements() select e; Console.WriteLine("Load in XDocument"); foreach (var item in q) { Console.WriteLine(item); } el 1 el 2 el 3
Load in XElement由此可看出,使用 XElement 的 Elements() 時,不會讀取 xml comment,會將該 r 當作 element 的current nodeel 1 el 2 el 3 Load in XDocumentel 1 el 2 el 3
string xml = @"這樣一來,程式碼就顯的有些長而不易維護。 因此,在linq to xml 的設計時,有考慮到這一點。"; XElement el = XElement.Parse(xml); string strDate = el.Element("invoice").Attribute("date").Value; DateTime? date = null; if (!string.IsNullOrEmpty(strDate)) date = DateTime.Parse(strDate); Console.WriteLine(date);
string xml = @"注意到可直接使用 DateTime? date = (DateTime?) … 來取得可能為 null 的 attribute。"; XElement el = XElement.Parse(xml); DateTime? date = (DateTime?) el.Element("invoice").Attribute("date"); Console.WriteLine(date);
Visual Studio 已經幫我們做了很多事情。但我們希望更進一步地做到組建自動化及測試自動化。
簡單的方法,就是下排程
cd Dir_Containing_Sln_File
msbuild solutionfile.sln /t:Rebuild /p:Configuration=Debug > build-log.txt
cd Dir_Containing_Sln_File
MSTest /testcontainer:testProject1\bin\Debug\test.dll /runconfig:localtestrun.testrunconfig > test-log.txt
客戶詢問了一個問題:為何資料庫存入客戶公司抬頭,顯示出來卻是 ?XXX公司。
問題出在這個?號,是不是真的問號。
一般來說,前端作業人員在操作時,當然不會笨到輸入?號。
在查詢介面(SSMS)查出?號,不一定真的是問題,而是該字碼無法顯示字型,因此只能顯示?來代表。
例如,使用者輸入了一個使用者電腦中造字檔才有的字,但該特別的字卻只存在於該使用者的電腦。
那要如何判斷是不是特別的字呢?看起來與「?」是一模一樣的.
select '煊眾', cast('煊眾' as varbinary) select N'煊眾', cast(N'煊眾' as varbinary) select cast(0x3FB2B3 as varchar(20)) select cast(0x4A713E77 as nvarchar(20))
查詢的結果如下
由上面的例子知道,當無法儲存資料時,SQL Server 會將該字儲存成「?」。 也就是「煊」字會儲存成「?」(0x3F)
利用這個方法,發現了原來是資料庫設計時就設計錯誤了。中文字必須設計成 nchar(50) 或 nvarchar。而一旦使用 char(50) 或 varchar,就會發生儲存成?(0x3F)的問題。
DebugView 是一個好用的 Debug 軟體。
在程式撰寫時,常常被教導要寫
Debug.Write("My debug inforation");
但是,除了在 Visual Studio 內可以看到 debug info 外,其他似乎一無用處了
在執行 .net 程式之前先啟動 DebugView,就可以看到 debug infomation 了using System; using System.Diagnostics; using System.IO; using System.Linq; class Program { static void Main(string[] args) { for (int i = 0; i < 1000; i++) { Stopwatch w = new Stopwatch(); w.Start(); TestMethod(); w.Stop(); Debug.WriteLine(string.Format("count {0} elapsed {1} msec", i, w.ElapsedMilliseconds)); } } private static void TestMethod() { string[] aColl = File.ReadAllLines(@"c:\a.txt"); string[] bColl = File.ReadAllLines(@"c:\b.txt"); var q = from a in aColl where !bColl.Contains(a) select a; foreach (var item in q) { Console.WriteLine(item); } } }
2008/09/16
在Vista 上執行時,若未使用Run as administrator,會出現如下的錯誤
此錯誤將導致無法讀取asp.net 的 debug information
另外,除了必須 Run as administrator,也必須勾選 "Capture Global Win32" 這個選項,才能看到 asp.net 的 debug information
Linq to XML 的寫作非常方便。以往要組一個 xml ,都必須從 XmlDocument 開始,現在使用 Linq to XML 就不用了。
//code 1 XElement el = new XElement("r", new XElement("invoice", new XElement("invoiceNumber", "AB12345678"), new XElement("invoiceDate", DateTime.Now) ) );產生的 xml 結果如下
<r> <invoice> <invoiceNumber>AB12345678</invoiceNumber> <invoiceDate>2008-09-01T10:08:22.9666505+08:00</invoiceDate> </invoice> </r>
這樣的方式極為簡便。
//code 2 XNamespace ns = "http://www.compnay.com.tw/Invoice"; XElement el = new XElement(ns + "r", new XElement(ns + "invoice", new XElement(ns + "invoiceNumber", "AB12345678"), new XElement(ns + "invoiceDate", DateTime.Now) ));產生如下的 xml
<r xmlns="http://www.compnay.com.tw/Invoice"> <invoice> <invoiceNumber>AB12345678</invoiceNumber> <invoiceDate>2008-09-01T10:16:48.2077244+08:00</invoiceDate> </invoice> </r>
//code 3 XNamespace ns = "http://www.compnay.com.tw/Invoice"; XElement el = new XElement("{http://www.compnay.com.tw/Invoice}r", new XElement("{http://www.compnay.com.tw/Invoice}invoice", new XElement("{http://www.compnay.com.tw/Invoice}invoiceNumber", "AB12345678"), new XElement("{http://www.compnay.com.tw/Invoice}invoiceDate", DateTime.Now) ) );結果是一樣的
<r xmlns="http://www.compnay.com.tw/Invoice"> <invoice> <invoiceNumber>AB12345678</invoiceNumber> <invoiceDate>2008-09-01T10:20:56.8615067+08:00</invoiceDate> </invoice> </r>
這樣的寫法雖然較容易了解,但較不容易修改,我個人不建議這樣的寫法。
另外,注意到雖然我們沒有說要寫成 default namespace,但Linq to XML 會「自動」地視狀況修改。
我們可以使用 XAttribute 來使用 namesapce prefix。如下程式碼。
//code 4 XNamespace ns = "http://www.compnay.com.tw/Invoice"; XElement el = new XElement("r", new XAttribute(XNamespace.Xmlns + "i", "http://www.compnay.com.tw/Invoice"), new XElement("invoice", new XElement("invoiceNumber", "AB12345678"), new XElement("invoiceDate", DateTime.Now) ) );結果如下。注意到這樣的方法,可以很方便地產生了一個 namespace prefix i,但卻沒有任何節點使用到這個 prefix
<r xmlns:i="http://www.compnay.com.tw/Invoice"> <invoice> <invoiceNumber>AB12345678</invoiceNumber> <invoiceDate>2008-09-01T10:27:11.773833+08:00</invoiceDate> </invoice> </r>
使用下面的程式碼,就不難了解 xml namespace 的特殊
//code 5 XNamespace ns = "http://www.compnay.com.tw/Invoice"; XElement el = new XElement("r", new XAttribute(XNamespace.Xmlns + "i", "http://www.compnay.com.tw/Invoice"), new XElement("{i}invoice", new XElement("invoiceNumber", "AB12345678"), new XElement("invoiceDate", DateTime.Now) ) );產生的xml 如下。xml:i="http:....." 這個 namespace 宣告了,卻沒有任何節點使用。i 是一個 namespace 的值,是inovice節點的 default namespace。invoiceNumber 與 invoiceDate的 namespace 卻是 ""。一個簡單的xml,卻有三個 namespace,基本上是錯誤的設計。
<r xmlns:i="http://www.compnay.com.tw/Invoice"> <invoice xmlns="i"> <invoiceNumber xmlns="">AB12345678</invoiceNumber> <invoiceDate xmlns="">2008-09-01T11:02:47.1886207+08:00</invoiceDate> </invoice> </r>
如果要像 code 2,產生相同的結果,但不要每一個節點使用 ns + "xxx"這樣的方式可不可以呢?如下的程式碼會發生錯誤
//code 6, fails XNamespace ns = "http://www.compnay.com.tw/Invoice"; XElement el = new XElement("r", new XAttribute("xmlns", "http://www.compnay.com.tw/Invoice"), new XElement("invoice", new XElement("invoiceNumber", "AB12345678"), new XElement("invoiceDate", DateTime.Now) ) );
錯誤的訊息為 Unhandled Exception: System.Xml.XmlException: The prefix '' cannot be redefined from '' to 'http://www.compnay.com.tw/Invoice' within the same start element tag. 看來,沒有一個好的方法,將其他的節點批次地設為 default namespace了。必須每一個節點都如 code 2 一般,將每一個節點,一個個設 namespace。也沒有辦法設哪一個 namespace 為 default namespace。
最後的範例,是 prefix namespace, 請與範例2 對照
//code 7 XNamespace ns = "http://www.compnay.com.tw/Invoice"; XElement el = new XElement(ns + "r", new XAttribute(XNamespace.Xmlns + "i", ns), new XElement(ns + "invoice", new XElement(ns + "invoiceNumber", "AB12345678"), new XElement(ns + "invoiceDate", DateTime.Now) ) );產生的 xml 結果如下
<i:r xmlns:i="http://www.compnay.com.tw/Invoice"> <i:invoice> <i:invoiceNumber>AB12345678</i:invoiceNumber> <i:invoiceDate>2008-09-02T08:52:11.4240786+08:00</i:invoiceDate> </i:invoice> </i:r>