eunice

introhow it workscase studieslanguagesissuesblog

structure

stacks

In Eunice, when it's intended that an item be dependent on another, the first item is placed above the second in a stack. When items are intended to be independent of each other, they can be placed in the same level.

The terminology "stack" is used, as having uni-directional dependencies (i.e. in one direction), means dependent items are placed on top of their dependencies. The lower an item is in a stack, the more dependent items its likely to have. Where an item is in the stack, has implications for concerns such as design, risk management and independent working.

Diagrams of uni-directional, bi-directional, stack, independent, direct and indirect dependencies

Eunice also identifies when there is a indirect bi-directional/circular dependency (see diagram).

All but the simplest of systems will require multiple stacks (see scopes / groups). Eunice is designed to be non-prescriptive so problem/domain specific stacks can develop naturally and collaboratively. Stacks can also be used to define technology/implementation based architectures (e.g. stacks levels used as layers).

For all dependencies to be uni-directional, conceptual models may need refining and reorganizing, so that concerns are expressed more independently. Some problems may also require functionality lower in the stack to support plug-ins, that can be implemented higher up in the stack. For example, by applying the dependency inversion principle from SOLID.

In some programming languages there are implied stacks, such as the order of functions in a file, or the order of files in a project.

scopes / groups

Stacks are defined in Eunice with different sized scopes and across boundaries, from individual functions, classes and files; to multiple, large codebases in different languages, frameworks and runtimes.

Eunice uses nested groups of items, each group can have an identifier and its own stack. When Eunice measures whether dependencies match the intended structure, the results for nested groups are summarized (see dependencies).

Diagrams of how dependencies cross the boundaries of different scopes and groups

Programming languages usually include ways of grouping code, such as the directories in a file system, namespaces, classes and closures/nested functions. Groups such as these can be inferred and automatically represented in Eunice. Multiple repositories, packages, services and systems can also be analysed separately and aggregated into a single diagram.

When identifying scopes and grouping code together, its beneficial to consider the dependencies as relationships, and the concepts of cohesion and coupling.

In Eunice, hierarchical structure and unidirectional dependencies come together to encourage less coupling in inter-group dependencies, replacing them with intra-group dependencies and more cohesion.

The following diagram shows an example of how these concepts manifest in Eunice. In the diagram the 4 items and 3 dependencies stay the same, but re-structuring the groups simplifies the relationships.

Diagram of how coupling is lower and cohesion is higher when dependencies are in uni-directional hierarchies

dependencies

arrows

Instead of showing dependencies as lines between items, each dependency is counted into the following categories:

matches stack
green down arrow
does not match stack
red up arrow
is not independent
red horizontal arrow

Stacks are explained in the structure section.

Selecting an arrow will list the dependencies counted in it (except arrows inside items which will open the item).

counts

Dependency counts appear for both sides of the dependency, the dependent item and the item depended on. When there are multiple counts a summary of all the counts is shown at the bottom.

upper depends on lower
Diagram of a stack where the upper item depends upon the lower item
lower depends on upper
Diagram of a stack where the lower item depends upon the upper item
interdependent (stacked)
Diagram of a stack where the upper and lower items depend on each other
independent
Diagram of two independent items
first depends
on second
Diagram of a level where the first item depends on the second
interdependent
(not stacked)
Diagram of a level where the first and second items depend on each other

Dependencies within an item are also summarized and shown inside the item box, below the identifier text.

parent
depends on
item
Diagram of a parent dependent on one of its child items
item
depends on
parent
Diagram of a parent where one of its child items depends on the parent
first item
depends on
second item
(not stacked)
Diagram of a parent where one its child items depends on another child item in the same level

Items and sub-items can also be opened. Selecting an item will show its child items and breadcrumb links for where it is in the hierarchy.

An opened item's outer dependencies are shown around the outside of its border.

If there are multiple child items a summary of their dependencies is shown in the bottom of the opened item's border.

Eunice showing breadcrumb links and contents of an opened item containing a stack of child items
Eunice showing parent outer dependencies
Eunice showing parent outer dependencies

advanced

For information on how Eunice uses YAML, is implemented and can be extended, see the advanced page.