Override the operation and scale the result of exactly one superclass call:
class ScaledSumChannel(factor: Int) extends SumChannel {
  override def apply(n: Int): Int = factor * super.apply(n)
}
The superclass updates its previous-input state once and returns its ordinary sum; only that returned value is scaled. The inputs and superclass history are unchanged by the scaling. Reimplementing the state update is unnecessary and could accidentally diverge from the superclass contract. As in the supplied channel, arithmetic uses the declared fixed-width integer type.
Use the decorator pattern. The wrapper implements the same object interface as its component and delegates before changing the output:
class ScaledChannel(inner: Channel, factor: Int) extends Channel {
  override def apply(n: Int): Int = factor * inner(n)
}
It can wrap any channel software object, not only a sum channel. Constructing the wrapper at run time chooses the additional behavior for an existing component, and several wrappers can be composed without adding a subclass for every combination. Each call reaches the wrapped channel once, preserving its state evolution. Scaling the input instead would define a different transformation, particularly for a component that already has history.
Class inheritance offers a compact specialized implementation: the scaled sum is also a SumChannel and can be used where that concrete type is required, while its inherited state handling is reused directly.
The decorator supports run-time object composition over any Channel implementation, including an already constructed stateful software object, without editing or subclassing each concrete software class. Its extra software object and delegation are a small cost. The two approaches therefore serve different reuse needs; the wrapper need not pretend to be the concrete sum-channel software class.

Articles by others on the same topic (0)

There are currently no matching articles.