友情提示:如果本网页打开太慢或显示不完整,请尝试鼠标右键“刷新”本网页!
富士康小说网 返回本书目录 加入书签 我的书架 我的书签 TXT全本下载 『收藏到我的浏览器』

VB2008从入门到精通(PDF格式英文版)-第30部分

快捷操作: 按键盘上方向键 ← 或 → 可快速上下翻页 按键盘上的 Enter 键可回到本书目录页 按键盘上方向键 ↑ 可回到本页顶部! 如果本书没有阅读完,想下次继续接着阅读,可使用上方 "收藏到我的浏览器" 功能 和 "加入书签" 功能!



        ExchangeRate = 100。0 

    End Sub 

End Class 



     Protected scope means only those classes that derive from a class (and the class itself) can  

view the methods; properties; or data members。 How many times and levels a class subclasses  

another class is not important。  

     Public scope is the loosest and simplest of all scopes。 You use Public whenever you want  

to expose functionality that other classes or derived classes want to reference。  

     Here are some guidelines for using each scope: 



     Private scope: You will use Private for most data member declarations because data member  

     declarations imply the state of an object。 Sometimes; when developing algorithms; you will  

     break apart the logic into several methods。 The broken…apart methods are used to solve a  

     problem; and thus should be used only in the context of the class; implying the methods  

     need to be declared using Private。  



     Protected scope: You will use Protected whenever you want to enforce an inheritance  

     architecture。 Very often; Protected and MustInherit go hand in hand; as both are intended  

     for inheritance。 The main objective behind  Protected is to offer a derived class access to  

     the private state of a parent class; or to offer reusable functionality that should be used  

     only by knowledgeable developers who are creating the subclasses。 


…………………………………………………………Page 170……………………………………………………………

148       CH AP T E R   6   ■    L E A R N IN G   T HE   B AS IC S  O F   OB J E CT OR I E N T E D   P R O G R AM M IN G 



                Public scope: As a rule; think carefully before using Public。 You will use public scope for the  

                most part; but it is also the scope that can cause the most problems。 For example; once you  

                declare something as Public; trying to later change the scope could wreak havoc in the  

                code that uses the class。 It might be harder to develop using the other scopes; but you will  

                have code that will have fewer maintenance issues。 It all es down to which methods  

                and properties you want to expose to the outside world。 



           Handling Verification 



           To run the test class TestCurrencyTrader; the following code is used。 



           Dim cls As TestCurrencyTrader = New TestCurrencyTrader() 

           cls。InitializeExchangeRate() 



                The modified test code entails instantiating TestCurrencyTrader and then calling the method  

           InitializeExchangeRate()。 But is this a test? After all; the InitializeExchangeRate() method  

           doesn’t have a parameter or return value。 Think of it as sending a letter via mail。 You don’t  

           know if the letter will arrive; but it probably will。 Tests that are probably passed are a really  

           bad idea。 

                We need to move the verification code from the test routine to the TestCurrencyTrader  

           class; like this: 



           Class TestCurrencyTrader 

               Inherits CurrencyTrader 

               Public Sub InitializeExchangeRate() 

                   ExchangeRate = 100。0 

                   If ExchangeRate  100。0 Then 

                       Throw New Exception(〃100。0 verification failed〃) 

                   End If 

               End Sub 

           End Class 



                The bolded code illustrates the verification code used to ensure that the value assigned to  

           ExchangeRate is the same one that is retrieved。 



           ■Note  The tests we’re using are being more plicated; and you may wonder; “Why do it that way?”  

           For this book; we are writing tests and creating our own testing framework。 Normally you would not do that。  

           You would use a testing framework such as NUnit ( http://nunit。org) or the Microsoft Visual Studio  

           Professional tools to help create the tests。 But here I want to demonstrate how to use Visual Basic; not a  

           testing tool。 By learning how to write the tests from the ground up; you will understand what to expect from  

           testing frameworks。 



           Using Conditional Statements 



           Having verification code within a class is acceptable in the context of the test class  

           TestCurrencyTrader。 However; the problem of testability is still present in those classes that do  

           not expose their state。 


…………………………………………………………Page 171……………………………………………………………

                        CH A PT E R   6   ■    L E A R N I N G   T HE   B AS IC S  O F   O B J E CT OR I E N TE D   P R O G R AM M IN G 149 



     To understand the problem; let’s return to the code for preheating the oven that you saw  

earlier in the section about the problems with properties。 Imagine rewriting Oven to include a  

verification test; like this: 



Class Oven 

    Private _temperature As Integer 



    Public Sub SetTemperature(ByVal temperature As Integer)  

        _temperature = temperature 

        If  _temperature  100。0 Then 

            Throw New Exception(〃100。0 verification failed〃) 

        End If 

    End Sub 

    Public Function AreYouPreHeated() As Boolean 

       ' Check if oven temperature matches prescribed temperature  

       Return False 

    End Function 

End Class 



     The bolded code illustrates a verification much like that used in CurrencyTrader; which  

verifies the parameter temperature for a specific value。 While the verification is useful for a  

particular test; it is not useful in the big picture。 As the code is written; the only valid value of  

temperature is 100。0; anything else will generate an exception。 It is definitely not a solution。 

     To get around this problem; you could use Visual Basic conditional statements。 Condi

tional statements are special keywords that allow a developer to define whether a piece of  

source code is piled。 Following is an example of source code that includes conditional  

statements。 



Class TestCurrencyTrader 

    Inherits CurrencyTrader 

    Public Sub InitializeExchangeRate() 

        ExchangeRate = 100。0 

#If INTEGRATE_TESTS Then 

        if  ExchangeRate  100。0 Then 

            Throw New Exception(〃100。0 verification failed〃) 

        End If 

#End If 

    End Sub 

End Class 



     The conditional statement always starts with a hash character (#); immediately followed  

by a keyword—If in this example。 Between the #If and #End If is code that is conditionally  

piled。 This is known as a preprocessor directive。 In this example; the condition means  

to pile the code contained within the #If and #End If block if the value  INTEGRATE_TESTS  

is true。 

     You can define a pilation identifier like  INTEGRATE_TESTS in the source code or in your  

IDE。 In Visual Basic Express; you can assign INTEGRATE_TESTS as follows: 


…………………………………………………………Page 172……………………………………………………………

150       CH AP T E R   6   ■    L E A R N IN G   T HE   B AS IC S  O F   OB J E CT OR I E N T E D   P R O G R AM M IN G 



               1。  Right…click your project and select Properties。 



               2。  Select the pile tab。 



               3。  Click the Advanced pile Options button。 



               4。  Add the  INTEGRATE_TESTS value to the Custom Constants text box。 



          Using Partial Classes for Verification 



          Conditional pilation is useful when you want to include or remove code depending on a  

          configuration。 However; some programmers will frown upon having conditional pilation  

          code within a function; as that would be a maintenance nightmare。 Another solution is to use  

          the Partial class keyword in conjunction with conditional pilation statements。 

               Thus far in all of the examples; whenever we defined a class; all of the methods and code  

          were declared between the Class/End Class pair。 By using partial classes; it is possible to declare  

          a class in multiple places。 When the Visual Basic piler piles the source code; the individual  

          class pieces will be assembled into a single class definition。 For our test code; we can create an  

          implementation partial class and a conditionally piled test partial class implementation。  

          The following is the modified TestCurrencyTrader class that could be used to test the state  

          without exposing the state。 



          Partial Class TestCurrencyTrader 

              Inherits CurrencyTrader 

              Public Sub InitializeExchangeRate()  

                  ExchangeRate = 100。0 

              End Sub 

          End Class 



          #if  INTEGRATE_TESTS Then 

          Partial Class TestCurrencyTrader  

              Inherits CurrencyTrader 

              Public Sub VerifyExchangeRate(ByVal value As Double) 

                  If ExchangeRate  value Then 

                      Throw New Exception(〃ExchangeRate verification failed〃) 

                  End If 

              End Sub 

          End Class 

          #End If 



               The keyword  Partial prefixes the Class keyword。 The first implementation of  

          TestCurrencyTrader is an example of not exposing state。 The second implementation of  

          TestCurrencyTrader; which is declared in the context of a conditional pilation statement;  

          contains the method VerifyExchangeRate()。 This is a verification method that tests the  

          ExchangeRate property for a particular value。 


…………………………………………………………Page 173……………………………………………………………

                         CH A PT E R   6   ■    L E A R N I N G   T HE   B AS IC S  O F   O B J E CT OR I E N TE D   P R O G R AM M IN G 151 



■Note  You can use partial classes only in the context of a single assembly; as the Partial keyword cannot  

be used across assembly boundaries。 When I say “single assembly;” I am referring to the piled pieces of  

 source code illustrated in Chapter 1。 In other words; if you define a partial class in a library; then all  

pieces of the partial class need to be defined in the library。  



     Partial classes make it simple to separate functionality into various source code files。 This  

example demonstrates using partial classes to manipulate internal state of a class without  

violating the do…not…expose…internal…state rule。 Another use of partial classes is in the context  

of code generators; where one source code file contains the custom code; and the other source  

code file contains the generator code。  



■Note  Only one part of a partial class needs to be explicitly qualified as Partial。 The piler is smart  

enough to realize that if it sees one part as Partial; then all the other parts must also be partial (even if they  

aren’t explicitly qualified with the Partial keyword)。 



Finishing the Base Class 



The ExchangeRate property is one of the pieces of shared functionality。 Another piece of shared  

functionality we want to implement is the calculation of the exchange rate。 We’ll do this with  

ConvertValue() and ConvertValueInverse() methods; which convert a currency from one value  

to another using multiplication or division。 The following shows the methods in the pleted  

base class implementation of CurrencyTrader。 



Public MustInherit Class CurrencyTrader 

    Private _exchangeRate As Double 



    Protected Property ExchangeRate() As Double 

        Get 

            Return _exchangeRate 

        End Get 

        Set (ByVal Value As Double) 

            _exchangeRate = Value 

        End Set 

    End Property 

    Protected Function ConvertValue(ByVal input As Double) As Double 

        Return _exchangeRate * input 

    End Function 

    Protected Function ConvertValueInverse(ByVal input As Double) As Double 

        Return input / _exchangeRate 

    End Function 

End Class 


…………………………………………………………Page 174……………………………………………………………

152       CH AP T E R   6   ■    L E A R N IN G   T HE   B AS IC S  O F   OB J E CT OR I E N T E D   P R O G R AM M IN G 



                The bolded code highlights the methods that convert the currency from one unit to another。  

           Notice that there is no declaration of specific currency units; because the base class is a utility  

           class used to help us realize an active trader or hotel trader implementation。 



           ■Note  Base class functionality; even when appearing trivial; is defined to ensure consistency in implemen

           tation。 Without consistency; you encounter the problem where one implementation does one thing and another  

           implementation does something pletely different。  



                This pletes our test code。 Now we will implement the active trader and hotel trader  

           ponents of the currency exchange application。 



           Writing the Active Trader and Hotel Trader  

           Currency Converters 



           With the TestCurrencyTrader test solution pleted; it’s time to turn our attention to the  

           CurrencyTrader solution。 As mentioned earlier; this consists of the active trader and hotel  

           trader currency converter ponents。 Here; you’ll see more clearly what it means to use  

           inheritance。 



           Implementing ActiveCurrencyTrader 



           The ActiveCurrencyTrader class implements the logic of the active currency trader。 To begin;  

           we’ll add its constructor。  



           Adding a Constructor to ActiveCurrencyTrader  



           To give ActiveCurrencyTrader some default state; we use a constructor。 However; the constructor  

           will serve another purpose; in that any class that instantiates ActiveCurrencyTrader will consider  

           the instance as immutable。 Immutable means that once data has been assigned to the instance; it  

           cannot be altered。 In other words; it is unchangeable。 



           ■Note  The String type is immutable because once a string variable has been assigned; it cannot be  

           changed。 Take a look at the methods associated with String; and you will see nothing that allows you to  

           modify the contents。 An immutable type is good because it allows you to implement a set…it…and…forget…it  

           object; and it prevents other classes from accidentally changing the contents。 Overall; an immutable type is  

           robust and predictable (though they are the exception; not the rule; most types allow you to modify state)。  



                The following shows the constructor code added to ActiveCurrencyTrader。 


…………………………………………………………Page 175……………………………………………………………

                       CH A PT E R   6   ■    L E A R N I N G   T HE   B AS
返回目录 上一页 下一页 回到顶部 11 11
快捷操作: 按键盘上方向键 ← 或 → 可快速上下翻页 按键盘上的 Enter 键可回到本书目录页 按键盘上方向键 ↑ 可回到本页顶部!
温馨提示: 温看小说的同时发表评论,说出自己的看法和其它小伙伴们分享也不错哦!发表书评还可以获得积分和经验奖励,认真写原创书评 被采纳为精评可以获得大量金币、积分和经验奖励哦!