Как насчет того, чтобы сделать его управляемым событиями? Уровень GUI подписывается на события из уровня данных или связи, и когда событие запускается, знает, чтобы обновить себя. Таким образом, уровень GUI знает о слое data / comms, но не наоборот.
Кстати, не уверен, что ваша среда, но нужно быть осторожным, обновляя GUI из потока, на котором запущено событие. Например, в .NET вам потребуется использовать Control.Invoke (http://msdn.microsoft.com/en-us/library/zyzhdc6b.aspx) для обновления графического интерфейса из потока, не являющегося графическим интерфейсом.