monix/monix-nio

Hide all types that we don't want exposed, most types should be final, etc.

alexandru opened this issue · 0 comments

Example:

abstract class AsyncChannelConsumer[T <: AsyncMonixChannel] extends Consumer[Array[Byte], Long]

Guys, there's no way we want to allow users to reuse this class, because this abstract class is a matter of implementation details.

Remember that after a 1.0 release when we'll start recommending this project to people, we'll need to maintain backwards compatibility.

We need to start from the concrete and evolve to the abstract, choosing along the way what we want to expose. And I know I'm going against OOP common practice, but if given the choice to pick between copy/paste or expose a common trait / abstract class for implementation reuse, I personally prefer to copy/paste. And for implementation reuse, the ideal is to expose (internal, private) functions.

Here's the plan:

  1. think hard about what needs to be exposed and hide everything that's not useful or that is half baked
  2. prefer functions for implementation reuse instead of inheritance
  3. all classes exposed must be final, unless we really, really want to allow inheritance
  4. all case class definitions need to be final
  5. protected refers to inheritance, therefore search and replace all protected[tcp] (and similar) with private[tcp] (or whatever the package is)

In concrete terms, the things I observed as needing improvement:

  1. monix.nio.AsyncChannelConsumer: such a type cannot be exposed, because this type is about implementation reuse and isn't useful as a polymorphic abstraction
  2. monix.nio.AsyncChannelObservable: such a type cannot be exposed, because this type is about implementation reuse and isn't useful as a polymorphic abstraction
  3. monix.nio.AsyncMonixChannel: this type is only supported for things that can do random access (i.e. files), needs refactoring (see #6) and shouldn't be in the base monix.nio package
  4. monix.nio.Bytes is private[nio], so move it to a new monix.nio.internal package, because code organization is very important for users that may want to browse the code and that want to see immediately the things they can use. See for example the root of monix-reactive as inspiration
  5. monix.nio.tcp.AsyncTcpClientConsumer should be final
  6. monix.nio.tcp.AsyncTcpClient should be final
  7. monix.nio.tcp.SocketClient should be final and should be private[nio] and not protected[nio]
  8. move stuff in monix.nio.file.internal to monix.nio.internal because we can do with a single internal package per project