DZone
Thanks for visiting DZone today,
Edit Profile
  • Manage Email Subscriptions
  • How to Post to DZone
  • Article Submission Guidelines
Sign Out View Profile
  • Post an Article
  • Manage My Drafts
Over 2 million developers have joined DZone.
Log In / Join
Refcards Trend Reports
Events Video Library
Refcards
Trend Reports

Events

View Events Video Library

Zones

Culture and Methodologies Agile Career Development Methodologies Team Management
Data Engineering AI/ML Big Data Data Databases IoT
Software Design and Architecture Cloud Architecture Containers Integration Microservices Performance Security
Coding Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
Culture and Methodologies
Agile Career Development Methodologies Team Management
Data Engineering
AI/ML Big Data Data Databases IoT
Software Design and Architecture
Cloud Architecture Containers Integration Microservices Performance Security
Coding
Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance
Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks

Curious about the future of data-driven systems? Join our Data Engineering roundtable and learn how to build scalable data platforms.

Data Engineering: The industry has come a long way from organizing unstructured data to adopting today's modern data pipelines. See how.

Threat Detection: Learn core practices for managing security risks and vulnerabilities in your organization — don't regret those threats!

Managing API integrations: Assess your use case and needs — plus learn patterns for the design, build, and maintenance of your integrations.

Avatar

Simon Brown

Hands-on Software Architect, Trainer, Coach and Consultant at Coding the Architecture

Trinity, Jersey, GB

Joined Nov 2011

About

Simon lives in Jersey (Channel Islands) and works as an independent consultant, specialising in software architecture, technical leadership and the balance with agility. Simon regularly speaks at international software development conferences and provides consulting/training to software teams at organisations across Europe, ranging from small startups through to global blue chip companies. He is the founder of "Coding the Architecture" (a website about pragmatic, hands-on software architecture) and the author of "Software Architecture for Developers" (an e-book that is being published incrementally through Leanpub). He still likes to write code too, primarily in .NET and Java.

Stats

Reputation: 277
Pageviews: 195.6K
Articles: 11
Comments: 12
  • Articles
  • Comments

Articles

article thumbnail
Using PlantUML and Structurizr Together
Creating a PlantUML exporter for Structurizr allows you to create a model of your software system and have the PlantUML diagrams be consistent with that model.
December 13, 2016
· 8,840 Views · 2 Likes
article thumbnail
Structurizr for .Net
Create detailed architecture models by writing Java or C# code with a web-based software architecture tool called Structurizr.
March 15, 2016
· 4,703 Views · 1 Like
article thumbnail
Diagramming Microservices With the C4 Model
Learn how to diagram a microservices architecture with the C4 model with these tips.
September 1, 2015
· 15,143 Views · 4 Likes
article thumbnail
The Art of Visualising Software Architecture
Simon Brown talks about the basis for his new book on software architectures and the difficulty in visualizing architectural models.
August 31, 2015
· 4,109 Views · 3 Likes
article thumbnail
Diff'ing Software Architecture Diagrams
robert annett wrote a post titled diagrams for system evolution where he describes a simple approach to showing how to visually describe changes to a software architecture. in essence, in order to show how a system is to change, he'll draw different versions of the same diagram and use colour-coding to highlight the elements/relationships that will be added, removed or modified. i've typically used a similar approach for describing as-is and to-be architectures in the past too. it's a technique that works well. although you can version control diagrams, it's still tricky to diff them using a tool. one solution that addresses this problem is to not create diagrams, but instead create a textual description of your software architecture model that is then subsequently rendered with some tooling. you could do this with an architecture description language (such as darwin ) although i would much rather use my regular programming language instead. creating a software architecture model as code this is exactly what structurizr is designed to do. i've recreated robert's diagrams with structurizr as follows. and since the diagrams were created by a model described as java code , that description can be diff'ed using your regular toolchain. code provides opportunities this perhaps isn't as obvious as robert's visual approach, and i would likely still highlight the actual differences on diagrams using notation as robert did too. creating a textual description of a software architecture model does provide some interesting opportunities though.
June 19, 2015
· 1,008 Views
article thumbnail
Package by Component and Architecturally-aligned Testing
i've seen and had lots of discussion about "package by layer" vs "package by feature" over the past couple of weeks. they both have their benefits but there's a hybrid approach i now use that i call "package by component". to recap... package by layer let's assume that we're building a web application based upon the web-mvc pattern. packaging code by layer is typically the default approach because, after all, that's what the books, tutorials and framework samples tell us to do. here we're organising code by grouping things of the same type. there's one top-level package for controllers, one for services (e.g. "business logic") and one for data access. layers are the primary organisation mechanism for the code. terms such as "separation of concerns" are thrown around to justify this approach and generally layered architectures are thought of as a "good thing". need to switch out the data access mechanism? no problem, everything is in one place. each layer can also be tested in isolation to the others around it, using appropriate mocking techniques, etc. the problem with layered architectures is that they often turn into a big ball of mud because, in java anyway, you need to mark your classes as public for much of this to work. package by feature instead of organising code by horizontal slice, package by feature seeks to do the opposite by organising code by vertical slice. now everything related to a single feature (or feature set) resides in a single place. you can still have a layered architecture, but the layers reside inside the feature packages. in other words, layering is the secondary organisation mechanism. the often cited benefit is that it's "easier to navigate the codebase when you want to make a change to a feature", but this is a minor thing given the power of modern ides. what you can do now though is hide feature specific classes and keep them out of sight from the rest of the codebase. for example, if you need any feature specific view models, you can create these as package-protected classes. the big question though is what happens when that new feature set c needs to access data from features a and b? again, in java, you'll need to start making classes publicly accessible from outside of the packages and the big ball of mud will again emerge. package by layer and package by feature both have their advantages and disadvantages. to quote jason gorman from schools of package architecture - an illustration , which was written seven years ago. to round off, then, i would urge you to be mindful of leaning to far towards either school of package architecture. don't just mindlessly put socks in the sock draw and pants in the pants draw, but don't be 100% driven by package coupling and cohesion to make those decisions, either. the real skill is finding the right balance, and creating packages that make stuff easier to find but are as cohesive and loosely coupled as you can make them at the same time. package by component this is a hybrid approach with increased modularity and an architecturally-evident coding style as the primary goals. the basic premise here is that i want my codebase to be made up of a number of coarse-grained components, with some sort of presentation layer (web ui, desktop ui, api, standalone app, etc) built on top. a "component" in this sense is a combination of the business and data access logic related to a specific thing (e.g. domain concept, bounded context, etc). as i've described before , i give these components a public interface and package-protected implementation details, which includes the data access code. if that new feature set c needs to access data related to a and b, it is forced to go through the public interface of components a and b. no direct access to the data access layer is allowed, and you can enforce this if you use java's access modifiers properly. again, "architectural layering" is a secondary organisation mechanism. for this to work, you have to stop using the public keyword by default . this structure raises some interesting questions about testing, not least about how we mock-out the data access code to create quick-running "unit tests". architecturally-aligned testing the short answer is don't bother, unless you really need to. i've spoken about and written about this before, but architecture and testing are related. instead of the typical testing triangle (lots of "unit" tests, fewer slower running "integration" tests and even fewer slower ui tests), consider this. i'm trying to make a conscious effort to not use the term "unit testing" because everybody has a different view of how big a "unit" is. instead, i've adopted a strategy where some classes can and should be tested in isolation. this includes things like domain classes, utility classes, web controllers (with mocked components), etc. then there are some things that are easiest to test as components, through the public interface. if i have a component that stores data in a mysql database, i want to test everything from the public interface right back to the mysql database. these are typically called "integration tests", but again, this term means different things to different people. of course, treating the component as a black box is easier if i have control over everything it touches. if you have a component that is sending asynchronous messages or using an external, third-party service, you'll probably still need to consider adding dependency injection points (e.g. ports and adapters) to adequately test the component, but this is the exception not the rule. all of this still applies if you are building a microservices style of architecture. you'll probably have some low-level class tests, hopefully a bunch of service tests where you're testing your microservices though their public interface, and some system tests that run scenarios end-to-end. oh, and you can still write all of this in a test-first, tdd style if that's how you work. i'm using this strategy for some systems that i'm building and it seems to work really well. i have a relatively simple, clean and (to be honest) boring codebase with understandable dependencies, minimal test-induced design damage and a manageable quantity of test code. this strategy also bridges the model-code gap , where the resulting code actually reflects the architectural intent. in other words, we often draw "components" on a whiteboard when having architecture discussions, but those components are hard to find in the resulting codebase. packaging code by layer is a major reason why this mismatch between the diagram and the code exists. those of you who are familiar with my c4 model will probably have noticed the use of the terms "class" and "component". this is no coincidence. architecture and testing are more related than perhaps we've admitted in the past. p.s. i'll be speaking about this topic over the next few months at events across europe, the us and (hopefully) australia
April 4, 2015
· 8,929 Views
article thumbnail
Structurizr: System Context Diagram as Code
as i said in resolving the conflict between software architecture and code , my focus for this year is representing a software architecture model as code. in simple sketches for diagramming your software architecture , i showed an example system context diagram for my techtribes.je website. it's a simple diagram that shows techtribes.je in the middle, surrounded by the key types of users and system dependencies. it's your typical "big picture" view. this diagram was created using omnigraffle (think microsoft visio for mac os x) and it's exactly that - a static diagram that needs to be manually kept up to date. instead, wouldn't it be great if this diagram was based upon a model that we could better version control, collaborate on and visualize? if you're not sure what i mean by a "model", take a look at models, sketches and everything in between . this is basically what the aim of structurizr is. it's a way to describe a software architecture model as code, and then visualize it in a simple way. the structurizr java library is available on github and you can download a prebuilt binary . just as a warning, this is very much a work in progress and so don't be surprised if things change! here's some java code to recreate the techtribes.je system context diagram. package com.structurizr.example; import com.structurizr.io.json.jsonwriter; import com.structurizr.model.location; import com.structurizr.model.model; import com.structurizr.model.person; import com.structurizr.model.softwaresystem; import com.structurizr.view.systemcontextview; import com.structurizr.view.viewset; import java.io.stringwriter; /** * this is a model of the system context for the techtribes.je system, * the code for which can be found at https://github.com/techtribesje/techtribesje */ public class techtribessystemcontext { public static void main(string[] args) throws exception { // create a model and the software system we want to describe model model = new model("techtribes.je", "this is a model of the system context for the techtribes.je system, the code for which can be found at https://github.com/techtribesje/techtribesje"); softwaresystem techtribes = model.addsoftwaresystem(location.internal, "techtribes.je", "techtribes.je is the only way to keep up to date with the it, tech and digital sector in jersey and guernsey, channel islands"); // create the various types of people (roles) that use the software system person anonymoususer = model.addperson(location.external, "anonymous user", "anybody on the web."); anonymoususer.uses(techtribes, "view people, tribes (businesses, communities and interest groups), content, events, jobs, etc from the local tech, digital and it sector."); person authenticateduser = model.addperson(location.external, "aggregated user", "a user or business with content that is aggregated into the website."); authenticateduser.uses(techtribes, "manage user profile and tribe membership."); person adminuser = model.addperson(location.external, "administration user", "a system administration user."); adminuser.uses(techtribes, "add people, add tribes and manage tribe membership."); // create the various software systems that techtribes.je has a dependency on softwaresystem twitter = model.addsoftwaresystem(location.external, "twitter", "twitter.com"); techtribes.uses(twitter, "gets profile information and tweets from."); softwaresystem github = model.addsoftwaresystem(location.external, "github", "github.com"); techtribes.uses(github, "gets information about public code repositories from."); softwaresystem blogs = model.addsoftwaresystem(location.external, "blogs", "rss and atom feeds"); techtribes.uses(blogs, "gets content using rss and atom feeds from."); // now create the system context view based upon the model viewset viewset = new viewset(model); systemcontextview contextview = viewset.createcontextview(techtribes); contextview.addallsoftwaresystems(); contextview.addallpeople(); // and output the model and view to json (so that we can render it using structurizr.com) jsonwriter jsonwriter = new jsonwriter(true); stringwriter stringwriter = new stringwriter(); jsonwriter.write(viewset, stringwriter); system.out.println(stringwriter.tostring()); } } executing this code creates this json , which you can then copy and paste into the try it page of structurizr. the result (if you move the boxes around) is something like this. don't worry, there will eventually be an api for uploading software architecture models and the diagrams will get some styling, but it proves the concept. what we have then is an api that implements the various levels in my c4 software architecture model, with a simple browser-based rendering tool. hopefully that's a nice simple introduction of how to represent a software architecture model as code, and gives you a flavour for the sort of direction i'm taking it. having the software architecture as code provides some interesting opportunities that you don't get with static diagrams from visio, etc and the ability to keep the models up to date automatically by scanning the codebase is what i find particularly exciting. if you have any thoughts on this, please do drop me a note.
January 16, 2015
· 5,928 Views · 3 Likes
article thumbnail
Distributed Big Balls of Mud
if you want evidence that the software development industry is susceptible to fashion, just go and take a look at all of the hype around microservices. it's everywhere! for some people microservices is "the next big thing", whereas for others it's simply a lightweight evolution of the big soap service-oriented architectures that we saw 10 years ago "done right". i do like a lot of what the current microservice architectures are doing, but it's by no means a silver bullet. okay, i know that sounds obvious, but i think many people are jumping on them for the wrong reason. i often show this slide in my conference talks, and i've blogged about this before , but basically there are different ways to build software systems. on the one side we have traditional monolithic systems, where everything is bundled up inside a single deployable unit. this is probably where most of the industry is. caveats apply, but monoliths can be built quickly and are easy to deploy, but they provide limited agility because even tiny changes require a full redeployment. we also know that monoliths often end up looking like a big ball of mud because of the way that software often evolves over time. for example, many monolithic systems are built using a layered architecture, and it's relatively easy for layered architectures to be abused (e.g. skipping "around" a service to call the repository/data access layer directly). on the other side we have service-based architectures, where a software system is made up of many separately deployable services. again, caveats apply but, if done well, service-based architectures buy you a lot of flexibility and agility because each service can be developed, tested, deployed, scaled, upgraded and rewritten separately, especially if the services are decoupled via asynchronous messaging. the downside is increased complexity because your software system now has many more moving parts than a monolith. as robert says, the complexity is still there, you're just moving it somewhere else . there is, of course, a mid-ground here. we can build monolithic systems that are made up of in-process components, each of which has an explicit well-defined interface and set of responsibilities. this is old-school component-based design that talks about high cohesion and low coupling, but i usually sense some hesitation when i talk about it. and this seems odd to me. before i explain why, let me quote something from a blog post that i read earlier this morning about the rationale behind a team adopting a microservices approach. when we started building karma, we decided to split the project into two main parts: the backend api, and the frontend application. the backend is responsible for handling orders from the store, usage accounting, user management, device management and so forth, while the frontend offers a dashboard for users which accesses this api. along the way we noticed that if the whole backend api is monolithic it doesn't work very well because everything gets entangled. the blog post also mentions scaling, versioning and multiple languages/frameworks as other reasons to choose microservices. again, there are no silver bullets here, everything is a trade-off. anyway, "everything getting entangled" is not a reason to switch from monoliths to microservices. if you're building a monolithic system and it's turning into a big ball of mud, perhaps you should consider whether you're taking enough care of your software architecture. do you really understand what the core structural abstractions are in your software? are their interfaces and responsibilities clear too? if not, why do you think moving to a microservices architecture will help? sure, the physical separation of services will force you to not take some shortcuts, but you can achieve the same separation between components in a monolith. a little design thinking and an architecturally-evident coding style will help to achieve this without the baggage of going distributed. many of the teams i've spoken to are building monolithic systems and don't want to look at component-based design. the mid-ground seems to be a hard-sell. i ran a software architecture sketching workshop with a team earlier this year where we diagrammed one of their software systems. the diagram started as a strictly layered architecture (presentation, business services, data access) with all arrows pointing downwards and each layer only ever calling the layer directly beneath it. the code told a different story though and the eventual diagram didn't look so neat anymore. we discussed how adopting a package by component approach could fix some of these problems, but the response was, "meh, we like building software using layers". it seems as if teams are jumping on microservices because they're sexy, but the design thinking and decomposition strategy required to create a good microservices architecture are the same as those needed to create a well structured monolith. if teams find it hard to create a well structured monolith, i don't rate their chances of creating a well structured microservices architecture. as michael feathers recently said, " there's a bit of overhead involved in implementing each microservice. if they ever become as easy to create as classes, people will have a freer hand to create trouble - hulking monoliths at a different scale. ". i agree. a world of distributed big balls of mud worries me.
August 4, 2014
· 7,683 Views
article thumbnail
Diagramming Spring MVC Webapps
some diagrams for the spring petclinic application following on from my previous post ( software architecture as code ) where i demonstrated how to create a software architecture model as code, i decided to throw together a quick implementation of a spring component finder that could be used to (mostly) automatically create a model of a spring mvc web application. spring has a bunch of annotations (e.g. @controller, @component, @service and @repository) and these are often/can be used to signify the major building blocks of a web application. to illustrate this, i took the spring petclinic application and produced some diagrams for it. first is a context diagram. next up are the containers, which in this case are just a web server (e.g. apache tomcat) and a database (hsqldb by default). and finally we have a diagram showing the components that make up the web application. these, and their dependencies, were found by scanning the compiled version of the application (i cloned the project from github and ran the maven build). here is the code that i used to generate the model behind the diagrams. package com.structurizr.example; import com.fasterxml.jackson.databind.objectmapper; import com.fasterxml.jackson.databind.serializationfeature; import com.structurizr.componentfinder.componentfinder; import com.structurizr.componentfinder.springcomponentfinderstrategy; import com.structurizr.model.*; import com.structurizr.view.componentview; import com.structurizr.view.containerview; import com.structurizr.view.contextview; /** * this is a c4 representation of the spring petclinic sample app (https://github.com/spring-projects/spring-petclinic/). */ public class springpetclinic { public static void main(string[] args) throws exception { model model = new model(); // create the basic model (the stuff we can't get from the code) softwaresystem springpetclinic = model.addsoftwaresystem(location.internal, "spring petclinic", ""); person user = model.addperson(location.external, "user", ""); user.uses(springpetclinic, "uses"); container webapplication = springpetclinic.addcontainer("web application", "", "apache tomcat 7.x"); container relationaldatabase = springpetclinic.addcontainer("relational database", "", "hsqldb"); user.uses(webapplication, "uses"); webapplication.uses(relationaldatabase, "reads from and writes to"); // and now automatically find all spring @controller, @component, @service and @repository components componentfinder componentfinder = new componentfinder(webapplication, "org.springframework.samples.petclinic", new springcomponentfinderstrategy()); componentfinder.findcomponents(); // finally create some views contextview contextview = model.createcontextview(springpetclinic); contextview.addallsoftwaresystems(); contextview.addallpeople(); containerview containerview = model.createcontainerview(springpetclinic); containerview.addallpeople(); containerview.addallsoftwaresystems(); containerview.addallcontainers(); componentview componentview = model.createcomponentview(springpetclinic, webapplication); componentview.addallcomponents(); objectmapper objectmapper = new objectmapper(); objectmapper.enable(serializationfeature.indent_output); string modelasjson = objectmapper.writevalueasstring(model); system.out.println(modelasjson); } } the resulting json representing the model was then copy-pasted across into my simple (and very much in progress) diagramming tool . admittedly the diagrams are lacking on some details (i.e. component responsibilities and arrow annotations, although those can be fixed), but this approach proves you can expend very little effort to get something that is relatively useful. as i've said before, it's all about getting the abstractions right.
July 1, 2014
· 8,072 Views
article thumbnail
Software Architecture as Code
if you've been following the blog, you will have seen a couple of posts recently about the alignment of software architecture and code. software architecture vs code talks about the typical gap between how we think about the software architecture vs the code that we write, while an architecturally-evident coding style shows an example of how to ensure that the code does reflect those architectural concepts. the basic summary of the story so far is that things get much easier to understand if your architectural ideas map simply and explicitly into the code. regular readers will also know that i'm a big fan of using diagrams to visualise and communicate the architecture of a software system, and this "big picture" view of the world is often hard to see from the thousands of lines of code that make up our software systems. one of the things that i teach people during my sketching workshops is how to sketch out a software system using a small number of simple diagrams, each at very separate levels of abstraction. this is based upon my c4 model , which you can find an introduction to at simple sketches for diagramming your software architecture . the feedback from people using this model has been great, and many have a follow-up question of "what tooling would you recommend?". my answer has typically been "visio or omnigraffle", but it's obvious that there's an opportunity here. representing the software architecture model in code i've had a lot of different ideas over the past few months for how to create, what is essentially, a lightweight modelling tool and for some reason, all of these ideas came together last week while i was at the goto amsterdam conference. i'm not sure why, but i had a number of conversations that inspired me in different ways, so i skipped one of the talks to throw some code together and test out some ideas. this is basically what i came up with... model model = new model(); softwaresystem techtribes = model.addsoftwaresystem(location.internal, "techtribes.je", "techtribes.je is the only way to keep up to date with the it, tech and digital sector in jersey and guernsey, channel islands"); person anonymoususer = model.addperson(location.external, "anonymous user", "anybody on the web."); person aggregateduser = model.addperson(location.external, "aggregated user", "a user or business with content that is aggregated into the website."); person adminuser = model.addperson(location.external, "administration user", "a system administration user."); anonymoususer.uses(techtribes, "view people, tribes (businesses, communities and interest groups), content, events, jobs, etc from the local tech, digital and it sector."); aggregateduser.uses(techtribes, "manage user profile and tribe membership."); adminuser.uses(techtribes, "add people, add tribes and manage tribe membership."); softwaresystem twitter = model.addsoftwaresystem(location.external, "twitter", "twitter.com"); techtribes.uses(twitter, "gets profile information and tweets from."); softwaresystem github = model.addsoftwaresystem(location.external, "github", "github.com"); techtribes.uses(github, "gets information about public code repositories from."); softwaresystem blogs = model.addsoftwaresystem(location.external, "blogs", "rss and atom feeds"); techtribes.uses(blogs, "gets content using rss and atom feeds from."); container webapplication = techtribes.addcontainer("web application", "allows users to view people, tribes, content, events, jobs, etc from the local tech, digital and it sector.", "apache tomcat 7.x"); container contentupdater = techtribes.addcontainer("content updater", "updates profiles, tweets, github repos and content on a scheduled basis.", "standalone java 7 application"); container relationaldatabase = techtribes.addcontainer("relational database", "stores people, tribes, tribe membership, talks, events, jobs, badges, github repos, etc.", "mysql 5.5.x"); container nosqlstore = techtribes.addcontainer("nosql data store", "stores content from rss/atom feeds (blog posts) and tweets.", "mongodb 2.2.x"); container filesystem = techtribes.addcontainer("file system", "stores search indexes.", null); anonymoususer.uses(webapplication, "view people, tribes (businesses, communities and interest groups), content, events, jobs, etc from the local tech, digital and it sector."); authenticateduser.uses(webapplication, "manage user profile and tribe membership."); adminuser.uses(webapplication, "add people, add tribes and manage tribe membership."); webapplication.uses(relationaldatabase, "reads from and writes data to"); webapplication.uses(nosqlstore, "reads from"); webapplication.uses(filesystem, "reads from"); contentupdater.uses(relationaldatabase, "reads from and writes data to"); contentupdater.uses(nosqlstore, "reads from and writes data to"); contentupdater.uses(filesystem, "writes to"); contentupdater.uses(twitter, "gets profile information and tweets from."); contentupdater.uses(github, "gets information about public code repositories from."); contentupdater.uses(blogs, "gets content using rss and atom feeds from."); it's a description of the context and container levels of my c4 model for the techtribes.je system. hopefully it doesn't need too much explanation if you're familiar with the model, although there are some ways in which the code can be made simpler and more fluent. since this is code though, we can easily constrain the model and version it. this approach works well for the high-level architectural concepts because there are very few of them, plus it's hard to extract this information from the code. but i don't want to start crafting up a large amount of code to describe the components that reside in each container, particularly as there are potentially lots of them and i'm unsure of the exact relationships between them. scanning the codebase for components if your code does reflect your architecture (i.e. you're using an architecturally-evident coding style), the obvious solution is to just scan the codebase for those components, and use those to automatically populate the model. how do we signify what a "component" is? in java, we can use annotations... package je.techtribes.component.tweet; import com.structurizr.annotation.component; ... @component(description = "provides access to tweets.") public interface tweetcomponent { /** * gets the most recent tweets by page number. */ list getrecenttweets(int page, int pagesize); ... } identifying those components is then a matter of scanning the source or the compiled bytecode. i've played around with this idea on and off for a few months, using a combination of java annotations along with annotation processors and libraries including scannotation, javassist and jdepend. the reflections library on google code makes this easy to do, and now i have simple java program that looks for my component annotation on classes in the classpath and automatically adds those to the model. as for the dependencies between components, again this is fairly straightforward to do with reflections. i have a bunch of other annotations too, for example to represent dependencies between a component and a container or software system, but the principle is still the same - the architecturally significant elements and their dependencies can mostly be embedded in the code. creating some views the model itself is useful, but ideally i want to look at that model from different angles, much like the diagrams that i teach people to draw when they attend my sketching workshop. after a little thought about what this means and what each view is constrained to show, i created a simple domain model to represent the context, container and component views... model model = ... softwaresystem techtribes = model.getsoftwaresystemwithname("techtribes.je"); container contentupdater = techtribes.getcontainerwithname("content updater"); // context view contextview contextview = model.createcontextview(techtribes); contextview.addallsoftwaresystems(); contextview.addallpeople(); // container view containerview containerview = model.createcontainerview(techtribes); containerview.addallsoftwaresystems(); containerview.addallpeople(); containerview.addallcontainers(); // component view for the content updater container componentview componentview = model.createcomponentview(techtribes, contentupdater); componentview.addallsoftwaresystems(); componentview.addallcontainers(); componentview.addallcomponents(); // let's exclude the logging component as it's used by everything componentview.remove(contentupdater.getcomponentwithname("loggingcomponent")); componentview.removeelementswithnorelationships(); again, this is all in code so it's quick to create, versionable and very customisable. exporting the model now that i have a model of my software system and a number of views that i'd like to see, i could do with drawing some pictures. i could create a diagramming tool in java that reads the model directly, but perhaps a better approach is to serialize the object model out to an external format so that other tools can use it. and that's what i did, courtesy of the jackson library . the resulting json file is over 600 lines long ( you can see it here ), but don't forget most of this has been generated automatically by java code scanning for components and their dependencies. visualising the views the last question is how to visualise the information contained in the model and there are a number of ways to do this. i'd really like somebody to build a google maps or prezi-style diagramming tool where you can pinch-zoom in and out to see different views of the model, but my ui skills leave something to be desired in that area. for the meantime, i've thrown together a simple diagramming tool using html 5, css and javascript that takes a json string and visualises the views contained within it. my vision here is to create a lightweight model visualisation tool rather than a visio clone where you have to draw everything yourself. i've deployed this app on pivotal web services and you can try it for yourself . you'll have to drag the boxes around to lay out the elements and it's not very pretty, but the concept works. the screenshot that follows shows the techtribes.je context diagram. thoughts? all of the c4 model java code is open source and sitting on github . this is only a few hours of work so far and there are no tests, so think of this as a prototype more than anything else at the moment. i really like the simplicity of capturing a software architecture model in code, and using an architecturally-evident coding style allows you to create large chunks of that model automatically. this also opens up the door to some other opportunities such automated build plugins, lightweight documentation tooling, etc. caveats apply with the applicability of this to all software systems, but i'm excited at the possibilities. thoughts?
June 25, 2014
· 8,921 Views
article thumbnail
An Architecturally-Evident Coding Style
okay, this is the separate blog post that i referred to in software architecture vs code . what exactly do we mean by an "architecturally-evident coding style"? i built a simple content aggregator for the local tech community here in jersey called techtribes.je , which is basically made up of a web server, a couple of databases and a standalone java application that is responsible for actually aggegrating the content displayed on the website. you can read a little more about the software architecture at techtribes.je - containers . the following diagram is a zoom-in of the standalone content updater application, showing how it's been decomposed. this diagram says that the content updater application is made up of a number of core components (which are shown on a separate diagram for brevity) and an additional four components - a scheduled content updater, a twitter connector, a github connector and a news feed connector. this diagram shows a really nice, simple architecture view of how my standalone content updater application has been decomposed into a small number of components. "component" is a hugely overloaded term in the software development industry, but essentially all i'm referring to is a collection of related behaviour sitting behind a nice clean interface. back to the "architecturally-evident coding style" and the basic premise is that the code should reflect the architecture. in other words, if i look at the code, i should be able to clearly identify each of the components that i've shown on the diagram. since the code for techtribes.je is open source and on github, you can go and take a look for yourself as to whether this is the case. and it is ... there's a je.techtribes.component package that contains sub-packages for each of the components shown on the diagram. from a technical perspective, each of these are simply spring beans with a public interface and a package-protected implementation. that's it; the code reflects the architecture as illustrated on the diagram. so what about those core components then? well, here's a diagram showing those. again, this diagram shows a nice simple decomposition of the core of my techtribes.je system into coarse-grained components. and again, browsing the source code will reveal the same one-to-one mapping between boxes on the diagram and packages in the code. this requires conscious effort to do but i like the simple and explicit nature of the relationship between the architecture and the code. when architecture and code don't match the interesting part of this story is that while i'd always viewed my system as a collection of "components", the code didn't actually look like that. to take an example, there's a tweet component on the core components diagram, which basically provides crud access to tweets in a mongodb database. the diagram suggests that it's a single black box component, but my initial implementation was very different. the following diagram illustrates why. my initial implementation of the tweet component looked like the picture on the left - i'd taken a "package by layer" approach and broken my tweet component down into a separate service and data access object. this is your stereotypical layered architecture that many (most?) books and tutorials present as a way to build (e.g.) web applications. it's also pretty much how i've built most software in the past too and i'm sure you've seen the same, especially in systems that use a dependency injection framework where we create a bunch of things in layers and wire them all together. layered architectures have a number of benefits but they aren't a silver bullet . this is a great example of where the code doesn't quite reflect the architecture - the tweet component is a single box on an architecture diagram but implemented as a collection of classes across a layered architecture when you look at the code. imagine having a large, complex codebase where the architecture diagrams tell a different story from the code. the easy way to fix this is to simply redraw the core components diagram to show that it's really a layered architecture made up of services collaborating with data access objects. the result is a much more complex diagram but it also feels like that diagram is starting to show too much detail. the other option is to change the code to match my architectural vision. and that's what i did. i reorganised the code to be packaged by component rather than packaged by layer. in essence, i merged the services and data access objects together into a single package so that i was left with a public interface and a package protected implementation. here's the tweet component on github . but what about... again, there's a clean simple mapping from the diagram into the code and the code cleanly reflects the architecture. it does raise a number of interesting questions though. why aren't you using a layered architecture? where did the tweetdao interface go? how do you mock out your dao implementation to do unit testing? what happens if i want to call the dao directly? what happens if you want to change the way that you store tweets? layers are now an implementation detail this is still a layered architecture, it's just that the layers are now a component implementation detail rather than being first-class architectural building blocks. and that's nice, because i can think about my components as being my architecturally significant structural elements and it's these building blocks that are defined in my dependency injection framework. something i often see in layered architectures is code bypassing a services layer to directly access a dao or repository. these sort of shortcuts are exactly why layered architectures often become corrupted and turn into big balls of mud. in my codebase, if any consumer wants access to tweets, they are forced to use the tweet component in its entirety because the dao is an internal implementation detail. and because i have layers inside my component, i can still switch out my tweet data storage from mongodb to something else. that change is still isolated. component testing vs unit testing ah, unit testing. bundling up my tweet service and dao into a single component makes the resulting tweet component harder to unit test because everything is package protected. sure, it's not impossible to provide a mock implementation of the mongodbtweetdao but i need to jump through some hoops. the other approach is to simply not do unit testing and instead test my tweet component through its public interface. dhh recently published a blog post called test-induced design damage and i agree with the overall message; perhaps we are breaking up our systems unnecessarily just in order to unit test them. there's very little to be gained from unit testing the various sub-parts of my tweet component in isolation, so in this case i've opted to do automated component testing instead where i test the component as a black-box through its component interface. mongodb is lightweight and fast, with the resulting component tests running acceptably quick for me, even on my ageing macbook air. i'm not saying that you should never unit test code in isolation, and indeed there are some situations where component testing isn't feasible. for example, if you're using asynchronous and/or third party services, you probably do want to ability to provide a mock implementation for unit testing. the point is that we shouldn't blindly create designs where everything can be mocked out and unit tested in isolation. food for thought the purpose of this blog post was to provide some more detail around how to ensure that code reflects architecture and to illustrate an approach to do this. i like the structure imposed by forcing my codebase to reflect the architecture. it requires some discipline and thinking about how to neatly carve-up the responsibilities across the codebase, but i think the effort is rewarded. it's also a nice stepping stone towards micro-services. my techtribes.je system is constructed from a number of in-process components that i treat as my architectural building blocks. the thinking behind creating a micro-services architecture is essentially the same, albeit the components (services) are running out-of-process. this isn't a silver bullet by any means, but i hope it's provided some food for thought around designing software and structuring a codebase with an architecturally-evident coding style.
June 9, 2014
· 5,273 Views

Comments

Coding the Documentation with Structurizr

May 22, 2017 · Grzegorz Ziemoński

It's a model of your software system that you're uploading rather than the source code itself, and you can choose how detailed that model is. The data is being stored encrypted, and there are commercial options for client-side encryption, on-premises data storage and an on-premises installation. For the SaaS version, in summary, you retain ownership of your uploaded content and provide Structurizr Limited the right to "publish" that content (based upon the security configured for the workspace, of course ... i.e. fully public, private, etc). Hope that helps.

F#: A day writing a Feedburner graph creator

Apr 13, 2015 · Alvin Ashcraft

Hi Martin,

Yes, that's exactly what I'm doing ... I'm using Structurizr to create a software architecture model, enrich it with what can be extracted from the code and then upload the resulting model to structurizr.com as a part of my build pipeline. This keeps the model and resulting diagrams nicely up to date.

I don't have any plans to perform any architectural validation (e.g. controllers using JDBC, etc) but it's certainly possible.

Cheers

Simon

Windows Azure Tools for Microsoft Visual Studio May 2009 CTP

Mar 02, 2015 · Vijaya Kadiyala

Will do and thanks Filipe, it's great to hear that you've found the C4 stuff useful. :-)

Structurizr: System Context Diagram as Code

Mar 02, 2015 · N A

Thanks Charles. Structurizr has been progressing rapidly since the start of the year and the API, diagram styling all now exist. Please do take a look and let me know what you think.

Cheers, Simon

Structurizr: System Context Diagram as Code

Mar 02, 2015 · N A

Thanks Charles. Structurizr has been progressing rapidly since the start of the year and the API, diagram styling all now exist. Please do take a look and let me know what you think.

Cheers, Simon

Structurizr: System Context Diagram as Code

Mar 02, 2015 · N A

Thanks Charles. Structurizr has been progressing rapidly since the start of the year and the API, diagram styling all now exist. Please do take a look and let me know what you think.

Cheers, Simon

Structurizr: System Context Diagram as Code

Mar 02, 2015 · N A

Thanks Charles. Structurizr has been progressing rapidly since the start of the year and the API, diagram styling all now exist. Please do take a look and let me know what you think.

Cheers, Simon

Convert IP To Geo Location and Address To Geo Location

Mar 02, 2015 · Naveen Kohli

Thanks Charles. Structurizr has been progressing rapidly since the start of the year and the API, diagram styling all now exist. Please do take a look and let me know what you think.

Cheers, Simon

Convert IP To Geo Location and Address To Geo Location

Mar 02, 2015 · Naveen Kohli

Thanks Charles. Structurizr has been progressing rapidly since the start of the year and the API, diagram styling all now exist. Please do take a look and let me know what you think.

Cheers, Simon

Convert IP To Geo Location and Address To Geo Location

Mar 02, 2015 · Naveen Kohli

Thanks Charles. Structurizr has been progressing rapidly since the start of the year and the API, diagram styling all now exist. Please do take a look and let me know what you think.

Cheers, Simon

Convert IP To Geo Location and Address To Geo Location

Mar 02, 2015 · Naveen Kohli

Thanks Charles. Structurizr has been progressing rapidly since the start of the year and the API, diagram styling all now exist. Please do take a look and let me know what you think.

Cheers, Simon

Logotypes Collection in PSD

Dec 02, 2014 · Peyman Dehbozorgi

Thanks Filipe ... those diagrams were created with OmniGraffle for the Mac, but they can be easily done with Visio too. My goal is to create some better tooling for this, and you can read about it at http://www.structurizr.com (it's a work in progress).

User has been successfully modified

Failed to modify user

ABOUT US

  • About DZone
  • Support and feedback
  • Community research
  • Sitemap

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

  • Article Submission Guidelines
  • Become a Contributor
  • Core Program
  • Visit the Writers' Zone

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 3343 Perimeter Hill Drive
  • Suite 100
  • Nashville, TN 37211
  • support@dzone.com

Let's be friends: