0

We have structured our application with typical layers. UI, Database access, services, Helpers etc. However, at the very top we have a project called "Interfaces" which contains the interface for pretty much every relevant class in the project. This leads to everything being available in every project.

Simplified it looks like this:

Interfaces => Database => Services => UI

Let's say we have a UI specific service "IWindowService" that deals with opening windows and popups.

Its suddenly available in a project way higher up in the hierarchy. Technically i have the option to write popups into my database layer.

Is this a bug or a feature? It reminds me a little of onion architecture, everything depends on the domain. But whats the point of layering, if it doesn't restrict access to anything?

It seems like Interface definitions should be placed with more care. A lot of them probably in the same project as the implementation, or higher up. But throwing everything in the top level project seems strange.

2

1 Answer 1

3

In short

It is not fully clear what kind of architecture you are using, but there's a high probability that your example is more a design issue than a feature;

Some more details

Layered architectures intend to reduce dependencies. Instead of any component being potentially dependent on any other, any component in one layer may be dependent on components of the layer below (in principle, immediately below, although open layers can be bypassed).

There are many variants, but for example:

                             dependency
Presentation (UI)                |
Services                         |
Data access layer (DAL)          |
Database                         V 

In such an architecture, the database or the data access layer should not know nor depend on UI. The idea is that you remain free to change anything on the top. For example offer a command line interface, a cash desk interface, of an augmented reality interface to the user, wihtout this affecting anyhow the database. So, no, in a layered architecture: IWindowService shall not be available in the DB service.

Concentric architectures, such as hexagonal architecture (it was the first), onion architecture or clean architecture adopt an inside-out approach, and keep interfaces with the external world in an outer layer. So instead of depending on your database, you can now change database as anything else, since it's in the outer layer.

In this architecture, the outer cores shall only be dependent on inner cores. But dependency inversion is used to allow the inner cores to use abstract interchangeable interfaces without knowing their specific implementations.

                                      dependency  dependency inversion
Interfaces (to DB, with user, ...)        |        <--+
Services                                  |           |
Business logic                            |           |
Entities                                  V        ---+

From what you describe, it seems that you are in a concentric arcthitecture. But it is still not fully clear if this is a bug or a feature:

  • If you could in the database layer use an interface that is interchangeable without depending on any specific implementation, and without making any assumptions, then you may be in a valid clean or onion architecture. I'd expect such an interface to be much more abstract, for example: INotifyError, since in no way shall the database layer implement an UI.
  • If the exposed interface requires assumptions about the user interface and specific knowledge. Then it would be a design issue considering the principle of least knowledge (your DB would need to know UI platform) and Single Responsibility Principle (the DB shall not deal with UI responsibilities).

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.