Prática de Shadowing: DRY Often Makes Your Code Worse - Aprenda a falar inglês com vídeo

Criando lição...
1
Here's some example code for normalizing email addresses and usernames.
2
There's two functions here that do that job.
3
And I have a main function that has a bunch of email addresses and users and then normalizes them.
4
Winner on this, then this is what we get.
5
Now, obviously, this code has quite a bit of duplication, right?
6
If you take a look at these function bodies.
7
So, naturally, we should apply dry.
8
Don't repeat yourself and remove it.
9
Let's do that.
10
So first I'm going to create a new function called normalize strings.
11
And this is going to get a list of items.
12
And it will return a list of strings.
13
Now we just need to pass in the various options that control how these strings are being normalized.
14
So should there be an add symbol?
15
Is there a minimum length of the string?
16
And a couple of other things as well that we can all see from these two functions.
17
So let me paste that in here like so.
18
So these are all the options that we have.
19
Then inside the function we can create the result which will be a list of strings.
20
Initially that will be empty and in the end this is what we're going to return.
21
And then we can go over the items in the list of items.
22
And then for For example,
23
if strip white space, we're going to strip the item.
24
And if lowercase, we're going to turn it into lowercase.
25
And similarly, we can go through all of these different options
26
and do whatever we need to do in order to take care of those.
27
we're going to append the item to the result and then we can return it.
28
And now that we removed all of this nasty duplication, we can now replace these calls with our new function.
29
So instead of calling normalize email addresses, we can call normalize strings.
30
And then we just need to pass the email addresses.
31
So for an email address, the require at symbol needs to be there.
32
We also want to split the add symbol and we want to strip the mail prefix.
33
And that gives us our normalized emails.
34
Then I can do the same thing for usernames.
35
So also here, normalized strings.
36
And then I pass the usernames.
37
The minimum length should be 3.
38
There we go and we also want to remove the at prefix like so.
39
And now when I run this code again, we get exactly the same results.
40
So what happened here?
41
There's less duplication for sure.
42
I removed most of it, but the code has become way worse.
43
The behavior currently is impossible to understand.
44
There is all sorts of flags that interact in non-obvious ways.
45
Every new requirement now means that we need to add another parameter to this very generic function that doesn't repeat itself.
46
So I may have removed duplication, but I also turned the code into a hot mess.
47
So what actually happened here?
48
Now, before I show you what is actually the right way to refactor this,
49
what I've learned over the years is that it's not just important that you know how software design principles and patterns work.
50
It's also important that you understand the trade-offs that are behind them.
51
And that's exactly what I go deep into in software design mastery.
52
This is not just another course with patterns and principles.
53
It's a comprehensive system for thinking about architecture, boundaries, trade-offs, long-term maintainability.
54
If you want to become truly confident in your design decisions, join the waiting list at rnodecodes.mastery.
55
The link is also in the video description.
56
So what does this teach us about dry?
57
Well, don't repeat yourself doesn't mean that you should merge anything that looks similar into a one function.
58
It's actually more about not duplicating knowledge and knowledge in code is in things like data,
59
rules, business logic, those kinds of things.
60
Now in the battery factor that I just did I purely focused on how the code was shaped.
61
I looked at if statements for loops and things like that and then tried to remove all of that duplication.
62
If you want to improve code don't just blindly apply a principle like dry.
63
You actually need to understand the code.
64
So let's try this again but now let's focus on behavior and responsibilities.
65
So I just threw out the bad refactor that I did and I went back to the original code.
66
So this is again what it looks like.
67
Let's analyze what is happening here.
68
So first thing is that these normalized functions actually do two things.
69
One which is filtering.
70
For example here if there is not an ad in address it's simply not going to consider it.
71
But we see the same thing happening in the username.
72
So there is filtering and there is normalization.
73
Now if we don't focus too much on trying to remove all the duplication, we can actually start splitting out this logic more, which is what makes way more sense when you want to improve the code.
74
For example, for the filtering bit, we can use another function to check whether an email address is actually valid.
75
So let's say we have function isValidEmail.
76
Let's get some address.
77
And this is going to give us a boolean value that determines whether this address is actually valid.
78
And that is actually where we can use this check.
79
So here we're going to return that there is actually an add sign in the address.
80
And then now we can write it like this.
81
So now we moved some of the logic, and this is still pretty simple, but we moved some of logic outside of the function
82
which is nice and we can do the same thing for the usernames.
83
So here the length of the username should be more or equal than three like so.
84
But now that we've split out this logic, we can take a look at, for example, this function and see if we can focus the responsibility a bit more.
85
Because currently, this is responsible for checking that an email address is valid by calling this function.
86
It's responsible for looping through a list of addresses and then actually doing the normalization process.
87
So those are actually way too many responsibilities.
88
So let's split up the responsibilities.
89
And again, I'm not thinking about duplication at this moment.
90
I'm truly just thinking about how to organize this code better.
91
And if I have to write a few extra lines of code for that, I don't really care about it.
92
So instead of having this function that normalizes all the email address in the list and also checks whether emails are valid,
93
let's create another function called normalizeEmailAddress.
94
That does basically the normalization job for a single email address.
95
This normalizes the address and will return that as a string value.
96
So then we can basically take this part like so and I'll put it in here and then we can refactor that.
97
So this actually should not be part of email address normalization.
98
So the first step is removing whitespace and turning it into a lowercase.
99
Then we get the local part and the domain.
100
We remove the prefix from the domain and then we're simply going to return this as a result.
101
So this is our normalize email address function.
102
And now actually normalize email addresses can be very simple.
103
Because we don't need all of this complication here.
104
We can even make this a lot shorter and just use a list comprehension.
105
And there we check if the email address is valid.
106
So now we turn this complicated function into something that's way simpler.
107
And for usernames we can do the same thing.
108
So here I'm also simply copying this, putting it in here.
109
We don't need the valid check here.
110
And I can simply return this as a result.
111
don't need to store it here.
112
And then also here in normalized usernames I can simply use a list comprehension.
113
Like so.
114
Let's run this to check whether this still works as expected.
115
Now when you take a look at this version of the code actually I didn't remove all the duplication
116
because that wasn't the focus I didn't focus on trying to remove duplication
117
and actually there is still duplication in here like normalizing email
118
addresses well this code looks a lot like normalizing the usernames
119
except it calls slightly different functions now you could decide to abstract
120
that away and make like a filter and process function
121
or something like that if you really wanted to but honestly to me this isn't that bad that there is some duplication.
122
However I did remove the right duplication in the sense
123
that validation rules like these kind of checks are now in a single place
124
and normalization rules are also in a single place
125
because they're grouped in these functions now they're not all mixed up
126
and by doing this it means that our control flow stays simple
127
and still readable even though there is still some duplication
128
and actually in many cases having some duplication in code is good these loops
129
or list comprehensions I don't really mind
130
that they're duplicated it's they're pretty cheap it's not many lines of code it's easy to read
131
but more importantly duplication can sometimes help you enforce boundaries for
132
example you may also encounter duplication sometimes in your api right
133
you might have a database schema you might have an api output schema these are going to be very similar
134
so you might be tempted to use the same object for
135
that maybe if you're using sql model or something but that couples your API directly to your database, your persistent layer.
136
By keeping them separate you avoid leaking database concerns into your API
137
and it gives you flexibility to evolve each of these independently.
138
So there is some duplication in that case there but repeating yourself is actually protecting your design in that case.
139
So overall when you're working on code like this I'd say prefer duplication over the wrong way of abstracting things.
140
Look for duplicated rules not duplicated loops and try to fix those.
141
If you notice
142
that you need to add a bunch of flags in order
143
to remove the duplication from the code that's probably a red flag, pun intended.
144
So instead focus on truly understanding the code.
145
You'll be way better at organizing the code more effectively.
146
And what I typically do when I write code whether that's me
147
or some AI coding agent is
148
that I start writing I don't really think about how it looks I copy things around
149
when I need them but when I notice
150
that there is actually duplicated rules then I might abstract things away
151
so abstraction is a consequence of writing the code
152
and copying things around I don't start there
153
when using a tool like cloud code you can just let it write all the code
154
but then you do need to take that step of understanding the code
155
that it grows and seeing if you can abstract away a couple of things
156
and by the way
157
if you enjoy these types of design videos give a video
158
a like subscribe to the channel it helps me reach more people here on youtube
159
so finally dry don't repeat yourself is not a wrong principle
160
but it's really easy to misuse it's easy to think
161
that you should somehow not have any duplication in the logic That's not what it means.
162
The key thing is that you understand the code and
163
that you abstract away the right things so that they're properly separated and that knowledge, data, business logic is not duplicated in your code.
164
If you do it blindly, just start refactoring and moving things around, you'll often end up in a worse place.
165
You need to understand it and that leads to better abstractions.
166
But I'd like to hear what you think.
167
Do you apply the dry principle yourself to code?
168
Do you tend to over abstract things or do you tend to keep duplication around much longer?
169
Have you ever tried to refactor something removing duplication and it completely backfires?
170
Let me know in the comments.
171
Now, if you want to explore more software design videos, check out my design patterns playlist right here.
172
Thanks for watching and see you next time.

Sobre Esta Lição

Nesta prática de conversação em inglês, você terá a oportunidade de aprender como aplicar princípios de design de software, especificamente a ideia de não repetir o próprio código. Através de exemplos práticos de normalização de endereços de e-mail e nomes de usuário, você entenderá como simplificar o código enquanto mantém sua função original. A lição destacará o trade-off entre a redução da duplicação e a clareza do código, uma habilidade essencial não apenas para programadores, mas também para melhorar o raciocínio lógico e a comunicação em inglês.

Vocabulário e Frases Chave

  • normalizar - to normalize
  • duplicação - duplication
  • função principal - main function
  • símbolo @ - @ symbol
  • comprimento mínimo - minimum length
  • espaço em branco - white space
  • resultado - result
  • parâmetro - parameter

Dicas de Prática

Para melhorar a pronúncia em inglês e desenvolver suas habilidades de fala, recomenda-se a técnica de shadowing. Ao ouvir o conteúdo do vídeo, tente repetir imediatamente após ouvir. A fala rápida e direta do apresentador pode ser desafiadora, mas é essa dificuldade que ajudará na sua evolução. O objetivo do shadowspeak é imitar o tom e o ritmo do falante, então preste atenção não só nas palavras, mas na entonação e na cadência. Para maximizar sua prática de conversação em inglês, faça o seguinte:

  • Tente acompanhar o vídeo várias vezes, aumentando gradualmente a velocidade até o limite que você conseguir entender.
  • Utilize pausas estratégicas para repetir frases inteiras ou até mesmo parágrafos, assegurando que você capte a nuances do discurso.
  • Grave-se enquanto pratica shadowspeaks para que possa ouvir suas produções e identificar áreas de melhoria.

Lembre-se, a clareza na comunicação é fundamental, e a prática constante ajudará a transformar você em um comunicador mais eficaz em inglês. Boa sorte!

O que é a Técnica de Shadowing?

Shadowing é uma técnica de aprendizado de idiomas com base científica, originalmente desenvolvida para o treinamento de intérpretes profissionais. O método é simples, mas poderoso: você ouve áudio em inglês nativo e repete imediatamente em voz alta — como uma sombra seguindo o falante com 1-2 segundos de atraso. Pesquisas mostram melhora significativa na precisão da pronúncia, entonação, ritmo, sons conectados, compreensão auditiva e fluência na fala.