• No se han encontrado resultados

40 Would you code it that way?

It’s a common misconception that software architecture diagrams

It’s a common misconception that software architecture diagrams need to be stuck in need to be stuck in the clouds,the clouds, showing high-level concepts and abstractions that present the logical rather than the physical. showing high-level concepts and abstractions that present the logical rather than the physical. But it doesn’t have to be this way and bringing them back down to earth often makes diagrams But it doesn’t have to be this way and bringing them back down to earth often makes diagrams easier to explain and understand. It can also make diagrams easier to draw too.

easier to explain and understand. It can also make diagrams easier to draw too. T

To illustrate why thinking about the implementation can help the o illustrate why thinking about the implementation can help the diagramming process, here arediagramming process, here are a couple of scenarios that I regularly hear in my training classes.

a couple of scenarios that I regularly hear in my training classes.

Shared components

Shared components

Imagine that you’re designing a 3-tier software system that makes use of a web server, an Imagine that you’re designing a 3-tier software system that makes use of a web server, an application server and a database. While thinking about the high-level components that reside application server and a database. While thinking about the high-level components that reside in each of these containers, it’s not uncommon to hear a conversation like this:

in each of these containers, it’s not uncommon to hear a conversation like this:

••   Attendee  Attendee: “Should we draw the logging component outside of the web server and the: “Should we draw the logging component outside of the web server and the application server, since it’s used by both?”

application server, since it’s used by both?”

•• MeMe: “Would you code it that way? Will the logging component be running outside of both: “Would you code it that way? Will the logging component be running outside of both the web server and application server? For example, will it really be a separate standalone the web server and application server? For example, will it really be a separate standalone process?”

process?”

••   Attendee  Attendee: “Well … no, it would probably be a shared component in a [JAR file|DLL|etc]: “Well … no, it would probably be a shared component in a [JAR file|DLL|etc] that we would deploy to both servers.”

that we would deploy to both servers.”

•• MeMe: “Great, then let’s draw it like that too. Include the logging component inside of each: “Great, then let’s draw it like that too. Include the logging component inside of each server and label it as a shared component with an annotation, stereotype or symbol.” server and label it as a shared component with an annotation, stereotype or symbol.” If you’re going to implement something like a

If you’re going to implement something like a shared logging component that will be shared logging component that will be deployed todeployed to a number of different servers, make sure that your diagram reflects this rather than potentially a number of different servers, make sure that your diagram reflects this rather than potentially confusing people by including something that might be mistaken for a separate centralised confusing people by including something that might be mistaken for a separate centralised logging server. If in doubt, always ask yourself how you would code it.

logging server. If in doubt, always ask yourself how you would code it.

Layering strategies

Layering strategies

Imagine you’re designing a web application that is internally split up into a UI layer, a services Imagine you’re designing a web application that is internally split up into a UI layer, a services layer and a data access layer.

layer and a data access layer.

••   Attendee  Attendee: “Should we show that all communication to the database from the UI goes: “Should we show that all communication to the database from the UI goes through the services layer?”

through the services layer?”

Would you code it that way?

Would you code it that way? 121121

••   Attendee  Attendee: “We were thinking of perhaps adopting the: “We were thinking of perhaps adopting the CQRS¹ CQRS¹ pattern, so the UI could pattern, so the UI could bypass the services layer and use the data access layer directly.”

bypass the services layer and use the data access layer directly.”

•• MeMe: “In that case, draw the : “In that case, draw the diagram as you’ve just explained, with lines from the Udiagram as you’ve just explained, with lines from the UI to bothI to both the services

the services and data access and data access layers. Annotate the lines to layers. Annotate the lines to indicate the intent and rationale.indicate the intent and rationale.”” Again, the simple way to answer this type of question is to understand how you would code it. Again, the simple way to answer this type of question is to understand how you would code it.

Diagrams should reflect reality

Diagrams should reflect reality

If you’re drawing diagrams to retrospectively communicate a software system then the question If you’re drawing diagrams to retrospectively communicate a software system then the question becomes “is that

becomes “is that how  how  we coded it?”. The principle is the same though. Diagrams should present we coded it?”. The principle is the same though. Diagrams should present abstractions that reflect reality rather than provide conceptual representations that don’t exist. abstractions that reflect reality rather than provide conceptual representations that don’t exist. Y

You should be able to ou should be able to see how the diagram see how the diagram elements are reflected in the elements are reflected in the codebase and vice versa.codebase and vice versa. If you can understand how you would code it, you can understand how to visualise it.

If you can understand how you would code it, you can understand how to visualise it. ¹¹http://martinfowler.com/bliki/CQRS.htmlhttp://martinfowler.com/bliki/CQRS.html

41 Software architecture vs code

41 Software architecture vs code

Although many software teams find it tricky to

Although many software teams find it tricky to  visualise the software architecture of their visualise the software architecture of their

software systems

software systems, let’s assume that this , let’s assume that this isn’t the case and that you’re isn’t the case and that you’re sketching some ideas relatedsketching some ideas related to the software architecture for a new system you’ve been tasked to build. An important aspect to the software architecture for a new system you’ve been tasked to build. An important aspect of 

of  just enough software architecture just enough software architecture is to understand how the significant elements of a software is to understand how the significant elements of a software system fit

system fit togethertogether..

Responsibility-driven design and decomposition into

Responsibility-driven design and decomposition into

components

components

For me, this means going down to the level of components, services or modules that each have For me, this means going down to the level of components, services or modules that each have a specific set of responsibilities. It’s worth stressing this isn’t about understanding low-level a specific set of responsibilities. It’s worth stressing this isn’t about understanding low-level implementation details, it’s about performing an initial level of decomposition. The Wikipedia implementation details, it’s about performing an initial level of decomposition. The Wikipedia page for

page for Component-based development¹ Component-based development¹ has a good summary and a “component” might be has a good summary and a “component” might be something like a risk calculator, audit logger, report generator, data importer, etc. The simplest something like a risk calculator, audit logger, report generator, data importer, etc. The simplest way to think about a component is that it’s a set of related behaviours behind an interface, way to think about a component is that it’s a set of related behaviours behind an interface, which may be implemented using one or more collaborating classes (assuming an OO language, which may be implemented using one or more collaborating classes (assuming an OO language, of course). Good components share a number of characteristics with good classes. They should of course). Good components share a number of characteristics with good classes. They should have high cohesion, low coupling, a well-defined public interface, good encapsulation, etc. have high cohesion, low coupling, a well-defined public interface, good encapsulation, etc. There are a number of benefits to thinking about a software system in terms of components, There are a number of benefits to thinking about a software system in terms of components, but essentially it allows us to think and talk about the software as a small number of high-level but essentially it allows us to think and talk about the software as a small number of high-level abstractions rather than the hundreds and thousands of individual classes that make up most abstractions rather than the hundreds and thousands of individual classes that make up most enterprise systems. The photo below shows a typical component diagram produced during the enterprise systems. The photo below shows a typical component diagram produced during the training classes we run. Groups are asked to design a simple

training classes we run. Groups are asked to design a simple financial risk system financial risk system that needs to that needs to pull in some data, perform some calculations and generate an Excel report as the output.

pull in some data, perform some calculations and generate an Excel report as the output. ¹¹http://en.wikipedia.org/wiki/Component-based_software_engineeringhttp://en.wikipedia.org/wiki/Component-based_software_engineering

Software architecture vs code

Software architecture vs code 123123

We often think in terms of components We often think in terms of components This

This sketsketchch incluincludes tdes thehe major major compocomponentnents yous you woulwouldd expeexpect to ct to seesee for a for a systesystemm that that is impois importingrting data, performing risk calculations and generating a report. These components provide us with data, performing risk calculations and generating a report. These components provide us with a framework for partitioning the behaviour within the boundary of our system and it should a framework for partitioning the behaviour within the boundary of our system and it should be relatively easy to trace the major use cases/user stories across them. This is a really useful be relatively easy to trace the major use cases/user stories across them. This is a really useful starting point for the software development process and can help to create a shared vision that starting point for the software development process and can help to create a shared vision that the team can work towards.

the team can work towards.

But it’s also very dangerous at the same time. Without technology choices (or options), this But it’s also very dangerous at the same time. Without technology choices (or options), this diagram looks like the sort of thing an ivory tower architect might produce and it can seem very diagram looks like the sort of thing an ivory tower architect might produce and it can seem very “conceptual” (or “fluffy”, depending on your point of view) for many people with a technical “conceptual” (or “fluffy”, depending on your point of view) for many people with a technical background.

background.

We talk about components but write classes

We talk about components but write classes

People generally understand the benefit of thinking about software as a small number of high- People generally understand the benefit of thinking about software as a small number of high- level building blocks. After all, it’s a great way to partition responsibilities across a software level building blocks. After all, it’s a great way to partition responsibilities across a software system and you’ll often hear people talking in terms of components when they’re having system and you’ll often hear people talking in terms of components when they’re having architecture discussions. This is what

architecture discussions. This is what component-based  component-based developmentdevelopment²² is all about and although is all about and although many people

many people talk  talk  about their software systems in terms of components, that structure isn’t about their software systems in terms of components, that structure isn’t usually reflected in the code. This is one of the reasons why there is a disconnect between usually reflected in the code. This is one of the reasons why there is a disconnect between software architecture and coding as disciplines - the architecture diagrams on the wall say one software architecture and coding as disciplines - the architecture diagrams on the wall say one thing, but the code says another.

thing, but the code says another.

When you open up a codebase, it will often reflect some other structure due to the organisation When you open up a codebase, it will often reflect some other structure due to the organisation of the code. The mapping between the architectural view of a software system and the code are of the code. The mapping between the architectural view of a software system and the code are often very different. This is sometimes why you’ll see people ignore architecture diagrams (or often very different. This is sometimes why you’ll see people ignore architecture diagrams (or documentation) and say “the code is the only single point of truth”. George Fairbanks calls this documentation) and say “the code is the only single point of truth”. George Fairbanks calls this

Software architecture vs code 124 the “Model-code gap” in his book called  Just Enough Software Architecture³. The organisation of the codebase can really help or hinder architectural understanding.

Packaging code by layer

Many software teams structure their code by layer. In other words, if you open up a codebase, you’ll see a package for domain classes, one for UI stuff, one for “business services”, one for data access, another for integration points and so on. I’m using the Java terminology of a “package” here, but the same is applicable to namespaces in C#, etc.

The reason for this is very simple. We know that architectural layering is generally “a good thing” and many of the tutorials out there teach this packaging style as a way to structure code. If you do a Google search for tutorials related to Spring or ASP.NET MVC, for example, you’ll see this in the sample code. I spent most of my career building software systems in Java and I too used the same packaging approach for the majority of the projects that I worked on.

Although there’s nothing particularly wrong with packaging code in this way, this code structure never quite reflects the abstractions that we think about when we view the system from an architecture perspective. If you’re using an OO programming language, do you talk about “objects” when you’re having architecture discussions? In my experience, the answer is no. I typically hear people referring to concepts like components and services instead. The result is that a “component” on an architecture diagram is actually implemented by a combination of  classes across a number of different layers. For example, you may find part  of the component in a “services” package and the rest of the component inside the “data access” package.

Software architecture vs code 125

Packaging by layer

In order to make this possible, the code in the lower layers (e.g. that “data access” package) often has public visibility, which means that it can be called directly from any other layer in the architecture too.

Packaging by feature

Packaging by layer isn’t the only answer though and Mark Needham has a great blog post called Coding: Packaging by vertical slice⁴ that talks about another approach to code organisation based upon vertical slices of functionality. A  Google search for “package by feature vs package by layer”⁵ will throw up lots of other discussions on the same topic.

⁴http://www.markhneedham.com/blog/2012/02/20/coding-packaging-by-vertical-slice/

Software architecture vs code 126

Packaging by component

Organising a codebase by layer makes it easy to see the overall structure of the software but there are trade-offs. For example, you need to delve inside multiple layers (e.g. packages, namespaces, etc) in order to make a change to a feature or user story. Also, many codebases end up looking eerily similar given the fairly standard approach to layering within enterprise systems.

In Screaming Architecture⁶, Uncle Bob Martin says that if you’re looking at a codebase, it should scream something about the business domain. Organising your code by feature rather than by layer gives you this, but again there are trade-offs. A slight variation I like is organising code explicitly by component. For example, if you take a look at the je.techtribes.component.tweet package on GitHub⁷, you’ll see that it looks something like this.

Packaging by component

This is similar to packaging by feature, but it’s more akin to the “micro services” that Mark Needham talks about in  his blog post⁸. Each sub-package of  je.techtribes.component⁹ houses a separate component, complete with it’s own internal  layering and configuration. As far as possible, all of the internals are package scoped. You could potentially pull each component out and put it in it’s own project or source code repository to be versioned separately. This approach will likely seem familiar to you if you’re building something that has a very explicit

⁶http://blog.8thlight.com/uncle-bob/2011/09/30/Screaming-Architecture.html

⁷https://github.com/techtribesje/techtribesje/tree/master/techtribes-core/src/je/techtribes/component/tweet

⁸http://www.markhneedham.com/blog/2012/02/20/coding-packaging-by-vertical-slice/

Software architecture vs code 127 loosely coupled architecture such as a distributed messaging system made up of loosely coupled components.

I’m fairly confident that most people are still building something more monolithic in nature though, despite thinking about their system in terms of components. I’ve certainly packaged

 parts  of monolithic codebases using a similar approach in the past but it’s tended to be fairly ad hoc. Let’s be honest, organising code into packages isn’t something that gets a lot of brain- time, particularly given the refactoring tools that we have at our disposal. Organising code by

Documento similar