structurizr / java

Structurizr for Java
https://docs.structurizr.com/java
Apache License 2.0
1.01k stars 289 forks source link

No common interface to create element relationships #72

Closed beatw closed 6 years ago

beatw commented 6 years ago

It is not possible to write code that creates relationships for elements of different types because the abstract class StaticStructureElement is not public. The alternative to make StaticStructureElement public would be an interface that contains the public "uses" methods. There is also no uses method with a more common destination argument, for example of type StaticStructureElement...

simonbrowndotje commented 6 years ago

What is it that you're trying to do?

beatw commented 6 years ago

I'm trying to do the following: in our company we have an architecture metamodel with domains, applications, functional components and technical (deployable) components. As we evaluate structurizr to describe our current architecture but also for the ongoing changes I tried to map parts of the architecture in structurizr workspaces. The idea I have is to model the existing architecture using Java classes (one class for each domain, application, component ...). Maybe we can even generate some or parts of them from existing sources... The advantage of this approach is that I can use all the benefits of the IDE (code completion, source code management e.g. one file per component, ...). I create a "single instance model" of all this classes, so I get an object model of the whole architecture (of course lazy so that I have also instances the I need). I can then apply changes in the form of feature classes (add new components, relationships to the model),nicely tagged as "NEW". I'm now mapping the parts of my architecture model into a structurizr c4model to create the diagrams of the part of the architecture model I'm interested in. I have different mappings, as for some aspects it is better to have our "application" as software system whereas for other aspects it's better to have for example the functional components as software systems. I was quite fast trying out my idea, but when I started mapping the relationships from my model into the C4model I encountered the problem I described above. I solved it at the moment by adding the following methode to StaticStructureElement and make the class public.

public Relationship uses(StaticStructureElement destination, String description, String technology, InteractionStyle interactionStyle) { return getModel().addRelationship(this, destination, description, technology, interactionStyle); }

beatw commented 6 years ago

For the same reason I would appreciate if the Taggable Class would be a public Interface.

simonbrowndotje commented 6 years ago

I've just pushed some changes to support this.

beatw commented 6 years ago

I still don't see how I can create a general relationship between to elements of type StaticStructureElement... Sonething like: public Relationship uses(StaticStructureElement destination, String description, String technology, InteractionStyle interactionStyle) { return getModel().addRelationship(this, destination, description, technology, interactionStyle); }

simonbrowndotje commented 6 years ago

Like this? https://github.com/structurizr/java/blob/master/structurizr-core/src/com/structurizr/model/StaticStructureElement.java#L163

beatw commented 6 years ago

Yes, perfect, if the class StaticStructureElement would be public...

simonbrowndotje commented 6 years ago

I also made it public too. These changes haven't yet been pushed out to Maven Central, that will happen with the 1.0.0-RC5 release, which should happen in the next couple of weeks.

beatw commented 6 years ago

Perfect thanks! Would you mind to make Taggable public as well or provide access to its methods with a public interface?

simonbrowndotje commented 6 years ago

Element and Relationship are the direct subclasses of Taggable (which is really just an internal helper class I created to remove duplicate code) ... are these not sufficient?

beatw commented 6 years ago

As I map a complete model (part of a bigger model) to the workspace C4 model I need to the Transfer the tags. There for it would be nice to transfer the tags from Taggable to Taggable: protected void transferTags(ch.mobi.model.Taggable aTaggableElement, com.structurizr.model.Taggable aTaggableC4Element) { for(String tag: aTaggableElement.getTags()) { aTaggableC4Element.addTags(tag); } }
But I can code around it, if you see a reason to hide your Taggable interface...

simonbrowndotje commented 6 years ago

Yes, I'd rather keep the Taggable class hidden ... it's just an internal implementation detail.