16. Object Diagrams

image

Sometimes, it can be useful to show the state of the system at a particular time. Like a snapshot of a running system, a UML object diagram shows the objects, relationships, and attribute values that obtain at a given instant.

A Snapshot in Time

Some time ago, I was involved with an application that allowed users to draw the floor plan of a building on a GUI. The program captured the rooms, doors, windows, and wall openings in the data structure, as shown in Figure 16-1. Although this diagram shows you what kinds of data structures are possible, it does not tell you exactly what objects and relationships are instantiated at any given time.

Figure 16-1. Floor plan

image

Let’s assume that a user of our program draws two rooms, a kitchen, and a lunchroom, connected by a wall opening. Both the kitchen and the lunchroom have a window to the outside. The lunchroom also has a door that opens outward to the outside. This scenario is depicted by the object diagram in Figure 16-2. This diagram shows the objects that are in the system and what other objects they are connected to. It shows kitchen and the lunchRoom as separate instances of Space. It shows how these two rooms are connected by a wall opening. It shows that the outside is represented by another instance of space. And it shows all the other objects and relationships that must exist.

Figure 16-2. Lunchroom and kitchen

image

Object diagrams like this are useful when you need to show what the internal structure of a system looks like at a particular time, or when the system is in a particular state. An object diagram shows the intent of the designer. It shows the way that certain classes and relationships are going to be used. It can help to show how the system will change as various inputs are given to it.

But be careful; it is easy to get carried away. In the past decade, I have probably drawn fewer than a dozen object diagrams of this kind. The need for them simply has not arisen very frequently. When they are needed, they are indispensable, and that’s why I’m including them in this book. However, you aren’t going to need them very often, and you should definitely not assume that you need to draw them for every scenario in the system or even for every system.

Active Objects

Object diagrams are also useful in multithreaded systems. Consider, for example, the SocketServer code in Listing 16-1. This program implements a simple framework that allows you to write socket servers without having to deal with all the nasty threading and synchronization issues that accompany sockets.

image


Listing 16-1. SocketServer.cs

using System.Collections;
using System.Net;
using System.Net.Sockets;
using System.Threading;

namespace SocketServer
{

  public interface SocketService
  {
    void Serve(Socket s);
  }

  public class SocketServer
  {
    private TcpListener serverSocket = null;
    private Thread serverThread = null;
    private bool running = false;
    private SocketService itsService = null;
    private ArrayList threads = new ArrayList();

    public SocketServer(int port, SocketService service)
    {
      itsService = service;
      IPAddress addr = IPAddress.Parse("127.0.0.1");
      serverSocket = new TcpListener(addr, port);
      serverSocket.Start();
      serverThread = new Thread(new ThreadStart(Server));
      serverThread.Start();
    }

    public void Close()
    {
      running = false;
      serverThread.Interrupt();
      serverSocket.Stop();
      serverThread.Join();
      WaitForServiceThreads();
    }

    private void Server()
    {
      running = true;
      while (running)
      {
        Socket s = serverSocket.AcceptSocket();
        StartServiceThread(s);
      }
    }

    private void StartServiceThread(Socket s)
    {
      Thread serviceThread =
        new Thread(new ServiceRunner(s, this).ThreadStart());
      lock (threads)
      {
        threads.Add(serviceThread);
      }
      serviceThread.Start();
    }


    private void WaitForServiceThreads()
    {
      while (threads.Count > 0)
      {
        Thread t;
        lock (threads)
        {
          t = (Thread) threads[0];
        }

        t.Join();
      }
    }

    internal class ServiceRunner
    {
      private Socket itsSocket;
      private SocketServer itsServer;

      public ServiceRunner(Socket s, SocketServer server)
      {
        itsSocket = s;
        itsServer = server;
      }


      public void Run()
      {
        itsServer.itsService.Serve(itsSocket);
        lock (itsServer.threads)
        {
          itsServer.threads.Remove(Thread.CurrentThread);
        }
        itsSocket.Close();
      }

      public ThreadStart ThreadStart()
      {
        return new ThreadStart(Run);
      }
    }
  }
}


The class diagram for this code is shown in Figure 16-3. It’s not very inspiring, and it’s difficult to see what the intent of this code is from the class diagram. The figure shows all the classes and relationships, but somehow the big picture doesn’t come through.

Figure 16-3. SocketServer class diagram

image

However, look at the object diagram in Figure 16-4. This shows the structure much better than the class diagram does. Figure 16-4 shows that the SocketServer holds onto the serverThread and that the serverThread runs in a delegate named Server(). It shows that the serverThread is responsible for creating all the ServiceRunner instances.

Figure 16-4. SocketServer object diagram

image

Note the heavy bold lines around the Thread instances. Objects with heavy bold borders represent active objects, which act as the head of a thread of control. They contain the methods, such as Start, Abort, Sleep, and so on, that control the thread. In this diagram, all the active objects are instances of Thread because all the processing is done in delegates that the Thread instances hold references to.

The object diagram is more expressive than the class diagram because the structure of this particular application is built at runtime. In this case, the structure is more about objects than about classes.

Conclusion

Object diagrams provide a snapshot of the state of the system at a particular time. This can be a useful way to depict a system, especially when the system’s structure is built dynamically instead of imposed by the static structure of its classes. However, one should be leery of drawing many object diagrams. Most of the time, they can be inferred directly from corresponding class diagrams and therefore serve little purpose.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.235.46.191