# Informal interfaces and abstract types

**URL:** <https://discourse.julialang.org/t/informal-interfaces-and-abstract-types/95993>\
**Category:** General Usage\
**Tags:** question, design-pattern\
**Created:** [March 13, 2023, 10:42am UTC](https://discourse.julialang.org/t/informal-interfaces-and-abstract-types/95993 "2023-03-13T10:42:10Z")\
**Posts on this page:** 2\
**Page:** 1

<div class="post-metadata">

**Author:** ![nolb](https://avatars.discourse-cdn.com/v4/letter/n/96bed5/32.png) [@nolb](https://discourse.julialang.org/u/nolb)\
**Post date:** [March 13, 2023, 10:42am UTC](https://discourse.julialang.org/t/informal-interfaces-and-abstract-types/95993/1 "2023-03-13T10:42:10Z")

</div>

Hi everyone,

I have a question regarding best practices for the design of informal interfaces.

Let’s say that I want to implement a service that continuously reads in data from a source, processes the data, and publishes the result somewhere. The service should be configurable, such that it can read in data from different sources (e.g., filesystem, database, Kafka topic, etc.). The same goes for publishing the output.

Initially I would have implemented this with abstract types along these lines (and how it is described in this tutorial: [Getting Started With Julia : Interfaces | packtpub.com - YouTube](https://www.youtube.com/watch?v=2U6FrrB9PtM)):

```julia
# A reader reads in data from some input
#
# Required methods:
#
# read_data(reader) - provide the next data object of the reader
abstract type Reader end

# Provide the next data object
function read_data end

struct FileSystemReader <: Reader
    path_to_files::String
    ...
end

struct KafkaReader <: Reader
    address::String
    ...
end

```

The publisher interface would be implemented analogously. Finally, I would have kept the reader and the publisher of a service in another type:

```julia
struct Service
    reader::Reader
    publisher::Publisher
    ...
end

```

Since the `reader` and the `publisher` attributes would rarely get accessed, I am not worried about performance and thus using abstract types for those fields is fine.

However, at this point I am wondering what the actual benefit of having the abstract types `Reader` and `Publisher` would be. Actually, I think it would only be a restriction. For example, if I want to have a type that implements both interfaces, this type could only be a subtype of either `Reader` or `Publisher`.

Therefore, I am currently leaning towards this implementation without using abstract types:

```julia
# A reader reads in data from some input
#
# Required methods:
#
# read_data(reader) - provide the next data object of the reader

# Provide the next data object
function read_data end

struct FileSystemReader # implements the reader interface
    path_to_files::String
    ...
end

function read_data(reader::FileSystemReader)
    ...
end

struct KafkaClient # implements the reader interface and the publisher interface
    address::String
    ...
end

function read_data(client::KafkaClient)
    ...
end

function publish(client::KafkaClient)
    ...
end

...

struct Service
    reader # must implement the reader interface
    publisher # must implement the publisher interface
    ...
end

```

It looks a bit odd to not have a type here associated with the attributes of `Service`, but again, I am not worried about performance here. Of course, I could also parameterize the `Service` type.

The only benefit of having abstract types that I can think of is dynamic dispatch when there was some sort of hierarchy associated with readers and publisher (which I don’t expect to have in my service). For example, maybe I want to treat “remote” and “local” readers differently.

```julia
abstract type Reader end
abstract type RemoteReader <: Reader end # supertype of KafkaReader
abstract type LocalReader <: Reader end # supertype of FileSystemReader

```

However, I could also achieve this differentiation using Traits without having the issue that a type cannot be a reader and a publisher at the same time.

My question now is: Am I missing something here? Are there additional benefits of using abstract types when defining informal interfaces that I am currently not seeing?

Thanks a lot in advance for your feedback.

---

<div class="post-metadata">

**Author:** ![nolb](https://avatars.discourse-cdn.com/v4/letter/n/96bed5/32.png) [@nolb](https://discourse.julialang.org/u/nolb)\
**Post date:** [May 11, 2023, 8:57am UTC](https://discourse.julialang.org/t/informal-interfaces-and-abstract-types/95993/2 "2023-05-11T08:57:06Z")

</div>

I saw that a similar question has already been asked here: [Why use subtypes instead of traits and duck typing?](https://discourse.julialang.org/t/why-use-subtypes-instead-of-traits-and-duck-typing/59146)
