| only for RuBoard |
Many books that cover object-oriented design do not focus on any particular language. Some don't even contain one line of code, which shows that knowledge of object design can transcend whatever language you work with.
This chapter mentions several good and not-so-good programming practices, but this discussion is only an introduction to the topic. You should remember a few general rules that will get you started on the right track:
Design a class from the
Limit scope as much as possible when dealing with classes,
Classes are nouns; methods are verbs. If you find yourself writing a class named Wash , you really might be writing a method that should be in Car .
Methods imply behavior; properties imply state. Don't confuse the two concepts.
Minimize interactions among classes to reduce complexity in the system.
The first abstraction you come up with is probably not the best. If you get an abstraction wrong, you might end up coding yourself into a corner later on and be forced to punch holes in your once-beautiful object hierarchy.
Whatever you do, be consistent. A lack of consistency is a lack of style. Develop your style. The people who have to look at your code when you leave will thank you instead of curse you.
| only for RuBoard |
| only for RuBoard |
The chapter is "officially" over (wink, wink). The following two listings are only an exercise. Example 3-16 contains a remote debugging console. This console window can run on any computer on your network (or it can run on your only computer if you are processor-challenged). It just sits there, waiting for messages from the RemoteDebug class, which is shown in Example 3-17. To run the remote debug console, compile Example 3-16 and type the following code on the command line:
C:\>listener 1969
This line causes the remote console to wait for messages on port 1969.
Example 3-16 can be compiled from the command line as
vbc /t:exe /r:system.dll listener.vb
Example 3-17 contains the listing for the
RemoteDebug
class, which sends messages to the remote debug console. It also
contains a small test class so you can compile the class to an
executable and test it. Once the remote debug console is started,
you have to
Example 3-17, however, wires the remote debug class into the Log example from Example 3-9 earlier in the chapter. It can be compiled the same way as Example 3-16.
'references: system.dll
Imports System
Imports System.Net
Imports System.Net.Sockets
Imports System.Text
Public Class Listener
Implements IDisposable
Private port As Integer
Private myListener As TcpListener
Private mySocket As Socket
Private disposed As Boolean
Public Sub New(ByVal port As Integer)
Me.port = port
myListener = New TcpListener(port)
End Sub
Public Sub Listen( )
Dim buffer(1024) As Byte
Dim bytes As Integer
Dim ASCII As Encoding = Encoding.ASCII
'Start the listener
myListener.Start( )
'Wait for a connection
mySocket = myListener.AcceptSocket( )
myListener.Stop( )
'Read incoming bytes and convert to an ASCII
'string
bytes = mySocket.Receive(buffer, buffer.Length, 0)
Do While (bytes > 0)
Dim msg As String
msg = ASCII.GetString(buffer, 0, bytes)
Console.WriteLine(msg)
bytes = mySocket.Receive(buffer, buffer.Length, 0)
Loop
mySocket.Close( )
End Sub
Protected Overridable Sub DoDispose( )
mySocket.Close( )
MyListener.Stop( )
GC.SuppressFinalize(Me)
End Sub
Public Sub Dispose( ) Implements IDisposable.Dispose
Dispose(True)
GC.SuppressFinalize(Me)
End Sub
Protected Sub CheckDispose( )
If (disposed) Then
Throw New ObjectDisposedException( _
"RemoteDebug has been disposed.")
End If
End Sub
Protected Sub Dispose(ByVal disposing As Boolean)
If Not disposed Then
disposed = True
If (disposing) Then
DoDispose( )
End If
End If
End Sub
Public Sub Close( )
Dispose( )
End Sub
Protected Overrides Sub Finalize( )
Close( )
End Sub
End Class
Public Class Application
Public Shared Sub Main(ByVal args( ) As String)
If args.Length > 1 Then
Dim port As Integer = Convert.ToInt32(args(1))
Console.WriteLine("Listening on port {0}", port.ToString( ))
Dim myListener As New Listener(port)
While (True)
myListener.Listen( )
End While
Else
Console.WriteLine("USAGE: listen <port number>")
End If
End Sub
End Class
'references: system.dll
Imports System
Imports System.Net
Imports System.Net.Sockets
Imports System.Text
Public Class RemoteDebug
Implements IDisposable
Private remoteServer As IPAddress
Private endPoint As IPEndPoint
Private sock As Socket
Private ASCII As Encoding
Private disposed As Boolean
Public Sub New(ByVal server As String, ByVal port As Integer)
ASCII = Encoding.ASCII
remoteServer = Dns.Resolve(server).AddressList(0)
EndPoint = New IPEndPoint(remoteServer, port)
'Create the Socket for sending data over TCP
sock = New Socket(AddressFamily.InterNetwork, _
SocketType.Stream, _
ProtocolType.Tcp)
sock.Connect(EndPoint)
End Sub
Public Sub Write(ByVal msg As String)
CheckDispose( )
If sock.Connected Then
Dim buffer( ) As Byte = ASCII.GetBytes(msg)
sock.Send(buffer, buffer.Length, 0)
End If
End Sub
Public Sub Dispose( ) Implements IDisposable.Dispose
Dispose(True)
GC.SuppressFinalize(Me)
End Sub
Protected Overridable Sub DoDispose( )
sock.Shutdown(SocketShutdown.Send)
sock.Close( )
GC.SuppressFinalize(Me)
End Sub
Protected Sub CheckDispose( )
If (disposed) Then
Throw New ObjectDisposedException( _
"RemoteDebug has been disposed.")
End If
End Sub
Protected Sub Dispose(ByVal disposing As Boolean)
If Not disposed Then
disposed = True
If (disposing) Then
DoDispose( )
End If
End If
End Sub
Public Sub Close( )
Dispose( )
End Sub
Protected Overrides Sub Finalize( )
Close( )
End Sub
End Class
Public Class Test
Public Shared Sub Main( )
Dim dbg As New RemoteDebug("localhost", 1969)
dbg.Write("This is a test")
dbg.Close( )
End Sub
End Class
| only for RuBoard |