嗔秤戻幣�哉膵�云利匈嬉蝕湊蛸賜�塋床四衲���萩晦編報炎嘔囚^泡仟 ̄云利匈��
VB2008貫秘壇欺娼宥(PDF鯉塀哂猟井)-及14何蛍
酔楯荷恬: 梓囚徒貧圭�鮗� ○ 賜 ★ 辛酔堀貧和鍬匈 梓囚徒貧議 Enter 囚辛指欺云慕朕村匈 梓囚徒貧圭�鮗� ● 辛指欺云匈競何! 泌惚云慕短嗤堋響頼���誅卒亮茂�俊彭堋響��辛聞喘貧圭 "辺茄欺厘議箝誓匂" 孔嬬 才 "紗秘慕禰" 孔嬬��
by scrolling down the String class page and clicking the pareTo link���此�
pares this instance with a specified Object。
This definition does not tell you much�察�so you will need to go back to the String page and
click another method name。 Click the pare link�察�and then click the pare��String�察�String��
link。 In the explanation of the pare�┌� method�察�you find the following text�此�
The parison terminates when an inequality is discovered or both strings have been
pared。 However�察�if the two strings pare equal to the end of one string�察�and the
other string has characters remaining�察 �then the string with remaining characters is
considered greater。 The return value is the result of the last parison performed。
´´´´´´´´´´´´´´´´´´´´´´Page 82´´´´´´´´´´´´´´´´´´´´´´´
60 CH AP T E R 3 * L E A R N IN G AB OU T ST R I N G M A N I P U L AT IO N S
*Note Looking up the meaning of a method is not a long process�察�even though it may seem like that from
the description in this section。 With experience�察�you don¨t even notice the extra clicks。
The pareTo�┌� method failed because of the character´by´character parison�察�which
is illustrated in Figure 3´7。
Figure 3´7。 How pareTo�┌� fails to pare strings that appear identical but have extra
characters
Strings are stored in buffers�察�with one space in the buffer allocated to one character。 As you
can see from Figure 3´7�察�whitespace takes up one space in the buffer。 We can take advantage of
this sometimes�察�as you¨ll see in the next section。
Now that you know what the problem is�察�the next step is to find a solution。
Solving the Extra Whitespace Problem
You can solve the whitespace problem in multiple ways。 Which way you use depends on your
needs。 Let¨s look at several solutions and see which works best for our translation program。
Trimming the Whitespace
The first solution we¨ll look at is to trim the whitespace using a method intended for that purpose。
The whitespace problem is not unique and is well known。 The String type has a method that
can be used to remove�察�or trim�察�the whitespace from a buffer。 You can remove whitespace at
the beginning�察�end�察�or both sides of the buffer。
´´´´´´´´´´´´´´´´´´´´´´Page 83´´´´´´´´´´´´´´´´´´´´´´´
CH AP T E R 3 * L E AR N IN G AB O U T ST R I N G M A N I PU L A TI O N S 61
As tempting as it is to change the original implementation of TranslateHello�┌��察�don¨t do
that�察�because you might inadvertently break something that is working just fine。 When you
develop code�察�you have multiple possible ways to solve a problem。 If you start messing around
with the original source code�察�by the time you reach the third or fourth solution�察�the code might
be a plete mess。 Your fixes might make things worse�察�and trying to backtrack in your source
code bees very difficult。
*Note To manage your source code�察�you should use version control。 However�察�even with version control�察 �
when you delete past attempts�察�ideas get lost。 Thus�察�while your source code will be clean�察�you might forget
something you did three or four hours ago。 Trust me�察�this happens�察�because developing source code is an
intensive thought process。
The solution is to create a shim that calls the TranslateHello�┌� method。 The shim is used
to fix the bug。 The following shim code is a temporary solution�此�
Public Function TrimmingWhitespace��ByVal buffer As String�� As String
Return Translator。TranslateHello��buffer。Trim�┌���
End Function
TrimmingWhitespace�┌� is a method that trims whitespace from the string to be translated。
buffer。Trim is new functionality that preprocesses the buffer。 Finally�察�we call the original
method�察�TranslateHello�┌��察�to perform the translation。
Of course�察�we need to test the new method to see if it trims the string to be translated。 The
following is the corresponding test code。
Dim verifyValue As String = TrimmingWhitespace�── �allo;��
If verifyValue。pareTo�─�hallo;�� 0 Then
Console。WriteLine�─�Extra white spaces allo to hallo test failed;��
End If
The test calls the work´in´progress method�察�TrimmingWhitespace�┌��察�to see if everything
works。 The verification code does not change。
So that you get predictable results�察�remember to call the shim and not the original method。
If you run the test code�察�you¨ll see that the shim works�察�and thus we have a solution。
Finding a Substring
Another solution to the whitespace problem is to find a specific substring in a buffer。 Think of
it as a search solution�察�where a method iterates over a string and attempts to match elements
of a buffer to some text that is being searched。 The work´in´progress code is shown in Figure 3´8。
The test code is not shown here�察�because it is similar to that for the previous solution�察�with
the difference being the method being tested。
´´´´´´´´´´´´´´´´´´´´´´Page 84´´´´´´´´´´´´´´´´´´´´´´´
62 CH AP T E R 3 * L E A R N IN G AB OU T ST R I N G M A N I P U L AT IO N S
IndexOf�┌� attempts to match the
text ^allo ̄ in the variable buffer。
Work´in´progress
If the text is found�察�an offset
method
that is not ´1 is returned。
Public Function FindSubstring��ByVal buffer As String��_
As String
If buffer。IndexOf�─�allo;�� ´1 Then
Return Translator。TranslateHello�─�allo;��
End If
Return ;;
End Function IndexOf�┌� returns the index of the
first matched character�察�which is 2。
Visual Basic will always start
a l l o counting with the value 0。
Index 0 1 2 3 4 5
Figure 3´8。 Finding a substring to solve the whitespace problem
Which Is the Best Solution�拭�
Take a moment to think about which is the best solution�此�trimming the whitespace or finding a
substring。 The answer is neither is perfect�察�each solution has its problems。 This is a very mon
occurrence when you are developing software。 You think you have all the corners covered�察�and
then another scenario causes your software to fail。
Again�察�I want to stress that you need to write more tests to figure out which scenarios might
cause your software to fail。 For the solution of trimming whitespace�察�writing another test causes
it to fail�察�as shown in the following code。 It cannot be tweaked to make the test succeed。
Dim verifyValue As String = TrimmingWhitespace�─�a allo;��
If verifyValue。pareTo�─�hallo;�� 0 Then
Console。WriteLine�─�Test failed�此�cannot parse multiple words;��
End If
In the test�察�the leading ^a ̄ is considered the first character and is not trimmed。 The verification
will fail because pareTo�┌� cannot verify the misaligned buffer caused by the leading ^a。 ̄
If the new test were executed against the substring solution�察�it would succeed and find the
word ^allo。 ̄ Because the new test caused the first solution to fail�察�it would seem that solution is
a no´go。 Our confidence has been increased in the second solution because the old test and the
new test did not fail。 But don¨t be too hasty to consider that as the best path。 The substring
solution fails with the following test。
Dim verifyValue As String = FindSubstring�─�allodium;��
If verifyValue。pareTo�─�hallo;�� 0 Then
Console。WriteLine�─�allodium to hallo test failed;��
End If
´´´´´´´´´´´´´´´´´´´´´´Page 85´´´´´´´´´´´´´´´´´´´´´´´
CH AP T E R 3 * L E AR N IN G AB O U T ST R I N G M A N I PU L A TI O N S 63
The word tested�察 �allodium�察院�contains the characters allo。 The verification will succeed�察 �
and this is an example of a false positive。
*Note It is important to have many tests that verify a multitude of different scenarios。 You should have tests
that are supposed to succeed and those that are supposed to fail。
The conclusion is that neither of the solutions works properly。 With extended testing�察�each
solution created new problems。 We need to find another solution。
DEVELOPMENT FRUSTRATIONS
It would seem that creating solutions and then creating tests that nullify the solution is a lesson in frustration。
You create code that does not solve the problems。 What you must realize and take to heart is that this is part
of the software development process。 Yes�察�some people write code and don¨t worry about the tests�察�but those
developers give software development a bad name。
You want to be a trustworthy developer who tests your code。 I have been�察�and my wife is�察�a software
development manager。 In her words�察 �I can deal with slow developers�察�but I cannot deal with developers who
I cannot trust to write stable and robust code。 The problem with untrustworthy developers is that I cannot let
them release code into production and always have to have somebody looking over their shoulders。 ̄
Writing the Tests Before Writing the Code
The reason the previous solutions failed is because each solution was a knee´jerk reaction。
Knee´jerk reactions are those where when you encounter a bug�察�you fix the bug!no more and
no less。 Instead�察�you should figure out what the bug is trying to tell you。 The original bug with
the leading whitespace was not a whitespace bug�察�but a bug that was saying�察 �Hey�察�what if my
text is not aligned�察�or part of a sentence�察�and so on�拭院�
To solve the bug�察�you don¨t write code�察�but you think of all of the tests that your code needs
to pass。 You need to assign responsibility and define contexts that succeed and fail。 In the
translation example�察�the appropriate implementation approach would be to write the tests
before writing the code。 Table 3´1 shows the contexts that fail and succeed。
Table 3´1。 Appropriate Tests for the Translation Program
Test Verification Result
allo Success
; allo ; Success
word allo Fail�此�you can¨t translate a single word without translating the other words
word allo word Fail�此�same reason as with word allo
prefixallo Fail�此�different word
´´´´´´´´´´´´´´´´´´´´´´Page 86´´´´´´´´´´´´´´´´´´´´´´´
64 CH AP T E R 3 * L E A R N IN G AB OU T ST R I N G M A N I P U L AT IO N S
Table 3´1。 Appropriate Tests for the Translation Program ��Continued��
Test Verification Result
alloappend Fail�此�different word
prefixalloappend Fail�此�different word
As you can see in the table�察�most test cases are failures because the translation ponent
is meant to translate single words only。 The test cases seem plete�察�but in fact�察�we are missing
one more set of cases�察�which are outlined in Table 3´2。
Table 3´2。 The Missing Test Cases for the Translation Program
Test Verification Result
Allo Success
; allO ; Success
Text can contain mixed cases�察�and from a human perspective�察�mixed case is still the same
word。 However�察�the puter considers mixed case as a pletely different buffer�察�and so we
must be able to cope with this situation。
Figure 3´9 shows the working solution。
Chaining ToLower�┌� and
Trim�┌� together first obtains ToLower�┌� returns a
the result of ToLower�┌� and lowercase copy of
then applies Trim�┌� to it the original string
Public Class Translator
Public Shared Function TranslateHello��ByVal input _
As String�� As String
Dim temp As String = input。ToLower�┌�。Trim�┌�
If temp。pareTo�─�hello;�� = 0 Then
Return ;hallo;
ElseIf temp。pareTo�─�allo;�� = 0 Then
Return ;hallo;
End If Trim�┌� removes whitespace
Return ;;
End Function
End Class
Figure 3´9。 The final translation solution
´´´´´´´´´´´´´´´´´´´´´´Page 87´´´´´´´´´´´´´´´´´´´´´´´
CH AP T E R 3 * L E AR N IN G AB O U T ST R I N G M A N I PU L A TI O N S 65
Looking at the solution�察�you see that there are elements from the first solution�察�which was
discounted because it did not work properly。 This is an example of how quickly solving a bug�察 �
seeing that code fail�察�and discounting the solution can be incorrect。 You need to think through
why something fails�察�and not just fix the bug to get rid of it。
*Note All of the solutions involved use String type methods。 The String type is very sophisticated and
supports many operations that are monly performed on text。
At this point�察�we are finished with the translation of the greeting。 Next�察�I¨ll point out a couple of
additional items that you need to keep in mind when dealing with strings。
Quoting Strings
Along with strings�察�Visual Basic has the Char type。 A Char can be described as a single letter of a
sentence。 H
酔楯荷恬: 梓囚徒貧圭�鮗� ○ 賜 ★ 辛酔堀貧和鍬匈 梓囚徒貧議 Enter 囚辛指欺云慕朕村匈 梓囚徒貧圭�鮗� ● 辛指欺云匈競何!
梁椣戻幣�� 梁心弌傍議揖扮窟燕得胎��傍竃徭失議心隈才凪万弌誌育断蛍�輌臆惨軼僑〃�燕慕得珊辛參資誼持蛍才将刮襲潜��範寔亟圻幹慕得 瓜寡追葎娼得辛參資誼寄楚署衛、持蛍才将刮襲潜填��