嗔秤戻幣�哉膵�云利匈嬉蝕湊蛸賜�塋床四衲���萩晦編報炎嘔囚^泡仟 ̄云利匈��
源平慎弌傍利 卦指云慕朕村 紗秘慕禰 厘議慕尺 厘議慕禰 TXT畠云和墮 〆辺茄欺厘議箝誓匂〇

VB2008貫秘壇欺娼宥(PDF鯉塀哂猟井)-及43何蛍

酔楯荷恬: 梓囚徒貧圭�鮗� ○ 賜 ★ 辛酔堀貧和鍬匈 梓囚徒貧議 Enter 囚辛指欺云慕朕村匈 梓囚徒貧圭�鮗� ● 辛指欺云匈競何! 泌惚云慕短嗤堋響頼���誅卒亮茂�俊彭堋響��辛聞喘貧圭 "辺茄欺厘議箝誓匂" 孔嬬 才 "紗秘慕禰" 孔嬬��



              End Function 



              Public Sub Reset�┌� _ 

              Implements IEnumerator。Reset 

                  _currNode = _firstNode 

              End Sub 

          End Class 



               A class that can be enumerated must fulfill two objectives�此�implement the  IEnumerable  

          interface and implement the IEnumerator interface。 The IEnumerable class has a single method�察 �

          GetEnumerator�┌��察�which is used to retrieve a class instance that implements the IEnumerator  

          interface。 The two interfaces are split because retrieving the iteration functionality and iter

          ating the collection are two separate steps。 However�察�in the case of  LinkedListEnumerable�察 �

          these steps are bined into one class�察�and that is often the case。 

               The best way to explain how  LinkedListEnumerable works is to go through the code and  

          explain what methods and properties are called。 



               1。 The code in the client application starts a For Each loop�察�and sets up a context where a  

                   collection of elements is being iterated。 



               2。 The code calls the collection iterator。 In the example�察�this means calling the method  

                   RoomGroupingIterator�┌�。 



               3。  RoomGroupingIterator�┌� returns an instance of  LinkedListEnumerable�察�which is assigned  

                   the linked list that will be iterated。 



                      Public Function RoomGroupingIterator�┌� As IEnumerable 

                          Return New LinkedListEnumerable��_roomGroupings�� 

                      End Function 


´´´´´´´´´´´´´´´´´´´´´´Page 241´´´´´´´´´´´´´´´´´´´´´´´

                             C H AP TE R   8   *    L E AR N IN G   AB O U T   CO M P O N E N T O R IE N TE D   A R CH I TE C TU R E 219 



     4。  The method  LinkedListEnumerable。GetEnumerator�┌� is called�察�and an instance of  

         IEnumerator is returned。 



     5。  The code calls the method  LinkedListEnumerable。MoveNext�┌�。  



     6。  The implementation of MoveNext�┌� returns True to indicate that it was possible to move  

         to the next element。 If  False is returned�察�it means that the end of the collection!or in  

         this case�察�the linked list!is reached。  



     7。  If MoveNext�┌� returns True�察�then the property LinkedListEnumerable。Current�┌� is called  

         to retrieve the current linked list element。  



     8。  The retrieved linked list element is assigned to the variable of the For Each loop�察�which  

         is rg in this example。 



     9。  Control is returned to the For Each loop�察�and the user code does something with the  

         linked list element。  



    10。  When the For Each loop attempts another iteration�察�steps 5 through 9 are repeated until  

         MoveNext�┌� returns  False。 



    11。  When MoveNext�┌� returns  False�察�the iterator exits�察�causing an exit of the For Each loop。 



Adding Rooms to Groupings 



The data handle that we defined when adding the grouping is used when we add a room to a  

grouping。 The idea of the handle is to provide a reference that the kernel can use。 Since the  

handle is an instance of a RoomGrouping type�察�whenever a room is added to a grouping based on  

a handle�察�it is not necessary to find the room grouping。 The handle is the room grouping�察�and  

all that is necessary is a type cast。 The following demonstrates how to add a room to a room  

grouping ��in  LightingController��。 



Public Sub AddRoomToGrouping��ByVal grouping As Object�察�ByVal room As IRoom�� 

    Dim roomGrouping As RoomGrouping = TryCast��grouping�察�RoomGrouping�� 

    If roomGrouping Is Nothing Then 

        Throw New Exception�─�_ 

          ;Handle grouping is not a valid room grouping instance;�� 

    End If 

    Dim oldRooms As Room = TryCast��roomGrouping。Rooms�察�Room�� 

    If  oldRooms Is Nothing Then  

        roomGrouping。Rooms = New Room�┌� With ��。ObjRoom = room�� 

    Else  

        roomGrouping。Rooms。Insert��New Room�┌� With ��。ObjRoom = room���� 

    End If 

End Sub 



     In the implementation of AddRoomToGrouping�┌��察�the first step is to cast the handle grouping  

to an instance of RoomGrouping。 The cast used is the TryCast�┌� function�察�so that if the cast fails�察 �

it is only necessary to test if roomGrouping is not Nothing。 Executing the Nothing test is absolutely  

vital�察�otherwise�察�you might perform operations that will cause an exception to be thrown。 


´´´´´´´´´´´´´´´´´´´´´´Page 242´´´´´´´´´´´´´´´´´´´´´´´

220       CH AP T E R   8   *    L E A R N IN G   AB OU T   CO M P O N E N TO R IE N T E D  AR C HI TE CT U R E 



                Once the handle has been cast to a RoomGrouping instance�察�adding a room to the linked list  

           is trivial。 Adding a room involves only assigning the head of the list if there are no rooms in the  

          list�察�or calling the method Insert�┌� if there are rooms。 



           Performing Operations on a Group 



          With a grouping defined�察�you can perform global operations that affect all rooms of a grouping。  

           One example is turning off the lights in all the rooms in a grouping�察�which is based on the IRoom  

           interface instance。 Here is the code to turn off all of the lights in a grouping�此�



           Public Sub TurnOffLights��ByVal grouping As Object��  

                  Dim enumerableGrouping As LinkedListEnumerable = _ 

                    New LinkedListEnumerable��TryCast��grouping�察�BaseLinkedListItem���� 

                  For Each room As IRoom In enumerableGrouping  

                  Dim remote As IRemoteControlRoom = TryCast��room�察�IRemoteControlRoom�� 

                  Dim sensorRoom As ISensorRoom = TryCast��room�察�ISensorRoom�� 

                  If sensorRoom IsNot Nothing Then 

                      If Not sensorRoom。IsPersonInRoom Then 

                          Continue For 

                      End If 

                  ElseIf remote IsNot Nothing Then 

                      remote。LightSwitch��False�� 

                  End If 

              Next 

           End Sub 



                Notice that the handle is not converted into a RoomGrouping instance。 The handle is type  

           cast to BaseLinkedListItem�察�and then passed to the LinkedListEnumerable constructor。 For each  

           iteration of the For Each loop�察�the IRoom instance room is cast into the types IRemoteControlRoom  

           and ISensorRoom。 A cast to both of these types is necessary because�察�depending on the room  

           type�察�certain algorithms need to be executed。 For example�察�if the room is of type ISensorRoom  

           and the property IsPersonInRoom is True�察�then the lights should be left as is。 If the lights are to  

          be left as is�察�that means performing the next iteration using the Continue For keywords。 

                If the processing continues�察�we check if the room can be remotely controlled�察�which means  

           it implements the interface IRemoteControlRoom。 If remote is not Nothing�察�then we can call the  

           LightSwitch�┌� method with a parameter of  False to turn off the lights。 The iteration continues  

           for all rooms in the grouping。 

                This pletes the kernel�察�but before you how it fits with a lighting application�察�I would  

          like to discuss an alternative approach to implementing the kernel。 



           Defining the Kernel As an Interface Instead of a Class 



          As I noted earlier�察�rather than defining the kernel as a class�察�another approach would be to define  

           the kernel as an interface that is implemented。 If a pany were to distribute multiple implemen

           tations of a controller�察�an interface would be appropriate�察�but only if the multiple implementations  

           of the interface used the same set of methods。  


´´´´´´´´´´´´´´´´´´´´´´Page 243´´´´´´´´´´´´´´´´´´´´´´´

                              C H AP TE R   8   *    L E AR N IN G   AB O U T   CO M P O N E N T O R IE N TE D   A R CH I TE C TU R E 221 



      Do not confuse multiple implementations with multiple implementations that offer a  

pletely different feature set。 For example�察�controller version 1 and controller version super

duper 1000 might control the same room types�察�but the inputs�察�outputs�察�logic�察�and algorithms  

contained in each might be pletely different。 In that case�察�using an interface gains no advan

tage。 You might use a version 1 interface on a version super´duper 1000 for legacy integration�察 �

since the old interface has older ideas。 

     You would use an interface for the controller when multiple controllers implement the  

same interface。 You would use an interface if you want the flexibility to later implement multiple  

implementations using the same interface。 On the other hand�察�if there will only ever be a single  

implementation for a single interface declaration�察�it¨s much easier to use a class declared as  

Public。 

      If you do decide to declare the controller using an interface and implementation�察�you need  

to structure the project differently than the organization used for this chapter¨s example。 The  

reason is that you cannot declare the interfaces and implementations in the same project。  

Imagine trying to offer multiple kernel implementations�察�but for the users to be able to use the  

interfaces�察�they must reference a project that contains a particular kernel implementation。  

     You will need to modularize the structure and have an organization similar to that shown  

in Figure 8´5。  



Figure 8´5。 Organization of a modular interface and implementation architecture 


´´´´´´´´´´´´´´´´´´´´´´Page 244´´´´´´´´´´´´´´´´´´´´´´´

222       CH AP T E R   8   *    L E A R N IN G   AB OU T   CO M P O N E N TO R IE N T E D  AR C HI TE CT U R E 



                In Figure 8´5�察�the individual boxes represent a single  assembly。 Each assembly serves  

           a unique purpose�此�



               o  Definitions�此�An assembly that contains all interfaces used by all of the other assemblies。  

                  This represents a single assembly that changes very rarely and is a cornerstone of the  

                  application。 Along with interfaces�察�you would add general utility classes that all assem

                  blies would reference。 



               o  User�此�The main application that interacts with the interfaces of objects that are imple

                  mented in either the Kernel or  Implementations assemblies。 The User assembly is  

                  responsible for wiring together all of the types。 



               o  Kernel�此�An assembly that defines the main functionality of the application and manipu

                  lates instances that implement interfaces from the Definitions assembly。 The kernel  

                  does not know where the interfaces are implemented�察�and it expects some other piece of  

                  code to know where the implementations are。 



               o  Implementations�此�An assembly that contains the implementations of the interfaces that  

                  the kernel manipulates。 The programmer may create a single implementation assembly  

                  or multiple assemblies。 The implementations are only aware of the Definitions assembly�察 �

                  they are unaware of the Kernel assembly。 



           Building a plete Application 



          All of the code illustrated thus far is related to the kernel�察�and it would seem that our applica

           tion is plete。 In reality�察�the kernel has done nothing other than organize and manipulate  

           the rooms。 The kernel has not defined any implementations for a particular room。 Now let¨s  

           see how to define some rooms and use the rooms in the context of the kernel。  

                The idea is to enable a developer to add functionality to the kernel without affecting the  

           code of the kernel。 The example that we will go through defines a couple of rooms in a museum  

           ��the Museum project��。 



           *Note  The implementation of the Home project is not discussed here�察�but it is available in this book¨s down

           loadable source code。 



           Defining Some Rooms 



           The rooms are defined in a separate assembly called Museum and are not part of the kernel。 The  

           following is an example of a room implementation。 Again�察�remember to include a reference to  

           LibLightingSystem ��right´click References in Museum and select Add Reference then Projects   

           LibLightingSystem��。 


´´´´´´´´´´´´´´´´´´´´´´Page 245´´´´´´´´´´´´´´´´´´´´´´´

                           C H AP TE R   8   *    L E AR N IN G   AB O U T   CO M P O N E N T O R IE N TE D   A R CH I TE C TU R E 223 



。 。 。 

Imports LibLightingSystem 



    Friend Class PrivateRoom �此�Implements INoRemoteControlRoom  

    End Class 



    Friend Class PublicRoom �此�Implements ISensorRoom  

        Public ReadOnly Property IsPersonInRoom�┌� As Boolean _ 

            Implements ISensorRoom。IsPersonInRoom 

            Get  

                 Return False 

            End Get 

        End Property 



        Private _lightLevel As Double 



        Public ReadOnly Property LightLevel�┌� As Double _ 

            Implements ISensorRoom。LightLevel 

            Get 

                Return _lightLevel 

            End Get 

        End Property  



        Public Sub LightSwitch��ByVal lightState As Boolean�� _ 

            Implements IRemoteControlRoom。LightSwitch 

            If lightState Then 

                _lightLevel = 1 

            Else 

                _lightLevel = 0 

            End If 

        End Sub  



        Public Sub DimLight��ByVal level As Double�� _ 

            Implements IRemoteControlRoom。DimLight 

            _lightLevel = level 

        End Sub 

    End Class 



     The two room declarations�察�PrivateRoom and  PublicRoom�察�are both internal to the assembly。  

Each room implements the interface that it deems appropriate。 PrivateRoom implements the  

interface INoRemoteControlRoom�察�indicating that LightingController should leave the room alone。  

     PublicRoom implements ISensorRoom�察�indicating that it will tell the controller when a person is  

in the room and allow itself to be controlled。 The implementation of  PublicRoom is trivial and  

frankly not that useful�察�but it illustrates the bare minimum of what needs to be implemented。  

In a production environment�察�PublicRoom would have access to external devices such as a  

heat sensor and lights。 The objective of PublicRoom would be to give and take signals from the  

LightingController and take action。 It is not up to PublicRoom to ask whether or not a decision  


´´´´´´´´´´´´´´´´´´´´
卦指朕村 貧匯匈 和匯匈 指欺競何 壘��16�� 家��13��
酔楯荷恬: 梓囚徒貧圭�鮗� ○ 賜 ★ 辛酔堀貧和鍬匈 梓囚徒貧議 Enter 囚辛指欺云慕朕村匈 梓囚徒貧圭�鮗� ● 辛指欺云匈競何!
梁椣戻幣�� 梁心弌傍議揖扮窟燕得胎��傍竃徭失議心隈才凪万弌誌育断蛍�輌臆惨軼僑〃�燕慕得珊辛參資誼持蛍才将刮襲潜��範寔亟圻幹慕得 瓜寡追葎娼得辛參資誼寄楚署衛、持蛍才将刮襲潜填��