嗔秤戻幣�哉膵�云利匈嬉蝕湊蛸賜�塋床四衲���萩晦編報炎嘔囚^泡仟 ̄云利匈�《超噌�殻窟�嵌虜隆輓麈觚翹瀘卉韮�仍仍�。� 烏御危列
浪慕利 卦指云慕朕村 厘議慕尺 厘議慕禰 TXT畠云和墮 序秘慕杏 紗秘慕禰

VB2008貫秘壇欺娼宥(PDF鯉塀哂猟井)-及68嫗

梓囚徒貧圭�鮗� ○ 賜 ★ 辛酔堀貧和鍬匈��梓囚徒貧議 Enter 囚辛指欺云慕朕村匈��梓囚徒貧圭�鮗� ● 辛指欺云匈競何��
!!!!隆堋響頼��紗秘慕禰厮宴和肝写偬堋響��






           Implementing a Tax Engine and Tax Account 



           Implementing a Canadian tax engine means deriving a class from BaseTaxEngine�察�and that  

           means implementing the CreateTaxAccount�┌� method。 The implementation of the Canadian  

           tax engine will be in a new namespace�察�and a good name would be Canada ��as this is in the  

           LibTax project�察�it will have a root namespace of LibTax�察�so LibTax。Canada is the full namespace��。  

           The code will not show the namespace details�察�as they are implied。  

                The implementation is as follows�此�



           Friend Class TaxEngine  

               Inherits BaseTaxEngine 

               Public Overrides Function CreateTaxAccount�┌� As ITaxAccount  

                   Return New TaxAccount�┌� 

               End  Function 


´´´´´´´´´´´´´´´´´´´´´´Page 205´´´´´´´´´´´´´´´´´´´´´´´

                           CH AP T E R   7   *    L E AR N IN G   AB O U T   CO M P O N E N TS   AN D   C L AS S  H I E R AR C HI E S 183 



End Class 



     In the implementation of the CreateTaxAccount�┌� method�察�the TaxAccount class is instan

tiated。 TaxAccount is a class that derives from BaseTaxAccount and thus implements the ITaxAccount  

interface。 The implementation of TaxAccount is as follows�此�



Friend Class TaxAccount 

    Inherits BaseTaxAccount 



    Private _province As Province 

    Private _year As Integer 



    Public Overrides Function GetTaxRate��ByVal ine As Double�� As Double 

        If _year = 2008 Then 

            If _province = Province。Ontario Then 

                Return OntarioTax2008。TaxRate��ine�� 

            End If 

        End If 

        Throw New NotSupportedException�─�Year ; & _year & ; Province ; & _ 

            _province & ; not supported;�� 

    End Function 

End Class 



     The purpose of the GetTaxRate�┌� method is to return the applicable tax rate for the given  

amount。 In Canada�察�the tax rate is determined by which province you live in and the year。 The  

calculation in GetTaxRate�┌� has the ability to calculate the taxes for the year 2008 in the Ontario  

province。 Here¨s the skeleton of the OntarioTax2008 class�此�



Public Class OntarioTax2008 

    Public Shared Function TaxRate��ByVal ine As Double�� As Double 

        ' Return the appropriate rate 

    End Function 

End Class 



     Yet there is a problem�察�and it involves the data members _province and _year。 The data  

members are used in the calculation GetTaxRate�┌��察�but they are not assigned。 This is a problem。 



Assigning State When the Interface Cannot 



The problem of the Canadian tax account is a mon one that you will encounter in many  

situations。 The essence of the problem is the need to assign state that is specific to an imple

mentation without violating the intention of the general interface。 

     To illustrate the problem�察�let¨s say that the method GetTaxRate�┌� will include a reference  

to the province and year。 The rewritten  ITaxAccount interface would be as follows�此�



Public Interface ITaxAccount  

    Sub AddDeduction��ByVal deduction As ITaxDeduction�� 

    Sub AddIne��ByVal ine As ITaxIne�� 

    Function GetTaxRate��ByVal ine As Double�察�ByVal province As Province�察�_ 

    ByVal year As Integer�� As Double 


´´´´´´´´´´´´´´´´´´´´´´Page 206´´´´´´´´´´´´´´´´´´´´´´´

184       CH AP T E R   7   *    L E A R N IN G   AB OU T   CO M P O N E N TS   AN D  C L AS S  H I E R AR C H IE S 



              ReadOnly Property Deductions�┌� As ITaxDeduction�┌� 

              ReadOnly Property Ine�┌� As ITaxIne�┌� 

           End Interface 



                The bolded code illustrates the added parameters that are used to calculate Canadian taxes。  

          But is this a good solution�拭�No�察�it¨s a particularly bad solution。 The parameters are specific to  

          an implementation�察�and particularly to a Canadian implementation。 

                The parameter year could be justified because most countries do have specific tax rates  

          and implementations that are dependent on a year。 Yet the parameter province has no justifi

          cation。 Imagine trying to implement a British tax system and needing to specify a province�察 �

          when Britain does not collect ine tax at a local level。  

               A solution might be to redefine the interface as follows�此�



          Public Class Specifics  

              Public CanadianProvince As Province 

              Public AmericanState As State 

           End Class 



           Public Interface ITaxAccount  

              Sub AddDeduction��ByVal deduction As ITaxDeduction�� 

              Sub AddIne��ByVal ine As ITaxIne�� 

              Function GetTaxRate��ByVal ine As Double�察�ByVal year As Integer�察�_ 

              ByVal specifics As Specifics�� As Double 

              ReadOnly Property Deductions�┌� As ITaxDeduction�┌� 

              ReadOnly Property Ine�┌� As ITaxIne�┌� 

           End Interface 



                This new implementation has a specifics parameter�察�which is of type  Specifics。 The  

          purpose of Specifics is to define a class that is a hodgepodge of information that is needed to  

          determine the correct tax rate。 However�察�the Specifics approach is wrong�察�for the following  

          reasons�此�



               o  It requires knowing the implementation�察�which in the case of the interface is a bad idea。  

                  It is like going to a restaurant and saying you would like a waitress with blond hair。 



               o  Even if the type Specifics were acceptable�察�you would be adding and removing data  

                  members depending on how many tax systems you have implemented。 That is a bad  

                  idea and introduces maintenance issues。 



                The proposed solutions are not acceptable。 Additionally�察�there is still the problem of  

          having to figure out which tax rate to use。 



          Implementing Ideas with Specifics  



          To implement a solution�察�let¨s first start by fixing the TaxAccount class。 The modified version  

          will have some type of functionality that has data members that reference the year and prov

          ince。 Here is the modified and correct implementation of TaxAccount�此�


´´´´´´´´´´´´´´´´´´´´´´Page 207´´´´´´´´´´´´´´´´´´´´´´´

                           CH AP T E R   7   *    L E AR N IN G   AB O U T   CO M P O N E N TS   AN D   C L AS S  H I E R AR C HI E S 185 



Friend Class TaxAccount  

    Inherits BaseTaxAccount 



    Private _province As Province 

    Private _year  As Integer 



    Public Sub New ��ByVal province As Province�察�ByVal year As Integer��  

        _province = province 

        _year = year 

    End Sub 



    Public Overrides Function GetTaxRate��ByVal ine As Double��  As Double 

        If _year = 2008 Then 

            If _province = Province。Ontario Then 

                Return OntarioTax2008。TaxRate��ine�� 

            End If 

        End If 

        Throw New NotSupportedException�─�Year ; & _year & ; Province ; & _ 

            _province & ; not supported;�� 

    End Function 

End Class 



     The fix is to add a constructor that has province and year as parameters。 This sort of fix is  

quite mon�察�in that you don¨t change the interfaces�察�rather you change how the implemen

tations are instantiated。 Remember that when you instantiate a specific implementation�察�you  

know what functionality you want�察�and thus can give the additional parameters。 Once you are  

at the interface level�察�you should need to use only general ideas。  

     Now the TaxEngine class needs to be fixed。 TaxEngine is responsible for instantiating  

TaxAccount�察�and thus to instantiate a Canadian TaxAccount�察�TaxEngine needs additional  

parameters�察�as follows�此�



Friend Class TaxEngine  

    Inherits BaseTaxEngine 

    Public Overrides Function CreateTaxAccount�┌� As ITaxAccount  
卦指朕村 貧匯匈 和匯匈 指欺競何 壘��0�� 家��0��
隆堋響頼��紗秘慕禰厮宴和肝写偬堋響��
梁椣戻幣�� 梁心弌傍議揖扮窟燕得胎��傍竃徭失議心隈才凪万弌誌育断蛍�輌臆惨軼僑〃�燕慕得珊辛參資誼持蛍才将刮襲潜��範寔亟圻幹慕得 瓜寡追葎娼得辛參資誼寄楚署衛、持蛍才将刮襲潜填��