WEBVTT

1
00:00:00.120 --> 00:00:03.560
<v Speaker 1>Have you ever been knee deep in a software project

2
00:00:04.000 --> 00:00:07.679
<v Speaker 1>watching it grow and suddenly that familiar feeling of dread

3
00:00:07.960 --> 00:00:11.119
<v Speaker 1>creeps in. Oh yeah, but feeling that your elegant creation

4
00:00:11.640 --> 00:00:15.679
<v Speaker 1>is slowly but surely turning into well a ball of mud.

5
00:00:15.800 --> 00:00:18.120
<v Speaker 2>Mm hmm, complex, hard to change.

6
00:00:17.800 --> 00:00:21.960
<v Speaker 1>Exactly, Test suites, crawling bugs playing hide and seek. Yeah,

7
00:00:22.039 --> 00:00:24.879
<v Speaker 1>I think we've all been there. Definitely. Today we're diving

8
00:00:24.960 --> 00:00:30.160
<v Speaker 1>deep into a powerful solution for those growing pains. While

9
00:00:30.280 --> 00:00:33.960
<v Speaker 1>rails is absolutely fantastic for getting applications off the ground quickly,

10
00:00:34.119 --> 00:00:37.119
<v Speaker 1>it really is, it can face significant challenges when those

11
00:00:37.119 --> 00:00:39.640
<v Speaker 1>applications scale into large, complex beasts.

12
00:00:39.759 --> 00:00:40.799
<v Speaker 2>That's the crux of it.

13
00:00:40.799 --> 00:00:44.520
<v Speaker 1>And that's where component based Rails applications or CVRA comes in.

14
00:00:44.719 --> 00:00:47.799
<v Speaker 1>It's an architectural approach designed to bring order and control

15
00:00:47.840 --> 00:00:49.960
<v Speaker 1>back to those unruly rails code.

16
00:00:49.679 --> 00:00:53.479
<v Speaker 2>Bases right, and we're drawing heavily from Steven Hagman's excellent

17
00:00:53.520 --> 00:00:57.759
<v Speaker 2>book on this Component based Rails Applications, Large Domains under Control,

18
00:00:58.240 --> 00:00:59.719
<v Speaker 2>a really solid source.

19
00:01:00.119 --> 00:01:03.320
<v Speaker 1>Absolutely, So our mission today is to give you a shortcut.

20
00:01:03.439 --> 00:01:06.799
<v Speaker 1>We're going to unpack what CBI is, why it matters,

21
00:01:07.400 --> 00:01:13.719
<v Speaker 1>and how can transform a chaotic application into something well structured, maintainable.

22
00:01:13.159 --> 00:01:16.400
<v Speaker 2>And hopefully find some surprising insights along the way, things

23
00:01:16.400 --> 00:01:18.760
<v Speaker 2>that maybe go beyond the usual architecture talks.

24
00:01:18.799 --> 00:01:23.200
<v Speaker 1>Okay, so let's unpack this. Many rails apps start out elegant, right,

25
00:01:23.239 --> 00:01:27.280
<v Speaker 1>they're monoliths, a single cohesive unit. But what really happens

26
00:01:27.319 --> 00:01:30.560
<v Speaker 1>when they grow, say, beyond just a handful of developers

27
00:01:30.599 --> 00:01:34.159
<v Speaker 1>or features. Where does that wall of mud feeling actually

28
00:01:34.640 --> 00:01:35.200
<v Speaker 1>come from?

29
00:01:35.560 --> 00:01:38.599
<v Speaker 2>Well that's a critical point in an applications life cycle,

30
00:01:38.680 --> 00:01:41.040
<v Speaker 2>isn't it. You start seeing these telltale signs, like what

31
00:01:41.319 --> 00:01:43.680
<v Speaker 2>feature development starts to grind to a halt? It just

32
00:01:43.719 --> 00:01:47.480
<v Speaker 2>gets incredibly expensive to add anything new your test suites.

33
00:01:47.640 --> 00:01:53.079
<v Speaker 2>They get agonizingly slow, brittle. Sometimes honestly, they just get

34
00:01:53.079 --> 00:01:55.079
<v Speaker 2>abandoned because maintaining them is too painful.

35
00:01:55.200 --> 00:01:56.400
<v Speaker 1>Yeah, I've seen that happen.

36
00:01:56.319 --> 00:02:00.719
<v Speaker 2>And those elusive bugs they become increasingly difficult to track down. Now,

37
00:02:00.799 --> 00:02:03.560
<v Speaker 2>sheer size plays a role, for sure, but the root

38
00:02:03.680 --> 00:02:06.959
<v Speaker 2>cause is often complexity just spiraling out of control.

39
00:02:07.239 --> 00:02:12.719
<v Speaker 1>So it is about complexity spiraling. We're aiming for maintainability, obviously,

40
00:02:13.280 --> 00:02:15.800
<v Speaker 1>but how do we even begin to understand what a

41
00:02:15.800 --> 00:02:19.080
<v Speaker 1>complex code base truly means? Is there like a way

42
00:02:19.120 --> 00:02:21.199
<v Speaker 1>to measure that or is it just this gut feeling.

43
00:02:22.080 --> 00:02:24.759
<v Speaker 2>That's a fascinating question. And what's really interesting here is

44
00:02:24.759 --> 00:02:26.240
<v Speaker 2>how network theory.

45
00:02:26.199 --> 00:02:28.719
<v Speaker 1>Applies network theory in code.

46
00:02:28.879 --> 00:02:32.439
<v Speaker 2>Yeah, imagine your codebase as a sort of social network.

47
00:02:32.680 --> 00:02:36.439
<v Speaker 2>Your classes are the nodes, right, okay, and their interactions

48
00:02:36.479 --> 00:02:39.120
<v Speaker 2>the calls between them, those are the connections. Now, concepts

49
00:02:39.199 --> 00:02:43.479
<v Speaker 2>like Metcalf's law suggest utility, and you could argue complexity too,

50
00:02:43.759 --> 00:02:45.520
<v Speaker 2>grows with n squared.

51
00:02:45.199 --> 00:02:47.879
<v Speaker 1>Connection n square Okay, so it grows fast, it gets worse.

52
00:02:48.240 --> 00:02:50.240
<v Speaker 2>Read's law suggests it could even be two to the

53
00:02:50.280 --> 00:02:52.879
<v Speaker 2>power of n with subgroups. Think about adding one more

54
00:02:52.879 --> 00:02:55.319
<v Speaker 2>person to a small party. They don't just add one

55
00:02:55.360 --> 00:02:58.840
<v Speaker 2>new interaction, They potentially start new conversations with everyone already there.

56
00:02:58.879 --> 00:03:01.360
<v Speaker 2>The more people, the fast or the social connections, and

57
00:03:01.439 --> 00:03:03.039
<v Speaker 2>the complexity just explodes.

58
00:03:03.240 --> 00:03:07.960
<v Speaker 1>Wow, Okay, that sounds kind of depressing actually, like it's

59
00:03:08.000 --> 00:03:10.120
<v Speaker 1>an inescapable fate for any big.

60
00:03:09.960 --> 00:03:13.439
<v Speaker 2>App uh huh No, not depressing, Well, maybe a little daunting. Yeah,

61
00:03:13.520 --> 00:03:17.280
<v Speaker 2>But look, while adding more code always increases potential complexity,

62
00:03:17.400 --> 00:03:21.240
<v Speaker 2>that's just physics. Almost Good architecture is about staying.

63
00:03:20.879 --> 00:03:22.280
<v Speaker 1>In control, staying in control.

64
00:03:22.680 --> 00:03:25.919
<v Speaker 2>Introducing components, even with their own little bit of overhead,

65
00:03:25.919 --> 00:03:29.800
<v Speaker 2>actually helps manage this complexity, especially as the application gets bigger.

66
00:03:29.919 --> 00:03:33.319
<v Speaker 2>The goal isn't to eliminate complexity entirely. That's impossible. It's

67
00:03:33.360 --> 00:03:37.280
<v Speaker 2>more like learning to sail effectively. When the tide is rising.

68
00:03:37.319 --> 00:03:39.000
<v Speaker 2>You just want to stay afloat afloat.

69
00:03:39.080 --> 00:03:41.919
<v Speaker 1>I like that. So if the big monolist is the

70
00:03:41.960 --> 00:03:45.000
<v Speaker 1>ball of mud, how do we break it apart without

71
00:03:45.039 --> 00:03:48.919
<v Speaker 1>just creating, you know, smaller balls of mud everywhere? What

72
00:03:49.120 --> 00:03:52.520
<v Speaker 1>exactly is a component in this CBI context? Are we

73
00:03:52.520 --> 00:03:53.680
<v Speaker 1>talking micro services here?

74
00:03:53.719 --> 00:03:57.319
<v Speaker 2>Good question? Not necessarily microservices, though there are olapse in

75
00:03:57.360 --> 00:04:01.360
<v Speaker 2>the philosophy. The core idea is some Really, a component

76
00:04:01.439 --> 00:04:04.719
<v Speaker 2>is just a piece of software with really clear responsibilities,

77
00:04:04.879 --> 00:04:07.120
<v Speaker 2>a well defined public interface so you know how to

78
00:04:07.159 --> 00:04:10.680
<v Speaker 2>talk to it, and an explicit dependency on its surroundings.

79
00:04:11.039 --> 00:04:13.719
<v Speaker 2>It says exactly what it needs from the outside world.

80
00:04:13.800 --> 00:04:15.960
<v Speaker 1>Explicit dependency, and crucially this is key.

81
00:04:16.040 --> 00:04:21.319
<v Speaker 2>Unlike typical objects, maybe components cannot have circular dependencies. A

82
00:04:21.480 --> 00:04:23.920
<v Speaker 2>can depend on B, but B cannot depend back on

83
00:04:24.000 --> 00:04:25.480
<v Speaker 2>A directly or indirectly.

84
00:04:25.759 --> 00:04:27.720
<v Speaker 1>Uh okay, no loops.

85
00:04:27.439 --> 00:04:30.720
<v Speaker 2>No loops. Think of it as a self contained, independent unit.

86
00:04:31.040 --> 00:04:33.519
<v Speaker 1>Right, So here's where it gets really interesting for me

87
00:04:34.199 --> 00:04:37.160
<v Speaker 1>in Rails, what does that look like practically? What are

88
00:04:37.199 --> 00:04:38.759
<v Speaker 1>we actually building these components out of?

89
00:04:38.920 --> 00:04:43.199
<v Speaker 2>Stephan Hageman in the book really emphasizes using standard Ruby tools,

90
00:04:43.639 --> 00:04:46.160
<v Speaker 2>Ruby gems, and specifically Rails engines.

91
00:04:46.240 --> 00:04:46.879
<v Speaker 1>Rails engines.

92
00:04:46.959 --> 00:04:49.800
<v Speaker 2>Okay, I know those, and since Rails three point zero,

93
00:04:49.839 --> 00:04:53.480
<v Speaker 2>every Rails application is actually just an engine itself under

94
00:04:53.519 --> 00:04:53.839
<v Speaker 2>the hood.

95
00:04:54.000 --> 00:04:55.720
<v Speaker 1>Oh interesting, I didn't realize that. Yeah.

96
00:04:55.800 --> 00:04:59.120
<v Speaker 2>So engines are basically miniature applications that provide functionality to

97
00:04:59.160 --> 00:05:02.439
<v Speaker 2>their host application. Think about gems. You probably already use

98
00:05:02.639 --> 00:05:07.800
<v Speaker 2>like devise for authentication, right, yeah, device or threaded for forums,

99
00:05:08.120 --> 00:05:12.240
<v Speaker 2>or spree for e commerce. These are all basically components

100
00:05:12.240 --> 00:05:15.639
<v Speaker 2>implemented as engines. Oh okay, they're isolated, you can test

101
00:05:15.639 --> 00:05:19.480
<v Speaker 2>them individually, and they have those explicit non cyclic dependencies

102
00:05:19.519 --> 00:05:23.680
<v Speaker 2>we talked about that clear boundary is absolutely fundamental to

103
00:05:23.720 --> 00:05:24.839
<v Speaker 2>containing the complexity.

104
00:05:24.959 --> 00:05:28.800
<v Speaker 1>That makes perfect sense. So it's about clearly defined boundaries

105
00:05:28.839 --> 00:05:33.120
<v Speaker 1>and relationships. Is like building with Legos instead of Plato exactly.

106
00:05:33.240 --> 00:05:36.399
<v Speaker 2>That's a great analogy, much more structured, much easier to

107
00:05:36.519 --> 00:05:40.439
<v Speaker 2>reason about and change individual pieces so beyond just.

108
00:05:40.399 --> 00:05:43.879
<v Speaker 1>The tech definition, what are the real world, tangible benefits

109
00:05:44.079 --> 00:05:46.600
<v Speaker 1>for a team working on a large rails app. Why

110
00:05:46.639 --> 00:05:49.439
<v Speaker 1>does adopting this component based approach truly matter for you

111
00:05:49.519 --> 00:05:50.680
<v Speaker 1>and your project's.

112
00:05:50.279 --> 00:05:52.759
<v Speaker 2>Day to day Yeah, connecting it to the bigger picture.

113
00:05:52.959 --> 00:05:57.319
<v Speaker 2>CBRA dramatically improve several key areas. First off, improve communication

114
00:05:57.360 --> 00:05:57.759
<v Speaker 2>of intent.

115
00:05:57.879 --> 00:06:00.000
<v Speaker 1>Communication of intent? How so well.

116
00:06:00.000 --> 00:06:02.600
<v Speaker 2>Components force you to name and structure parts of your

117
00:06:02.639 --> 00:06:05.839
<v Speaker 2>application at a higher level. Imagine walking into a massive

118
00:06:05.839 --> 00:06:07.279
<v Speaker 2>codebase you've never seen before.

119
00:06:08.120 --> 00:06:09.920
<v Speaker 1>Daunting totally, But.

120
00:06:10.040 --> 00:06:13.000
<v Speaker 2>What if just by looking at its top level structure,

121
00:06:13.399 --> 00:06:18.759
<v Speaker 2>seeing component names like importer, source, master programs, you could

122
00:06:18.800 --> 00:06:20.600
<v Speaker 2>immediately grasp its core purpose.

123
00:06:20.839 --> 00:06:23.759
<v Speaker 1>I see the structure itself tells a story exactly.

124
00:06:24.079 --> 00:06:29.240
<v Speaker 2>CBRA helps the architecture itself scream the applications domain, not

125
00:06:29.319 --> 00:06:32.160
<v Speaker 2>just the framework underneath. It makes the intent clearer.

126
00:06:32.279 --> 00:06:33.759
<v Speaker 1>Okay, that's powerful. What else?

127
00:06:34.040 --> 00:06:37.000
<v Speaker 2>Second? You get improved collaboration among developers.

128
00:06:37.199 --> 00:06:39.079
<v Speaker 1>How does it help teams work together better?

129
00:06:39.560 --> 00:06:44.560
<v Speaker 2>Those explicit dependencies we keep mentioning they drastically reduce conflict zones.

130
00:06:45.000 --> 00:06:47.879
<v Speaker 2>The book gives this great example where maybe working on

131
00:06:47.959 --> 00:06:51.600
<v Speaker 2>a source component versus a user component reduces potential merge

132
00:06:51.600 --> 00:06:55.120
<v Speaker 2>conflicts from affecting the entire monolith down to maybe just

133
00:06:55.160 --> 00:06:57.639
<v Speaker 2>shared components like admin or navigator.

134
00:06:57.879 --> 00:07:00.040
<v Speaker 1>So fewer people stepping on each other's.

135
00:06:59.800 --> 00:07:03.519
<v Speaker 2>Toes precisely, Teams can work more independently on different areas,

136
00:07:03.639 --> 00:07:06.120
<v Speaker 2>leading to smooter development, fewer painful merges.

137
00:07:06.240 --> 00:07:07.120
<v Speaker 1>Nice, what's next.

138
00:07:07.360 --> 00:07:09.519
<v Speaker 2>Third, there's improved creation of features.

139
00:07:09.680 --> 00:07:10.920
<v Speaker 1>Easier to build new stuff.

140
00:07:11.240 --> 00:07:15.399
<v Speaker 2>Yeah, new features can often be developed as entirely new components.

141
00:07:15.680 --> 00:07:18.639
<v Speaker 2>Then you can simply feature flag them by like just

142
00:07:18.839 --> 00:07:21.600
<v Speaker 2>not loading that component's engine in production until it's ready.

143
00:07:21.759 --> 00:07:24.839
<v Speaker 1>Oh so, no need for complex branching strategies or separate

144
00:07:24.879 --> 00:07:26.920
<v Speaker 1>feature flag gems necessarily Often no.

145
00:07:27.319 --> 00:07:30.120
<v Speaker 2>You can even do things like duplicate an existing engine,

146
00:07:30.160 --> 00:07:34.079
<v Speaker 2>say reports, create Reports V two alongside it, test it,

147
00:07:34.160 --> 00:07:36.519
<v Speaker 2>deploy it, and then just sunset the old one later.

148
00:07:36.759 --> 00:07:39.040
<v Speaker 2>It allows for really agile evolution.

149
00:07:39.240 --> 00:07:40.040
<v Speaker 1>Okay, that's clever.

150
00:07:40.279 --> 00:07:43.560
<v Speaker 2>Fourth, you'll see improved maintenance. This is a big one.

151
00:07:43.680 --> 00:07:45.439
<v Speaker 1>Maintenance Yeah, always a pain point.

152
00:07:45.639 --> 00:07:49.959
<v Speaker 2>Upgrading external dependencies even rails itself becomes much easier. You

153
00:07:50.000 --> 00:07:53.120
<v Speaker 2>can test and adapt individual components to new versions while

154
00:07:53.120 --> 00:07:55.040
<v Speaker 2>the main app stays compatible.

155
00:07:54.560 --> 00:07:58.079
<v Speaker 1>For a while. Ah, so you avoid those massive terrifying

156
00:07:58.439 --> 00:08:01.560
<v Speaker 1>upgrade rails now brand inches that paralyze the team.

157
00:08:01.720 --> 00:08:05.160
<v Speaker 2>Hopefully it breaks the problem down. You tackle dependencies component

158
00:08:05.199 --> 00:08:06.240
<v Speaker 2>by component.

159
00:08:05.920 --> 00:08:07.759
<v Speaker 1>Makes sense and the last one.

160
00:08:07.600 --> 00:08:11.199
<v Speaker 2>And finally just improved comprehension of application.

161
00:08:10.759 --> 00:08:12.639
<v Speaker 1>Parts, easier to understand the code.

162
00:08:12.839 --> 00:08:16.959
<v Speaker 2>Definitely breaking that huge structure into smaller cohesive bits with

163
00:08:17.040 --> 00:08:21.040
<v Speaker 2>small interfaces. Let's developer's focus. You can load just one

164
00:08:21.160 --> 00:08:24.360
<v Speaker 2>component's context into your head at a time, reducing that

165
00:08:24.439 --> 00:08:28.439
<v Speaker 2>cognitive load. You're not trying to juggle the entire class

166
00:08:28.439 --> 00:08:29.959
<v Speaker 2>social network anymore.

167
00:08:29.639 --> 00:08:32.120
<v Speaker 1>Right, just focus on your lego block. I'm sold on

168
00:08:32.159 --> 00:08:35.039
<v Speaker 1>the benefits. So, if you're convinced and you want to

169
00:08:35.159 --> 00:08:38.840
<v Speaker 1>start a new large Rails project with CBR in mind,

170
00:08:39.399 --> 00:08:41.480
<v Speaker 1>how do you actually do it? What are the practical

171
00:08:41.480 --> 00:08:44.080
<v Speaker 1>first steps? How do you build that lego castle?

172
00:08:44.200 --> 00:08:46.879
<v Speaker 2>Well, the process starts pretty much like any rails app,

173
00:08:47.080 --> 00:08:47.679
<v Speaker 2>Rails new.

174
00:08:47.519 --> 00:08:48.720
<v Speaker 1>Repn okay standard start.

175
00:08:48.759 --> 00:08:51.279
<v Speaker 2>But then pretty much right away, you create a component's

176
00:08:51.320 --> 00:08:52.320
<v Speaker 2>folder at the root.

177
00:08:52.200 --> 00:08:53.840
<v Speaker 1>Level components folder, got it.

178
00:08:53.840 --> 00:08:56.960
<v Speaker 2>And then you use the rail's plugin generator to create

179
00:08:56.960 --> 00:08:59.799
<v Speaker 2>your first component inside that folder. So something like rails

180
00:08:59.799 --> 00:09:02.120
<v Speaker 2>plug in new zapp component.

181
00:09:01.799 --> 00:09:03.639
<v Speaker 1>Full mountable, full manable okay.

182
00:09:03.679 --> 00:09:06.840
<v Speaker 2>Stefan in the book uses a sports ball app example

183
00:09:06.879 --> 00:09:10.159
<v Speaker 2>for this, managing teams and games, simple enough to show

184
00:09:10.159 --> 00:09:11.320
<v Speaker 2>the concepts clearly.

185
00:09:11.600 --> 00:09:14.759
<v Speaker 1>Okay, a sports app. But wait, that name app component

186
00:09:14.919 --> 00:09:17.519
<v Speaker 1>that doesn't exactly scream its intent, does it? Yeah, seems

187
00:09:17.559 --> 00:09:19.120
<v Speaker 1>a bit generica. Is that just a placeholder?

188
00:09:19.240 --> 00:09:21.879
<v Speaker 2>Uh huh? Yeah, that's a sharp observation. And the book

189
00:09:21.960 --> 00:09:25.559
<v Speaker 2>actually uses app component intentionally at first?

190
00:09:25.799 --> 00:09:26.480
<v Speaker 1>Really why?

191
00:09:26.600 --> 00:09:30.519
<v Speaker 2>Precisely because it's ambiguous. It gives you a place to

192
00:09:30.759 --> 00:09:34.440
<v Speaker 2>essentially dump an entire existing application or the initial core

193
00:09:34.480 --> 00:09:38.639
<v Speaker 2>web stuff into one component as a starting point. You

194
00:09:38.679 --> 00:09:40.720
<v Speaker 2>don't get bogged down trying to find the perfect name

195
00:09:40.799 --> 00:09:41.399
<v Speaker 2>right at the beginning.

196
00:09:41.440 --> 00:09:43.720
<v Speaker 1>Oh okay, so it's a pragmatic first step exactly.

197
00:09:43.759 --> 00:09:46.559
<v Speaker 2>You get the structure in place. Later you refactor that

198
00:09:46.600 --> 00:09:50.279
<v Speaker 2>app component into multiple well named components like maybe Wabi

199
00:09:50.440 --> 00:09:55.000
<v Speaker 2>teams admin, games admin, once its true responsibilities become clearer.

200
00:09:55.039 --> 00:09:56.960
<v Speaker 2>It's a starting point, not the end goal.

201
00:09:57.480 --> 00:10:00.399
<v Speaker 1>Gotcha. Now. An interesting point the book brings up here

202
00:10:00.440 --> 00:10:04.919
<v Speaker 1>is about fundamental rails, things like database migrations. How do

203
00:10:04.960 --> 00:10:07.720
<v Speaker 1>those work when your app is split into these mini

204
00:10:07.720 --> 00:10:10.279
<v Speaker 1>applications these engines. Seems like that could get.

205
00:10:10.080 --> 00:10:13.240
<v Speaker 2>Messy yeah, that is a common pitfall. It catches people

206
00:10:13.240 --> 00:10:17.200
<v Speaker 2>out while running KEDB dot migrate might work fine inside

207
00:10:17.240 --> 00:10:20.720
<v Speaker 2>the component's dummy app during development, right, it won't automatically

208
00:10:20.799 --> 00:10:24.639
<v Speaker 2>work for the main host application initially. It's like trying

209
00:10:24.679 --> 00:10:27.240
<v Speaker 2>to flush a toilet in one office suite and realizing

210
00:10:27.279 --> 00:10:30.080
<v Speaker 2>it's on a completely separate plumbing system from the main building.

211
00:10:30.240 --> 00:10:32.120
<v Speaker 1>Okay, so how do you connect the plumbing.

212
00:10:32.279 --> 00:10:36.240
<v Speaker 2>The solution is pretty straightforward. You include a specific unctualizer

213
00:10:36.320 --> 00:10:40.240
<v Speaker 2>in your components engine dot RB file, something like initializer

214
00:10:40.279 --> 00:10:43.360
<v Speaker 2>dot ap pend migrations and the engine can fig yep,

215
00:10:43.759 --> 00:10:45.879
<v Speaker 2>and that tells the main application. Hey, look in my

216
00:10:46.000 --> 00:10:49.759
<v Speaker 2>dB migratefolder too. When you run migrations, it automatically appends

217
00:10:49.759 --> 00:10:52.679
<v Speaker 2>the engines migrations to the main apps list, no need

218
00:10:52.720 --> 00:10:55.120
<v Speaker 2>to manually copy them over, which is error prone.

219
00:10:55.240 --> 00:10:57.039
<v Speaker 1>Ah okay, that's clean.

220
00:10:57.039 --> 00:11:00.000
<v Speaker 2>It is, but you do have to be a bit careful.

221
00:11:00.279 --> 00:11:03.399
<v Speaker 2>The source explicitly points out not to chain commands like

222
00:11:03.720 --> 00:11:07.320
<v Speaker 2>RAKEDB dot drop, dB dot create, dB dot migrate when

223
00:11:07.360 --> 00:11:09.960
<v Speaker 2>migrations are loaded this way, as it can sometimes cause

224
00:11:09.960 --> 00:11:12.639
<v Speaker 2>issues depending on the order things load. It's about that

225
00:11:12.759 --> 00:11:14.559
<v Speaker 2>explicit configuration again.

226
00:11:14.559 --> 00:11:18.360
<v Speaker 1>Right, always subtleties. Okay, so dependencies. They can get messy

227
00:11:18.399 --> 00:11:21.279
<v Speaker 1>in any project, right. So once these components are defined

228
00:11:21.320 --> 00:11:24.000
<v Speaker 1>and they can find each other's migrations, the next hurdle

229
00:11:24.080 --> 00:11:27.159
<v Speaker 1>is making sure they actually work reliably together, which brings

230
00:11:27.240 --> 00:11:31.960
<v Speaker 1>us to how CBO manages dependencies between components and then testing.

231
00:11:31.600 --> 00:11:36.600
<v Speaker 2>And deployment exactly so dependencies. Components declare their external dependencies

232
00:11:36.679 --> 00:11:40.360
<v Speaker 2>like any other GEM in their dot gemspeck file standard stuff. Okay,

233
00:11:40.720 --> 00:11:43.519
<v Speaker 2>for internal components, the ones living in your component's directory,

234
00:11:43.840 --> 00:11:46.799
<v Speaker 2>you use path blocks in the main applications gem file.

235
00:11:47.080 --> 00:11:48.799
<v Speaker 1>So in the main gem file you'd have something like

236
00:11:48.919 --> 00:11:52.440
<v Speaker 1>gem teams admin path Components team.

237
00:11:52.279 --> 00:11:56.120
<v Speaker 2>Sadman precisely that tells Bundler where to find that local component.

238
00:11:56.279 --> 00:11:59.519
<v Speaker 2>The book shows examples integrating things like the slim templating

239
00:11:59.559 --> 00:12:03.759
<v Speaker 2>gem or even a specific true skill rating calculation library.

240
00:12:03.799 --> 00:12:05.759
<v Speaker 2>This way within components makes sense.

241
00:12:06.279 --> 00:12:09.240
<v Speaker 1>What about versioning, though, especially for those external gems that

242
00:12:09.279 --> 00:12:12.399
<v Speaker 1>components rely on. Do you let Bundler resolve them loosely

243
00:12:12.559 --> 00:12:14.720
<v Speaker 1>or do you lock them down? This causes so many

244
00:12:14.720 --> 00:12:15.759
<v Speaker 1>headaches and monoliths.

245
00:12:16.159 --> 00:12:19.919
<v Speaker 2>Yeah, this is absolutely critical. The strong recommendation from the

246
00:12:19.960 --> 00:12:22.960
<v Speaker 2>book is to lock down all run time dependencies and

247
00:12:23.039 --> 00:12:26.600
<v Speaker 2>each component's jumps back to exact versions.

248
00:12:26.279 --> 00:12:29.399
<v Speaker 1>Exact versions like gems library one point two.

249
00:12:29.240 --> 00:12:32.799
<v Speaker 2>Point three exactly like that the reason to avoid what

250
00:12:32.840 --> 00:12:35.879
<v Speaker 2>the book calls untested dependencies in production.

251
00:12:36.159 --> 00:12:36.759
<v Speaker 1>Ah right.

252
00:12:37.159 --> 00:12:40.120
<v Speaker 2>If your component was tested against version one point zho

253
00:12:40.159 --> 00:12:43.039
<v Speaker 2>of a GEM, but the main apps gemfile dot lock

254
00:12:43.159 --> 00:12:46.679
<v Speaker 2>somehow pulls in one point one for production, you've got

255
00:12:46.679 --> 00:12:49.759
<v Speaker 2>a dangerous gap. You're running code you haven't explicitly tested

256
00:12:49.759 --> 00:12:50.879
<v Speaker 2>in that component's context.

257
00:12:50.919 --> 00:12:53.320
<v Speaker 1>Okay, that makes a lot of sense, eliminate surprises. What

258
00:12:53.440 --> 00:12:56.399
<v Speaker 1>about development dependencies, Like if you're pointing to a specific

259
00:12:56.480 --> 00:12:58.080
<v Speaker 1>get commit of a GEM.

260
00:12:57.879 --> 00:13:00.440
<v Speaker 2>Good point for those, like maybe a specific admit of

261
00:13:00.480 --> 00:13:03.600
<v Speaker 2>that true skill library. You might actually need to duplicate

262
00:13:03.679 --> 00:13:06.039
<v Speaker 2>that get reference in the main app stem file as well.

263
00:13:06.480 --> 00:13:10.159
<v Speaker 2>Bundler sometimes ignores those specific refs in a dependencies gemspeck.

264
00:13:10.279 --> 00:13:12.840
<v Speaker 2>It's a bit of a workaround, but it ensures consistency.

265
00:13:13.080 --> 00:13:16.360
<v Speaker 1>Okay, so be explicit lock run time versions. Got it,

266
00:13:16.639 --> 00:13:20.960
<v Speaker 1>So you've built your components handled dependencies. Now how do

267
00:13:21.039 --> 00:13:24.960
<v Speaker 1>you actually test this structure? And then how do you

268
00:13:25.000 --> 00:13:28.120
<v Speaker 1>get it deployed? Does it need a whole new DEICD.

269
00:13:27.720 --> 00:13:31.600
<v Speaker 2>Pipeline testing is generally done per component. You navigate into

270
00:13:31.639 --> 00:13:34.559
<v Speaker 2>each component's directory and run its test suite, usually our

271
00:13:34.679 --> 00:13:36.240
<v Speaker 2>spec or minute.

272
00:13:35.960 --> 00:13:38.279
<v Speaker 1>Test so isolated tests yep.

273
00:13:38.720 --> 00:13:42.320
<v Speaker 2>The book covers setting up URSPEC for model specs, controller specs,

274
00:13:42.399 --> 00:13:45.879
<v Speaker 2>feature spex within an engine. One key tip, especially for

275
00:13:45.919 --> 00:13:49.159
<v Speaker 2>controller specs inside an engine, is you need to explicitly

276
00:13:49.240 --> 00:13:51.240
<v Speaker 2>tell arspec to use the engine's routes.

277
00:13:51.279 --> 00:13:51.919
<v Speaker 1>How do you do that?

278
00:13:51.960 --> 00:13:54.240
<v Speaker 2>You to add something like routes my component dot engine

279
00:13:54.240 --> 00:13:56.919
<v Speaker 2>dot routes inside your controller spec described block.

280
00:13:56.759 --> 00:13:59.320
<v Speaker 1>Okay, tells urspec which you are all helpers.

281
00:13:58.960 --> 00:14:01.679
<v Speaker 2>To use exactly. And then for the overall application build

282
00:14:01.679 --> 00:14:04.039
<v Speaker 2>you typically just have a simple shell script maybe build

283
00:14:04.080 --> 00:14:08.000
<v Speaker 2>dot esh that goes into each component directory, runs its tests,

284
00:14:08.039 --> 00:14:10.559
<v Speaker 2>and maybe runs some integration tests in the main app.

285
00:14:10.639 --> 00:14:13.600
<v Speaker 1>Right, a simple script orchestrating the component tests. What about

286
00:14:13.639 --> 00:14:16.799
<v Speaker 1>CI and deploying the platforms like Heroku or say Pivotal

287
00:14:16.799 --> 00:14:17.519
<v Speaker 1>Web Services.

288
00:14:17.759 --> 00:14:21.200
<v Speaker 2>For the most part, CBRI apps deploy like standard rails apps.

289
00:14:22.440 --> 00:14:25.879
<v Speaker 2>But there's a catch that non standard folder structure. Right

290
00:14:26.279 --> 00:14:28.320
<v Speaker 2>with the main app maybe nested in web container and

291
00:14:28.360 --> 00:14:30.279
<v Speaker 2>components and a separate components folder.

292
00:14:30.360 --> 00:14:32.519
<v Speaker 1>Yeah, build packs usually expect the rails app at the

293
00:14:32.559 --> 00:14:33.320
<v Speaker 1>root exactly.

294
00:14:33.720 --> 00:14:36.879
<v Speaker 2>So the common solution is to create a deploy artifact.

295
00:14:37.200 --> 00:14:39.120
<v Speaker 1>A deploy artifact.

296
00:14:38.679 --> 00:14:43.840
<v Speaker 2>Yeah, basically a script maybe prepare deploydirectory dotsh that copies

297
00:14:43.879 --> 00:14:46.960
<v Speaker 2>the necessary parts of the main app the bundled components

298
00:14:47.000 --> 00:14:49.919
<v Speaker 2>into a temporary directory that does have the standard structure

299
00:14:49.960 --> 00:14:51.360
<v Speaker 2>build packs expect.

300
00:14:51.360 --> 00:14:53.919
<v Speaker 1>You create a staging area with the right layout just

301
00:14:53.960 --> 00:14:54.559
<v Speaker 1>for deployment.

302
00:14:54.639 --> 00:14:58.320
<v Speaker 2>Precisely for Heroku. The book even mentions you might use

303
00:14:58.360 --> 00:15:01.519
<v Speaker 2>their platform API to up fload that generated artifact as

304
00:15:01.559 --> 00:15:05.279
<v Speaker 2>a tarball directly bypassing the standard get push hero kumine.

305
00:15:05.360 --> 00:15:08.360
<v Speaker 2>If your repos structure doesn't match what the build pack needs.

306
00:15:08.360 --> 00:15:12.200
<v Speaker 1>Clever okay, And once it's deployed, inevitably things need to change.

307
00:15:12.320 --> 00:15:16.960
<v Speaker 1>What about switching databases later or the big one upgrading rails.

308
00:15:17.159 --> 00:15:21.000
<v Speaker 1>How does CBRA help with those typically painful big lift moments.

309
00:15:20.799 --> 00:15:24.639
<v Speaker 2>Switching databases, say from school light to postcress School is

310
00:15:24.679 --> 00:15:27.679
<v Speaker 2>pretty straightforward for the main app, just like normal. But

311
00:15:27.759 --> 00:15:30.679
<v Speaker 2>an interesting subtle point the book makes is about achieving

312
00:15:30.720 --> 00:15:32.279
<v Speaker 2>dev test prod parity for.

313
00:15:32.240 --> 00:15:35.039
<v Speaker 1>Components parody for components, Yeah.

314
00:15:34.840 --> 00:15:37.759
<v Speaker 2>Setting up different database schemas for the main app and

315
00:15:37.799 --> 00:15:40.840
<v Speaker 2>each component like Sportsball development for the main app and

316
00:15:40.919 --> 00:15:43.960
<v Speaker 2>sports Ball Team sad Mind development for the team's component

317
00:15:44.320 --> 00:15:49.600
<v Speaker 2>actually improves testing and isolation. You ensure components aren't accidentally

318
00:15:49.639 --> 00:15:51.679
<v Speaker 2>bleeding into each other via the database.

319
00:15:52.519 --> 00:15:55.200
<v Speaker 1>Better isolation through separate schemas okay, and.

320
00:15:55.279 --> 00:15:58.519
<v Speaker 2>Rails upgrades still requires care. Obviously, you need to resolve

321
00:15:58.600 --> 00:16:02.000
<v Speaker 2>dependencies often update other gems along with Rails, but the

322
00:16:02.039 --> 00:16:05.759
<v Speaker 2>component structure helps. The book suggests thinking of major Rails

323
00:16:05.840 --> 00:16:09.720
<v Speaker 2>upgrades as long running dependency updates. You might create a

324
00:16:09.759 --> 00:16:13.360
<v Speaker 2>separate branch or build path upgrade components one by one,

325
00:16:13.519 --> 00:16:16.480
<v Speaker 2>ensuring their tests pass against the new Rails version before

326
00:16:16.559 --> 00:16:18.759
<v Speaker 2>merging it all back together. It gives you more granular

327
00:16:18.799 --> 00:16:20.879
<v Speaker 2>control over that big transition.

328
00:16:20.879 --> 00:16:24.759
<v Speaker 1>Breaks down the giant task. Okay, now let's shift gears

329
00:16:24.759 --> 00:16:27.879
<v Speaker 1>a bit. What if you're not starting fresh. What if

330
00:16:27.919 --> 00:16:30.559
<v Speaker 1>you're looking at an existing ball of mud, a legacy

331
00:16:30.639 --> 00:16:33.399
<v Speaker 1>Rails app, and you want to refactor it into components.

332
00:16:33.720 --> 00:16:36.480
<v Speaker 1>How do you even begin that process? Is it a

333
00:16:36.519 --> 00:16:38.559
<v Speaker 1>rip and replace or can you do it gradually?

334
00:16:39.080 --> 00:16:41.679
<v Speaker 2>That's the million dollar question for many teams, isn't it?

335
00:16:41.720 --> 00:16:44.159
<v Speaker 2>And the book brings in Robert Martin's idea here from

336
00:16:44.159 --> 00:16:47.679
<v Speaker 2>his talk Architecture the Lost Years, He argues that standard

337
00:16:47.759 --> 00:16:52.879
<v Speaker 2>rails apps often scream their framework, not their domain Intentscrean's.

338
00:16:52.000 --> 00:16:55.240
<v Speaker 1>The framework, meaning they look like rails apps, but you

339
00:16:55.279 --> 00:16:56.480
<v Speaker 1>can't easily tell what they do.

340
00:16:56.720 --> 00:17:00.799
<v Speaker 2>Kind of. Yeah. The web delivery mechanism controllers views is

341
00:17:00.840 --> 00:17:04.079
<v Speaker 2>front and center, but the core business logic, the actual

342
00:17:04.160 --> 00:17:07.480
<v Speaker 2>domain might be hidden or tangled up inside.

343
00:17:07.519 --> 00:17:09.839
<v Speaker 1>Okay, so how do we start changing that perception and

344
00:17:09.880 --> 00:17:12.279
<v Speaker 1>the structure itself, especially if we're starting from that big

345
00:17:12.319 --> 00:17:12.960
<v Speaker 1>ball of mud.

346
00:17:13.200 --> 00:17:16.839
<v Speaker 2>One really powerful, almost symbolic first step the book suggests

347
00:17:17.039 --> 00:17:20.519
<v Speaker 2>is to shift the main Rails application code like app

348
00:17:20.559 --> 00:17:24.799
<v Speaker 2>canfig gem file into a subfolder maybe call it web container.

349
00:17:24.440 --> 00:17:25.720
<v Speaker 1>Move the rails app itself.

350
00:17:26.000 --> 00:17:29.039
<v Speaker 2>Yeah, and then you elevate the components folder, even if

351
00:17:29.079 --> 00:17:31.960
<v Speaker 2>it's initially empty, to the root level of the project.

352
00:17:32.079 --> 00:17:35.359
<v Speaker 1>Oh I see that immediately changes the visual hierarchy exactly.

353
00:17:35.680 --> 00:17:39.400
<v Speaker 2>It signals visually that the components are the primary organizational

354
00:17:39.480 --> 00:17:42.319
<v Speaker 2>units and the Rails app is just one part the

355
00:17:42.359 --> 00:17:45.720
<v Speaker 2>delivery mechanism. It reframes how you think about the codebase.

356
00:17:46.200 --> 00:17:49.599
<v Speaker 1>Cool psychological trick. Okay, So after that, how do you

357
00:17:49.640 --> 00:17:51.759
<v Speaker 1>actually start extracting pieces.

358
00:17:51.640 --> 00:17:55.480
<v Speaker 2>Then you've basically got two main approaches. For the refactoring itself.

359
00:17:55.680 --> 00:17:58.519
<v Speaker 2>You can do bottom up extraction. Bottom up, yeah, you

360
00:17:58.559 --> 00:18:02.400
<v Speaker 2>analyze the existing code looking for cohesive chunks, maybe groups

361
00:18:02.400 --> 00:18:05.680
<v Speaker 2>of models that always work together, specific controllers and views

362
00:18:05.680 --> 00:18:09.359
<v Speaker 2>for one feature, files within a certain subfolder, or classes

363
00:18:09.400 --> 00:18:12.720
<v Speaker 2>sharing a common inheritance. You find these self contained parts

364
00:18:12.720 --> 00:18:15.359
<v Speaker 2>and pull them out into a component. The book uses

365
00:18:15.400 --> 00:18:18.359
<v Speaker 2>extracting a predictor domain gem as an example of this.

366
00:18:18.599 --> 00:18:21.799
<v Speaker 1>Okay, finding natural clusters in the existing code. What's the

367
00:18:21.880 --> 00:18:22.240
<v Speaker 1>other way?

368
00:18:22.440 --> 00:18:25.599
<v Speaker 2>The other way is pop down extraction. Here you start

369
00:18:25.759 --> 00:18:27.960
<v Speaker 2>not by looking at the code structure, but by thinking

370
00:18:28.000 --> 00:18:30.559
<v Speaker 2>about the application's domain or its users.

371
00:18:30.880 --> 00:18:32.519
<v Speaker 1>Domain driven kind of exactly.

372
00:18:33.079 --> 00:18:36.960
<v Speaker 2>You identify logical boundaries based on your understanding of the business. Okay,

373
00:18:37.000 --> 00:18:39.839
<v Speaker 2>this whole section deals with managing teams or maybe based

374
00:18:39.880 --> 00:18:43.160
<v Speaker 2>on user roles. This is the team's admin interface. This

375
00:18:43.279 --> 00:18:45.839
<v Speaker 2>is the game's admin stuff. This is the public prediction UI.

376
00:18:46.359 --> 00:18:50.279
<v Speaker 2>You define the component boundaries conceptually first, then pull the

377
00:18:50.319 --> 00:18:51.759
<v Speaker 2>relevant code into.

378
00:18:51.519 --> 00:18:54.599
<v Speaker 1>Them right top down, based on domain, bottom up, based

379
00:18:54.640 --> 00:18:59.000
<v Speaker 1>on code cohesion. What are some common roadblocks or challenges

380
00:18:59.039 --> 00:19:01.680
<v Speaker 1>people hit when they are doing this refactoring? It sounds

381
00:19:01.680 --> 00:19:04.599
<v Speaker 1>like you could easily break things or introduce new problems.

382
00:19:04.680 --> 00:19:07.599
<v Speaker 2>Oh definitely. One common one, especially as you pull out

383
00:19:07.720 --> 00:19:11.319
<v Speaker 2>UI related components, is running into what feel like seemingly

384
00:19:11.480 --> 00:19:13.240
<v Speaker 2>necessary circular dependencies.

385
00:19:13.400 --> 00:19:15.519
<v Speaker 1>Ah, the dreaded cycles again, like.

386
00:19:15.440 --> 00:19:18.599
<v Speaker 2>What global navigation is a classic example. Your main application

387
00:19:18.720 --> 00:19:21.759
<v Speaker 2>layout needs to generate links to paths defined inside your

388
00:19:21.799 --> 00:19:25.119
<v Speaker 2>newly extracted games admin component. Right yeah, but that games

389
00:19:25.119 --> 00:19:28.119
<v Speaker 2>admin component might also need access to something from the

390
00:19:28.160 --> 00:19:30.680
<v Speaker 2>main app or another component, creating a cycle.

391
00:19:30.880 --> 00:19:32.119
<v Speaker 1>So how do you break that cycle?

392
00:19:32.359 --> 00:19:36.400
<v Speaker 2>The book shows a couple ways. You could crudely hardcode

393
00:19:36.440 --> 00:19:40.119
<v Speaker 2>the paths in the main layout. Not ideal. Now, A

394
00:19:40.160 --> 00:19:44.440
<v Speaker 2>more elegant solution is to create an explicit contract. The

395
00:19:44.480 --> 00:19:48.720
<v Speaker 2>game's admin component itself provides its necessary navigation entry point.

396
00:19:49.000 --> 00:19:51.400
<v Speaker 2>Maybe it has a class method like self dot naventry

397
00:19:51.400 --> 00:19:54.279
<v Speaker 2>that returns the path and label. The main layout just

398
00:19:54.400 --> 00:19:57.039
<v Speaker 2>asks each UI component for its entry.

399
00:19:57.079 --> 00:19:59.960
<v Speaker 1>Ah and version of control. Basically, yeah, the component tells

400
00:20:00.079 --> 00:20:01.920
<v Speaker 1>the layout how to link to it precisely.

401
00:20:02.160 --> 00:20:05.279
<v Speaker 2>Another big challenge, of course, is just keeping the tests passing.

402
00:20:05.359 --> 00:20:08.680
<v Speaker 2>At each step, you make a small extraction, run the tests,

403
00:20:09.039 --> 00:20:12.279
<v Speaker 2>make another run the tests. Ideally, the book notes you

404
00:20:12.319 --> 00:20:15.880
<v Speaker 2>get separation of concerns reflected in broken tests, meaning when

405
00:20:15.920 --> 00:20:19.480
<v Speaker 2>you extract a component, ideally only tests directly related to

406
00:20:19.519 --> 00:20:23.759
<v Speaker 2>that component or its immediate dependence should break. If everything breaks,

407
00:20:23.920 --> 00:20:26.000
<v Speaker 2>your extraction probably wasn't clean enough.

408
00:20:26.079 --> 00:20:28.839
<v Speaker 1>Right, tests become your guide. The book uses the phrase

409
00:20:28.880 --> 00:20:32.039
<v Speaker 1>slippery slope when talking about extraction. Is that mends a

410
00:20:32.079 --> 00:20:33.079
<v Speaker 1>warning or ah huh?

411
00:20:33.119 --> 00:20:34.960
<v Speaker 2>No, it's actually framed as a slippery slope of.

412
00:20:34.960 --> 00:20:36.720
<v Speaker 1>A good kind, the good slippery slope.

413
00:20:36.880 --> 00:20:40.960
<v Speaker 2>Yeah. Stephen Wisely says it never hurts to extract too much.

414
00:20:41.039 --> 00:20:43.720
<v Speaker 2>It will always teach something, and it is always reversible.

415
00:20:44.319 --> 00:20:47.480
<v Speaker 2>The idea is, once you extract one component, it often

416
00:20:47.480 --> 00:20:50.920
<v Speaker 2>makes the next potential extraction much clearer. You start sliding

417
00:20:50.960 --> 00:20:54.160
<v Speaker 2>down this path of increasing modularity, and that's a good thing.

418
00:20:54.759 --> 00:20:56.720
<v Speaker 1>Okay, don't be afraid to extract. You can always put

419
00:20:56.720 --> 00:20:59.480
<v Speaker 1>it back. What about renaming components? We talked about starting

420
00:20:59.480 --> 00:21:02.160
<v Speaker 1>with app come How important is getting the names right?

421
00:21:02.200 --> 00:21:04.400
<v Speaker 1>Eventually seems like just changing names?

422
00:21:04.440 --> 00:21:07.319
<v Speaker 2>Oh, it's huge. The book calls renaming arguably the most

423
00:21:07.359 --> 00:21:08.839
<v Speaker 2>important refactor of them all.

424
00:21:08.960 --> 00:21:10.559
<v Speaker 1>Really most important.

425
00:21:10.640 --> 00:21:15.039
<v Speaker 2>Yeah, aligning a component's name, changing that vague app component

426
00:21:15.119 --> 00:21:18.599
<v Speaker 2>to a specific WebUI or reporting engine with its actual

427
00:21:18.640 --> 00:21:23.079
<v Speaker 2>discovered function is absolutely paramount. It's key to maintaining that

428
00:21:23.119 --> 00:21:26.240
<v Speaker 2>clarity and ensuring the architecture keeps screaming its intent.

429
00:21:26.559 --> 00:21:28.759
<v Speaker 1>So the name is the communication exactly.

430
00:21:28.839 --> 00:21:32.960
<v Speaker 2>It involves mechanical work sure, renaming folders, files, class names,

431
00:21:33.000 --> 00:21:36.839
<v Speaker 2>module references, but it's critical and luckily there are tools

432
00:21:36.920 --> 00:21:39.279
<v Speaker 2>like the Kleebray tools Jim mentioned in the book that

433
00:21:39.319 --> 00:21:41.200
<v Speaker 2>can help automate a lot of that grutwork.

434
00:21:41.519 --> 00:21:45.759
<v Speaker 1>Right tooling helps. Are there other common refactoring patterns besides

435
00:21:45.920 --> 00:21:48.039
<v Speaker 1>just extracting and renaming, Yeah.

436
00:21:47.920 --> 00:21:50.920
<v Speaker 2>The book mentions a few others. Splitting a component if

437
00:21:50.960 --> 00:21:54.920
<v Speaker 2>you realize it's actually doing two unrelated things. Creating dedicated

438
00:21:54.960 --> 00:21:57.359
<v Speaker 2>API components if you need separate back ends for a

439
00:21:57.359 --> 00:22:01.440
<v Speaker 2>WebUI and a public API. Creating third party service.

440
00:22:01.119 --> 00:22:04.839
<v Speaker 1>Adapters Adapters like wrapping external gems exactly.

441
00:22:05.000 --> 00:22:08.400
<v Speaker 2>Say you use brain tree for payments. Instead of scattering

442
00:22:08.440 --> 00:22:10.799
<v Speaker 2>brain Tree calls all over your app, you create a

443
00:22:10.839 --> 00:22:14.279
<v Speaker 2>brain Tree adapter component. It wraps the brain Tree gem,

444
00:22:14.480 --> 00:22:18.039
<v Speaker 2>exposes only the specific functions your app needs, and becomes

445
00:22:18.039 --> 00:22:21.400
<v Speaker 2>the single point of interaction. This reduces coupling to the

446
00:22:21.400 --> 00:22:23.759
<v Speaker 2>third party service and makes it easier to swap out

447
00:22:23.839 --> 00:22:24.559
<v Speaker 2>later if needed.

448
00:22:24.680 --> 00:22:27.519
<v Speaker 1>Smart isolating external dependencies.

449
00:22:26.880 --> 00:22:30.480
<v Speaker 2>And also creating common functionality components, maybe pulling out something

450
00:22:30.559 --> 00:22:33.559
<v Speaker 2>like a soft deletable concern or shared UI elements into

451
00:22:33.559 --> 00:22:35.240
<v Speaker 2>their own, small, reusable component.

452
00:22:35.359 --> 00:22:39.000
<v Speaker 1>Okay, so for those really big, scary, leazy balls of mud, Yeah,

453
00:22:39.079 --> 00:22:42.200
<v Speaker 1>is it always best to take these small incremental extraction

454
00:22:42.319 --> 00:22:45.000
<v Speaker 1>steps or is there ever a case for doing something

455
00:22:45.039 --> 00:22:45.839
<v Speaker 1>more drastic?

456
00:22:46.200 --> 00:22:50.079
<v Speaker 2>Interestingly, yes, the book suggests that sometimes the best approach

457
00:22:50.160 --> 00:22:52.079
<v Speaker 2>is to take one big step.

458
00:22:52.279 --> 00:22:55.319
<v Speaker 1>One big step sounds risky, it.

459
00:22:55.319 --> 00:22:57.839
<v Speaker 2>Sounds kind of crazy, right. The idea is you move

460
00:22:57.880 --> 00:23:01.119
<v Speaker 2>almost all the existing applications core a lot. Often most

461
00:23:01.559 --> 00:23:06.920
<v Speaker 2>models services anything tightly coupled into one single massive component

462
00:23:07.119 --> 00:23:07.799
<v Speaker 2>right at the start.

463
00:23:07.839 --> 00:23:11.039
<v Speaker 1>Wait, so you're just moving the entire mess into a

464
00:23:11.079 --> 00:23:14.359
<v Speaker 1>component folder. How does that help? Isn't that just creating

465
00:23:14.440 --> 00:23:15.519
<v Speaker 1>a worse application?

466
00:23:15.759 --> 00:23:18.640
<v Speaker 2>Like the book says, it feels like you're making it worse. Initially,

467
00:23:18.640 --> 00:23:20.640
<v Speaker 2>you start with one ball of mud, and now you

468
00:23:20.720 --> 00:23:23.640
<v Speaker 2>have maybe the thin rail shell and one slightly smaller

469
00:23:23.680 --> 00:23:26.599
<v Speaker 2>but still messy ball of mud inside a component. But

470
00:23:26.640 --> 00:23:29.119
<v Speaker 2>there's a real method to this madness. By doing that

471
00:23:29.160 --> 00:23:32.240
<v Speaker 2>big move, you immediately expose all that legacy code to

472
00:23:32.559 --> 00:23:35.640
<v Speaker 2>all the component based refactoring techniques we just discussed.

473
00:23:36.279 --> 00:23:38.240
<v Speaker 1>Because now it's inside a component.

474
00:23:37.880 --> 00:23:41.599
<v Speaker 2>Boundary exactly, you can now start applying those bottom up,

475
00:23:41.599 --> 00:23:45.279
<v Speaker 2>top down extractions, creating impactors splitting things within that big

476
00:23:45.319 --> 00:23:47.960
<v Speaker 2>component much more easily than when it was all tangled

477
00:23:48.039 --> 00:23:50.599
<v Speaker 2>up in the main rails app structure. It allows for

478
00:23:50.640 --> 00:23:54.240
<v Speaker 2>a much broader transformation to happen much more quickly than

479
00:23:54.240 --> 00:23:57.240
<v Speaker 2>trying to chip away with tiny extractions from the outside.

480
00:23:57.759 --> 00:24:01.240
<v Speaker 2>You instantly separate the framework concerns from the application core,

481
00:24:01.799 --> 00:24:04.960
<v Speaker 2>even if that core is still messy. It's a powerful kickstart.

482
00:24:05.599 --> 00:24:08.960
<v Speaker 1>Wow. Okay, that's counterintuitive but makes sense. You move the

483
00:24:09.000 --> 00:24:11.240
<v Speaker 1>mess to make it possible to clean the mess using

484
00:24:11.319 --> 00:24:15.519
<v Speaker 1>the new tools. Okay, So how does this CBRA approach

485
00:24:15.640 --> 00:24:18.880
<v Speaker 1>relate to other architectural patterns people might already be familiar with.

486
00:24:19.119 --> 00:24:22.519
<v Speaker 1>Does it replace things like say hexagonal architecture or domain

487
00:24:22.559 --> 00:24:24.559
<v Speaker 1>driven design or does it work with them?

488
00:24:24.839 --> 00:24:27.839
<v Speaker 2>That's a great question. It absolutely complements them, often by

489
00:24:27.839 --> 00:24:30.720
<v Speaker 2>adding a layer of rigor and enforcement. So with exxagle,

490
00:24:30.759 --> 00:24:34.039
<v Speaker 2>for instance, well hexagonal architecture or reports and adapters, it's

491
00:24:34.039 --> 00:24:37.519
<v Speaker 2>all about separating your core business logic from external concerns.

492
00:24:37.759 --> 00:24:40.839
<v Speaker 2>The database, the UI, third party APIs.

493
00:24:40.480 --> 00:24:41.960
<v Speaker 1>Right the core versus the shell.

494
00:24:42.279 --> 00:24:46.279
<v Speaker 2>CBRA helps enforce that separation by putting your core domain

495
00:24:46.319 --> 00:24:50.319
<v Speaker 2>logic into components with explicit dependencies, and your adapters like

496
00:24:50.519 --> 00:24:54.319
<v Speaker 2>UY or database access into other components. CBRA makes those

497
00:24:54.319 --> 00:24:57.319
<v Speaker 2>boundaries concrete and helps ensure the dependencies flow in the

498
00:24:57.359 --> 00:25:00.440
<v Speaker 2>right direction. The shell depends on the core or not

499
00:25:00.559 --> 00:25:04.079
<v Speaker 2>the other way around. The book shows how CBRA enforces

500
00:25:04.119 --> 00:25:05.880
<v Speaker 2>that directionality of the dependence.

501
00:25:06.200 --> 00:25:10.200
<v Speaker 1>Okay, so it makes the hexagonal boundaries physically real in

502
00:25:10.240 --> 00:25:14.480
<v Speaker 1>the codebase. What about something like DCI Data Context Interaction.

503
00:25:15.240 --> 00:25:19.200
<v Speaker 2>Yeah, DCI is more focused on modeling object interactions dynamically,

504
00:25:19.279 --> 00:25:22.279
<v Speaker 2>how objects play different roles within specific context to carry

505
00:25:22.279 --> 00:25:25.880
<v Speaker 2>out interactions or use cases. CBIRA can help here by

506
00:25:25.920 --> 00:25:28.799
<v Speaker 2>providing a place to actually put those DCI constructs. You

507
00:25:28.839 --> 00:25:32.279
<v Speaker 2>could potentially have components representing specific context or containing the

508
00:25:32.359 --> 00:25:35.480
<v Speaker 2>role definitions relevant to a certain part of the domain. Again,

509
00:25:35.559 --> 00:25:38.880
<v Speaker 2>it helps make those potentially abstract DCI concepts first level

510
00:25:38.920 --> 00:25:42.640
<v Speaker 2>citizens in the codebase with explicit boundaries and dependencies between them.

511
00:25:42.680 --> 00:25:45.960
<v Speaker 1>It at structure, so it provides the structural backbone for

512
00:25:46.039 --> 00:25:49.599
<v Speaker 1>these other patterns. Cool. Now, let's zoom out. If you're

513
00:25:49.599 --> 00:25:52.039
<v Speaker 1>listening to this and you're not a rails developer, maybe

514
00:25:52.079 --> 00:25:54.880
<v Speaker 1>you're building apps with Python and Django, or Java with

515
00:25:54.960 --> 00:25:59.640
<v Speaker 1>Spring or dot Net. Is this deep dive still relevant?

516
00:26:00.039 --> 00:26:02.240
<v Speaker 1>Where is CDRA really just a Rails thing?

517
00:26:02.440 --> 00:26:04.799
<v Speaker 2>No? Absolutely relevant. This is one of the most compelling

518
00:26:04.839 --> 00:26:08.680
<v Speaker 2>parts of the book. Actually, Stefan explicitly shows how this

519
00:26:09.200 --> 00:26:13.400
<v Speaker 2>component based development philosophy translates beautifully to other languages and frameworks.

520
00:26:13.519 --> 00:26:14.720
<v Speaker 1>Oh really, He shows examples.

521
00:26:14.880 --> 00:26:18.359
<v Speaker 2>Yeah, there are concrete examples showing project structures in Cottland,

522
00:26:18.400 --> 00:26:22.480
<v Speaker 2>Java using gradal and in dot nettischep that look remarkably

523
00:26:22.519 --> 00:26:24.880
<v Speaker 2>similar to the rail's CBRE structure.

524
00:26:24.960 --> 00:26:25.200
<v Speaker 1>Wow.

525
00:26:25.359 --> 00:26:28.200
<v Speaker 2>What's fascinating, as he points out, is that you look

526
00:26:28.440 --> 00:26:31.680
<v Speaker 2>not for language syntax, but for application structure, the way

527
00:26:31.720 --> 00:26:35.359
<v Speaker 2>dependencies are managed, the way modules or packages are organized,

528
00:26:35.680 --> 00:26:39.559
<v Speaker 2>the separation of concerns. The patterns are incredibly consistent across

529
00:26:39.599 --> 00:26:40.680
<v Speaker 2>these different textacs.

530
00:26:40.799 --> 00:26:43.279
<v Speaker 1>So the underlying principles are universal totally.

531
00:26:43.759 --> 00:26:49.400
<v Speaker 2>The core ideas of clear responsibility, explicit non cyclic dependencies,

532
00:26:49.920 --> 00:26:55.960
<v Speaker 2>managing complexity through modularity. These aren't Rail specific problems or

533
00:26:55.960 --> 00:26:59.920
<v Speaker 2>solutions they apply pretty much everywhere you build large software system.

534
00:27:00.599 --> 00:27:04.920
<v Speaker 2>The problems of complexity and maintainability are shared, and componentization

535
00:27:05.079 --> 00:27:08.559
<v Speaker 2>offers a consistent, powerful way to tackle them, regardless of

536
00:27:08.559 --> 00:27:09.519
<v Speaker 2>your specific tools.

537
00:27:09.599 --> 00:27:12.720
<v Speaker 1>That's really encouraging. So this deep dive has definitely shown

538
00:27:12.759 --> 00:27:16.200
<v Speaker 1>us that component based rails or component based architecture in

539
00:27:16.240 --> 00:27:18.799
<v Speaker 1>general isn't just some technical trick. It's really more of

540
00:27:18.839 --> 00:27:21.599
<v Speaker 1>a philosophy. Isn't it a way to manage complexity and

541
00:27:21.759 --> 00:27:22.599
<v Speaker 1>large projects?

542
00:27:22.680 --> 00:27:23.160
<v Speaker 2>Hidixel?

543
00:27:23.279 --> 00:27:27.759
<v Speaker 1>Yeah, turning that potential ball of mud into something well structured, understandable,

544
00:27:28.039 --> 00:27:31.559
<v Speaker 1>and crucially maintainable over the long haul. It's about regaining

545
00:27:31.599 --> 00:27:33.079
<v Speaker 1>control and clarity.

546
00:27:33.240 --> 00:27:36.119
<v Speaker 2>Indeed, and as a saying goes, knowledge is most valuable

547
00:27:36.160 --> 00:27:39.400
<v Speaker 2>when it's understood and actually applied. By consciously breaking down

548
00:27:39.440 --> 00:27:43.279
<v Speaker 2>your application into these explicit, well defined components, you really

549
00:27:43.279 --> 00:27:45.480
<v Speaker 2>do gain a level of control and clarity that pays

550
00:27:45.640 --> 00:27:48.519
<v Speaker 2>huge dividends down the road. It makes your systems more resilient,

551
00:27:48.559 --> 00:27:50.519
<v Speaker 2>easier to reason about, easier to evolve.

552
00:27:50.759 --> 00:27:52.920
<v Speaker 1>So the provocative thought for you listening, what does this

553
00:27:52.960 --> 00:27:56.279
<v Speaker 1>all mean for your projects? The next time you encounter

554
00:27:56.359 --> 00:27:58.839
<v Speaker 1>a sprawling code based maybe when you're working on right now,

555
00:27:59.200 --> 00:28:02.920
<v Speaker 1>instead of just feeling overwhelmed, ask yourself this, How much

556
00:28:02.960 --> 00:28:07.640
<v Speaker 1>clearer would its intent be if it truly screamed its domain,

557
00:28:07.880 --> 00:28:12.440
<v Speaker 1>not just its framework. Could components help reveal that core purpose?

558
00:28:12.680 --> 00:28:15.480
<v Speaker 2>Yeah, it's a powerful question to reflect on, and obviously

559
00:28:16.000 --> 00:28:18.640
<v Speaker 2>this deep dive is just scratching the surface. We really

560
00:28:18.759 --> 00:28:21.880
<v Speaker 2>encourage you to check out Stefan Hageman's book and explore

561
00:28:21.920 --> 00:28:24.559
<v Speaker 2>how these ideas might transform the way you build and

562
00:28:24.599 --> 00:28:27.240
<v Speaker 2>maintain your own applications. There's a lot more detail and

563
00:28:27.319 --> 00:28:28.480
<v Speaker 2>practical advice in there.
