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

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

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




existed�察�TaxEngine。CalculateTaxToPay�┌� would have needed to call the base class functionality  

to get the basic tax rate�察�and then recalculate the taxable monies to figure out if the surtax applied。 



*Note  When you use Overrides with methods�察�you are saying that you need something special。 This does  

not imply that the base class functionality will be called。 It implies that you might call the base class functionality  

and perform some additional operations。 Thus�察�when designing base class functionality�察�it is important to  

track calculations or operations using protected data members。 The data members avoid having derived classes  

perform the same operations multiple times�察�slowing down the application and avoiding potential errors。 



                                              USING NAMESPACES 



   Namespaces are used to define classes�察�interfaces�察�and structures that belong together。 In this chapter¨s  

   example�察�there is an American tax engine�察�a Swiss tax engine�察�and so on。 For organizational purposes�察�each  

   should have its own namespace。 Sometimes you might even create a custom assembly for each set of inter

   face implementations�察�but you would still need to create a namespace。 Creating a namespace is independent  

   of the fact of whether or not you create a separate assembly。 

         In the examples�察�I use namespaces like Surtax and Canada。 Whenever you create a class or a module�察 �

   or some other type�察�you can embed the type within the namespace。 Then to use the newly defined  

   namespaces in code pieces that are not part of the namespace�察�use the Imports keyword。  



Abstracting Instantiations with Factories 



Take a good look at the scope declaration of the tax engine shown earlier and pare it with  

the scope declaration for the ITaxEngine interface。 What you will notice is that  ITaxEngine is  

declared as Public scope�察�as is BaseTaxEngine�察�and TaxEngine is declared as  Friend。 Going back  

to our project structure�察�this scope declaration implies that any reference to LibTax will see the  

interface ITaxEngine and  BaseTaxEngine�察�but not TaxEngine。 For example�察�the following test  

code will not work。 



Dim taxengine As ITaxEngine = New Surtax。TaxEngine�┌� 



      The reason the test code will not work is that any type that is not declared with Public scope  

is private to the solution containing the declaration。 You may be thinking�察 �That¨s great!you  

declare a type that you cannot instantiate。 So�察�how can I use that type�拭院�

      The scope declarations are not a mistake and illustrate a design pattern called a factory 。 A  

factory is a way of abstracting the instantiation away from the caller so that the interface can  

vary from its implementation。 In our restaurant analogy�察�it means when you want a waiter�察�you  


´´´´´´´´´´´´´´´´´´´´´´Page 200´´´´´´´´´´´´´´´´´´´´´´´

178       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 



           don¨t want to need to know his name。 You would rather have a generic mechanism where the  

           restaurant presents to you the waiter。 Otherwise�察�to eat at a restaurant�察�you would need to  

           know the name of your waiter before being able to order something。 That would be inefficient。 

                The correct way of defining a factory is as follows�此�



              Public Module EngineCreator  

                  Public Function CreateSurtaxTaxEngine�┌� As ITaxEngine  

                      Return New Surtax。TaxEngine�┌� 

                  End Function 



                  ' Required for country´specific tax calculations 

                  Public Function CreateCanadianTaxEngine�┌� As ITaxEngine 

                      Return New Canada。TaxEngine�┌� 

                  End Function 

              End Module 



                The factory is typically declared in a module because a module is not instantiated。 Generally  

           speaking�察�you don¨t want to add a factory to an object that can be instantiated because it could  

           result in context´specific instantiation。 In other words�察�you usually want a fresh object created  

           from scratch each time�察�so it¨s not affected by the current state of the application。 In the imple

           mentation of CreateSurtaxTaxEngine�┌��察�the type Surtax。TaxEngine is instantiated�察�and the  

           instance is cast to the interface type ITaxEngine。 

                The EngineCreator module is declared with public scope�察�implying any code that references  

           the assembly can see the module。 Thus�察�the test code can be rewritten as follows ��we need to  

           import the LibTax project�察�of course���此�



           Dim taxengine As ITaxEngine = EngineCreator。CreateSurtaxTaxEngine�┌� 



                After calling  EngineCreator。CreateSurtaxTaxEngine�┌��察�the test code has a valid instance of  

           ITaxEngine。 It¨s very important to note that the test code has no idea what type implemented  

           the interface。 This allows the assembly to change which type is referenced in the implementa

           tion of CreateSurtaxTaxEngine�┌� without having to inform the caller of the method。 

                Putting this into the context of the restaurant�察�it means waiters can be replaced。 So if you  

           repeatedly visit a restaurant and get a waiter called John�察�but one day John gets sick and is not  

          working�察�you can still order and receive your food from the waitress called Mary。 It would be a  

           bad idea for a restaurant to depend on a particular server for a particular guest。 



           Using Default Implementations 



           In some cases�察�base classes are not necessary。 Sometimes you can create a default implemen

           tation that could span multiple subsystems。 In the case of the tax engine�察�an ine is an ine  

           in Canada�察�an ine in the United States�察�and an ine in Germany。 What varies is how the  

           ine is treated in each country when calculating taxes。 Another consistency across countries is  

           that if ine is a capital gain�察�not all of the ine is taxable。 

                In the case of ine�察�you can create an implementation that would be identical across  

           different tax engines�察�as follows�此�


´´´´´´´´´´´´´´´´´´´´´´Page 201´´´´´´´´´´´´´´´´´´´´´´´

                           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 179 



NotInheritable Class TaxIne  

    Implements ITaxIne 



    Private _amount As Double 

    Private _taxableRate As Double 



    Public Sub New��ByVal amount As Double�察�ByVal taxableRate As Double��  

        _amount = amount 

        _taxableRate = taxableRate 

    End Sub 

     

    Public ReadOnly Property RealAmount�┌� As Double _ 

        Implements ITaxIne。RealAmount 

        Get  

            Return _amount 

        End Get 

    End Property 



    Public ReadOnly Property TaxableAmount�┌� As Double _ 

        Implements ITaxIne。TaxableAmount 

        Get 

            Return _amount * _taxableRate 

        End Get 

    End Property 

End Class 



     The ITaxIne interface has two properties that are implemented in TaxIne�此�RealAmount  

and TaxableAmount。 The values for the two properties are considered read´only and are defined  

by the constructor of TaxIne。 The purpose of the constructor is to assign two values and  

then consider the object as immutable。 If you wanted to change the values of the ITaxIne  

interface�察�you would need to instantiate a new instance of TaxIne。 While it sounds like a pain  

to need to instantiate a new instance whenever you want to change the value of the RealAmount and  

TaxableAmount properties�察�this approach has some advantages in terms of performance and  

resource management。 

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