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