Sacrificial Architecture in Web Development
Published: 2020-08-17 11:01:51

What’s the ultimate goal of Agile methodologies? In my opinion, it could be distilled in the phrase: **_«Embrace Change»_**. While I understand the value of continuously adapting our code in order to develop the best software for our clients, there’s something that always bothers me as web developer. All the software architectures that I encountered during my career have one feature in common: **they are very hard to change**. Just try to change this!

![Complex Architecture](https://upload.wikimedia.org/wikipedia/commons/7/76/State_of_Wikibase%27s_frontend_architecture_at_2013-04-10.svg)
_Graph by [Danwe](https://commons.wikimedia.org/wiki/File:State_of_Wikibase%27s_frontend_architecture_at_2013-04-10.svg) / CC0_

So it seems that no kind of software architecture it’s really suited for Agile development.

Introducing Sacrificial Architecture
------------------------------------

Martin Fowler in one of his [posts](http://martinfowler.com/bliki/SacrificialArchitecture.html) introduced the concept of Sacrificial Architecture: a software architecture designed to build code that you can easily throw away. **Because the best code that you can write now, probably will not be suitable for your clients in a few years.**

I’m a frontend developer and I find that this kind of architecture is perfect for complex web application today. On the frontend, you need to change the UX and the look and feel of your application ASAP, according to your clients needs.

How to apply it?
----------------

Sacrificial Architecture is not a pattern or a well-defined architecture. So how can we apply it to modern web applications? **Obviously, there’s no right answer to this question**, but I have a couple of tips to share with you.

Modularity
----------

Modularity is a must-have for Sacrificial Architecture. You should divide your application in modules. The modules mustn’t know each other, in this way you could throw away a module and the application will continue to work. If modules need to share code, it needs to be put in a “shared” module.

![Our modular application](https://miro.medium.com/max/1400/1*t0lDIYju8_1kbo-ySKtWgQ.png)

But what happens if you need to share code between Module A and Module B? The first solution could be to put it in the “shared” module but you will find yourself in this kind of situation in no time…

![Our fat shared module…](https://miro.medium.com/max/1400/1*1iD755rg8bGAiyh83UnVBg.png)

If you start to put the code in the sharing module every-time you need it, the “shared” module will become a very “fat” module and then you will not be able to throw away any of your code. So in order to maintain your modules “disposable”, you need to accept code duplication. After all, as [Sandi Metz](https://medium.com/u/b49fae4639c2?source=post_page-----3926c0593fc8----------------------) says:

> duplication is far cheaper than the wrong abstraction.

Frameworks
----------

Modern Web Development is a jungle of frameworks. To apply the SA in the process of choosing the framework to develop your new JavaScript project, try to apply this pattern:

> Choose your framework as you will need to change it after six months

It may seem a little extreme, but if try to follow this rule you will use your framework better. Please consider the next AngularJS 1.X example:

```javascript
app.factory(‘getUsers’,\[‘$http’,function($http){  
 return $http.get(‘api/v1/users’);  
});app.controller(‘home’,\[  
 ‘$scope’,  
 ‘getUsers’,  
 function(  
     $scope,  
     getUsers){  
         getUsers().then(function(response){  
             $scope.users = response.data;  
         });  
}\]);
```

As you can see we created a _getUsers_ service that we use in the _home_ controller. **Note that we are bounded to Angular on the View level (the controller) and on the Business Logic level (the service)**. Let’s try with something different: let’s define our logic in a pure ECMAScript 6 module.

```javascript
export default function(){  
   return fetch(‘api/v1/users’).then(function (response) {  
       return response.json();  
   });  
};
```

And use it in the controller:

```javascript
import getUsers from ‘./getUsers’;app.controller(‘home’,\[  
   ‘$scope’,  
   function(  
       $scope){  
           getUsers().then(function(users){  
               $scope.users = users;  
           });  
}\]);
```

The code inside the controller is exactly the same, _but now our business logic is not depending on any framework_. In other words: it’s simpler for us to **throw away AngularJS** in favour of another framework. So your work is not done after you have chosen a framework, you also need to choose _what features_ of your framework you have to use **to keep the framework itself “sacrificial” all the time.**

![Meme](https://miro.medium.com/max/1280/1*DzZC6MtQf10DW9DLIXM8cw.jpeg)

Conclusions
-----------

This post is not meant to cover this topic entirely, and as I stated at the beginning of this post there’s no “right” guide to do a good Sacrificial Architecture: you just need to keep an open mind. And remember, quoting Martin Fowler…

> Sacrificial Architecture, sometimes it’s the fastest way to learn things

I talked about this same topic at [RuhrJS 2016](http://ruhrjs.de/) in July. You can see the video below

{% youtube Q2vqjQdw6jU %}