Julio Biason
5 years ago
4 changed files with 88 additions and 2 deletions
@ -0,0 +1,84 @@
|
||||
+++ |
||||
title = "Things I Learnt The Hard Way - Organize Your Code by Data/Type, Not Functionality" |
||||
date = 2019-07-15 |
||||
|
||||
[taxonomies] |
||||
tags = ["en-au", "books", "things i learnt", "project", "project organization"] |
||||
+++ |
||||
|
||||
A lot of projects assume that you'll put things with the same functionality in |
||||
the same place, no matter what data they deal with. This makes things harder |
||||
to break apart later. |
||||
|
||||
<!-- more --> |
||||
|
||||
Most projects keep organized by the functionality each component do. For |
||||
example, all the models are in the same place, all the functions that convert |
||||
one model into an internal structure/DTO are kept together, and so on. |
||||
Something like this: |
||||
|
||||
``` |
||||
. |
||||
+-- IncomingModels |
||||
| +-- DataTypeInterface |
||||
| +-- DataType1 |
||||
| +-- DataType2 |
||||
| +-- DataType3 |
||||
+-- Filters |
||||
| +-- FilterInterface |
||||
| +-- FilterValidDataType2 |
||||
+-- Processors |
||||
| +-- ProcessorInterface |
||||
| +-- ConvertDataType1ToDto1 |
||||
| +-- ConvertDataType2ToDto2 |
||||
+-- OutgoingModels |
||||
+-- DtoInterface |
||||
+-- Dto1 |
||||
+-- Dto2 |
||||
``` |
||||
|
||||
This is fine and works. But when you organize by data, it'll make a lot easier |
||||
to split your project in smaller projects -- 'cause, at some point, you may |
||||
want to do almost the same thing as you're doing right now, but with small |
||||
differences. |
||||
|
||||
``` |
||||
. |
||||
+-- Base |
||||
| +-- IncomingModels |
||||
| | +-- DataTypeInterface |
||||
| +-- Filters |
||||
| | +-- FilterInterface |
||||
| +-- Processors |
||||
| | +-- ProcessorInterface |
||||
| +-- OutgoingModels |
||||
| +-- DtoInterface |
||||
+-- Data1 |
||||
| +-- IncomingModels |
||||
| | +-- DataType1 |
||||
| +-- Processors |
||||
| | +-- ConvertDataType1ToDto1 |
||||
| +-- OutgoingModels |
||||
| +-- Dto1 |
||||
... |
||||
``` |
||||
|
||||
Now you can make a module that deals _only_ with Data1, another that works |
||||
only with Data2 and so on. And then you can break them into isolated modules. |
||||
|
||||
And then when you have another project that also have Data1 but also deals |
||||
with Data3, you can reuse most of the stuff in the Data1 module. |
||||
|
||||
And I do understand that this creates an explosion of directories/packages, |
||||
which may seem a bit unnecessary. |
||||
|
||||
Believe me, I also thought the idea of keeping things by functionality made |
||||
more sense. But in one project, I got a requirement to do almost the same |
||||
thing as I was doing before, but with a small change, which would require one |
||||
less step/transformation (in our example, you can think as the new requirement |
||||
as doing exactly what the Data1, Data2 and Data3 did, with their |
||||
transformations and such, but without the Data3 part). By breaking by their |
||||
types, I managed to create small modules for each one and the new project |
||||
would simply reference Data1 and Data2, but not Data3. |
||||
|
||||
{{ chapters(prev_chapter_link="/books/things-i-learnt/one-change-commit", prev_chapter_title="One Commit Per Change", next_chapter_link="/books/things-i-learnt/throw-away", next_chapter_title="Be Ready To Throw Your Code Away") }} |
Loading…
Reference in new issue