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