Yes you're right. The Topic is used as the Group actor. 
At the beginning I wrote a separate Group actor, but I found that many code are the same , such as the Prune logic. So I merge them together.
Here is the separate Group actor:
```scala
    class Group(emptyTimeToLive: FiniteDuration, routingLogic: RoutingLogic) extends Actor with ActorLogging {
      import context.dispatcher
      val pruneInterval: FiniteDuration = emptyTimeToLive / 2
      val pruneTask = context.system.scheduler.schedule(pruneInterval, pruneInterval, self, Prune)
      var pruneDeadline: Option[Deadline] = None

      var subscribers = Set.empty[ActorRef]

      override def postStop(): Unit = {
        super.postStop()
        pruneTask.cancel()
      }

      def receive = {
        case msg @ Subscribe(topic, group, ref) ⇒
            context watch ref
            subscribers += ref
            pruneDeadline = None
            context.parent ! Subscribed(SubscribeAck(msg), sender())
        case msg @ Unsubscribe(topic, group, ref) ⇒
          context unwatch ref
          remove(ref)
          context.parent ! Unsubscribed(UnsubscribeAck(msg), sender())
        case Terminated(ref) ⇒
          remove(ref)
        case Prune ⇒
          for (d ← pruneDeadline if d.isOverdue) context stop self
        case SendToOneSubscriber(msg) ⇒
          if (subscribers.nonEmpty)
            Router(routingLogic, (subscribers map ActorRefRoutee).toVector).route(msg, sender())
        case msg ⇒
          subscribers foreach { _ forward msg }
      }

      def remove(ref: ActorRef): Unit = {
        if (subscribers.contains(ref)) {
          subscribers -= ref
          if (subscribers.isEmpty)
            pruneDeadline = Some(Deadline.now + emptyTimeToLive)
        }
      }
    }
```

Shall we do the separating?