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