友情提示:如果本网页打开太慢或显示不完整,请尝试鼠标右键“刷新”本网页!阅读过程发现任何错误请告诉我们,谢谢!! 报告错误
狗狗书籍 返回本书目录 我的书架 我的书签 TXT全本下载 进入书吧 加入书签

VB2008从入门到精通(PDF格式英文版)-第88章

按键盘上方向键 ← 或 → 可快速上下翻页,按键盘上的 Enter 键可回到本书目录页,按键盘上方向键 ↑ 可回到本页顶部!
————未阅读完?加入书签已便下次继续阅读!




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 multip
返回目录 上一页 下一页 回到顶部 0 0
未阅读完?加入书签已便下次继续阅读!
温馨提示: 温看小说的同时发表评论,说出自己的看法和其它小伙伴们分享也不错哦!发表书评还可以获得积分和经验奖励,认真写原创书评 被采纳为精评可以获得大量金币、积分和经验奖励哦!