forked from ThinkR-open/engineering-shiny-book
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathplanning-ahead.Rmd
115 lines (71 loc) · 7.05 KB
/
planning-ahead.Rmd
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
# Planning Ahead {#planning}
## Working with a "long-term" mindset
> "Rome ne fut pas faite toute en un jour"
French proverb
### Prepare for success
// TODO
-> Planning is everything
-> Get ready for complexity
-> Think big, act small.
Understand the big picture, but implement one small feature at a time.
-> Future is now
### Applying the KISS principle
// TODO
> The KISS principle states that most systems work best if they are kept simple rather than made complicated; therefore, simplicity should be a key goal in design, and unnecessary complexity should be avoided.
`r right_link("KISS principle", "https://en.wikipedia.org/wiki/KISS_principle")`
Deeply rooted in the [Unix Philosophy](http://www.catb.org/~esr/writings/taoup/html/ch01s07.html), the KISS principle stands for "Keep It Simple, Stupid".
The story behind this principle is supposed to be that Kelly Johnson, lead engineer at the Lockheed Skunk Works, gave his workers a set of very common tools and said that the airplanes should be repairable with these tools, and these tools only.
The idea behind being, that the action of repairing the aircraft that come out of their factories should be possible to carry out by the average engineer.
KISS will:
-> Help you reason about the app in the long run, since it is
-> Hard to remove a feature once it's implemented
### Think long-term maintenance, now
// TODO
Maintenance, on the other hand, is something to think about from the beginning.
It includes being able to ensure that the application will work in the long run, and that new features can be easily implemented.
+ Working in the long run: separate the code containing the "business logic" (aka the data manipulation and the algorithms, which can work outside the context of the app) from the code building the application.
That way, you can write regression tests for these functions to ensure they are stable.
+ Implement new elements: as we are working with modules, it's easy to insert new elements inside the global application.
## Working as a team: tools & organisation
Complex Shiny Apps usually imply that several people will work on the application.
For example, at ThinkR, 3 to 4 people usually work on the application, but there might be more people involved on larger project.
Working as a team, whatever the coding project, requires discipline and organisation.
How can we achieve that?
### From the tools point of view:
#### Version Control & Test all the things
When you are working on a complex application, chances are that you'll be working on it for a significant period of time, meaning that you'll write code, modify it, use it, go back to it after a few weeks, change some other things, and probably break things.
Breaking things is a natural process of software engineering, notably when working on a piece of code during a long period.
Remember the last chapter where we defined that complex applications are too large to be understood fully?
Adding code that breaks the codebase will happen with complex app, so the sooner you take measure to solve code break the better.
As you can't prevent code to break, you should at least get the tooling to:
+ Be informed that the code has broken
+ Be able to identify changes, and to potentially get back in time to a previous code base.
To get informed about a code break, you'll need to write tests for your app, and to use Continuous Integration so that you're sure this is automatically detected^[
Relying on automatic tooling for monitoring code base is way safer than relying on developers to do manual checks every time they commit code.
].
We'll get back to testing and version control in depth in [chapter 14](#step-secure).
#### Small is beautiful
Last chapter introduced the notion of complexity in size, where the app grows so large that it's very hard to have a good grasp of it.
A large code base implies that the safe way to work is to split the app in pieces as much as possible.
Splitting a Shiny project is made possible by following two techniques:
+ Split your app into Shiny Modules, so that your app be though of as a tree, making is possible for every developer to concentrate on one node, and only one, instead of having to think about the global infrastructure when implementing features
![](img/app_tree.png)
+ Extract your core "non-reactive" functions, that we will also call the "business logic", and include them in external files, so that you can work on these outside of the app: in other words, so that you don't have to relaunch the whole app every time you need to do something new
We'll get back to Shiny module and how to organised your project in the next chapter.
### From the organisational point of view
First of all, you'll need one person (or maybe two) to be in charge of supervising the whole project.
It's hard to have the complete picture of what the app is doing, and most of the time, as a developer, you don't need to.
On the other hand, if the work is correctly spit between members of the team, you'll probably be focusing on one or more part(s) of the application, but you don't need to know every single bit of what the application is doing.
But someone has to be get the whole picture: what each part of the software is doing, and how to make all work together, and of course how to check that, at the end of the day, the results returned by the application are the correct ones.
This very same person will be the one that kicks off the project, and write the first draft of the application.
If you're following the workflow we'll describe in this book, this person in charge of supervising will create a `{golem}` project, fill the information, and define the application structure by providing the modules, and the prototype of the app.
If you're working following `git flow` (described in chapter 13), this person in charge of managing the app will also be in charge of reviewing the pull requests and merging them to `dev` if they solve the associated issue.
Don't worry if this sounds like a foreign language to you, we'll get back to this method in this book.
Once this skeleton of an app is created, create a series of tasks to be accomplished.
Using a Version Control System like `git` will help you there: you'll open a series of issues which will be closed during the development.
Other management tools can be used there: for example `redmine`, `jira`, or any issue tracking software can play this role.
We strongly suggest to use git, either on GitHub or on GitLab, as it can be easily integrated with R, and of course as it can also be used for doing versioning.
As the app will be split in various Shiny Modules, you can assign the development of one or more module(s) to one member of the team.
Remember that it's simpler to work in a context where one developer is assigned to one module, even if in reality it's a little bit more complex than that, and several members of the team might go back and forth working on a module.
But in a perfect world, one module equals one file, and every body safely works on their own part of the application.
Then, only one person is in charge of making all the pieces fit together.