The video offers a pragmatic framework for prioritizing abstraction over implementation to ensure long-term code maintainability. It is a vital reminder that the most durable software is designed in the mind before it is ever written in the editor.
Deep Dive
Voraussetzung
- Keine Daten verfügbar.
Nächste Schritte
- Keine Daten verfügbar.
Deep Dive
How to build understandable programsHinzugefügt:
Hey folks, I just want to show you some techniques I use to build understandable programs. I'll demonstrate by making a tic-tac-toe game in three separate phases. Phases one and two is the 3x3 case and phase three extends the board uh to end by end. This might seem simple, but there's some hidden complexities that will throw you off if you're not careful. Uh so first I'm going to show the wrong way to build which is going to lead to a mess and that's just coding without planning ahead or thinking about the program structure. And then I'm going to show the right approach. So let's start with phase one. I've got some starter code over here. Uh and the instructions are on uh the right and we have to implement these three methods. Uh we don't have to check for winners uh or anything. This phase is um fairly straightforward. So uh I'm just going to implement it. All right. Uh here's the implementation. I'm going to run the test cases and uh it passes. So now moving on to phase two. Here's phase two uh where we have to set the game status. So let's add a status here. Uh status uh to ongoing. And then let's put the status over here.
Now let's update uh this make move function. And this is the part that will get you if you're not planning ahead. So we first have to check uh if there's a row winner.
And so we have to iterate the rows. And so we need a we need a for loop for R in range three. And then we might do something like this. So we first check uh if if the board um or the first position uh is occupied and then if it is occupied we just check if the next three positions um are uh equal. So if and if they are equal and that means there's a winner on this row. So we just set the status.
All right. So now we've checked the rows, but we also have to check the columns. So, so we're just going to we might like copy paste this loop and then change this to a C. Change B over here. Put C over here. Put C over here.
And this checks the column. But now we have two for loops in our function and some nesting.
But now we have to check if there's a winner on the diagonal and the anti-diagonal. And then we also have to check if there's a draw. So more loops, more if statements. And uh I'm just going to go and add them. All right, here it is. This this part checks if there's a winner on the diagonal. This part checks if there's a winner on the anti-dagonal. And this part checks uh for a draw. Uh now if you look at this function it's uh it's a bit of a mess. There's a bunch of loops. There's a bunch of nesting. It's not readable. It's not testable. If you were to test like any individual like part like let's say you wanted to test like the row uh checking functionality in isolation. It's it's you can't really do it. It's kind of hard. And maybe it works, maybe it doesn't. If it doesn't work then um you know you're going to have a hard time like figuring out where things went wrong. If it does work, uh, I wouldn't feel like confident going to the next phase because like modifications might break stuff and debugging is a bit of a pain. So, let's delete this and rewrite it the right way. The right approach is not to write any code initially. Don't don't think about implementation details. Don't think about if statements, for loops, variables, etc. Just try to understand at a high level what this function is supposed to do. Write a note. So first and let me just uh write that down. Uh oops.
So first uh we got to check if the move is valid. Check if move is valid and if it's valid then we make the move.
We set the next status and then we set the next player. Now this doesn't have to be uh very detailed. It just needs to make sense at a high level. Uh and so like now we can like write some pseudo code. So um if uh you know can move uh then we move and then we set the next status we set the next player.
This kind of looks like real code. Uh in fact it is real code. If we have these functions we're just delegating the logic to these. Uh so the next step is to determine like each function signature and whether they should be in the class. The right way to think about classes is uh as state machines. We want to make them as simple as possible. So if the function is only used internally and doesn't update state, uh just put outside the class. Uh so this this cam move function uh for example, it should just take uh as input the board uh the row, the column, the status and return like uh true only if we can make a move.
It doesn't modify any state. So it shouldn't be part of the class. And let's give the board the row, the column uh and the uh status. Uh and then this move function uh well this move function modifies the board. So it should be inside the class. Uh and uh it should take as input the row uh sorry and the column not int. So let's give it the row and the column. And at this point like you can already kind of like like tell like how how like to implement like can move uh and also move like can move um it's just going to return true if the given position is empty and the status is ongoing. uh and move is just going to uh set uh position roll call to uh the player and like next status should also be uh inside the class and it shouldn't take uh as input uh anything because all it needs to do all it needs is really just these three things. Um in fact it probably just needs the board uh and the status but we're not going to implement this yet. Uh and the next player uh also doesn't take uh any inputs. It really just needs uh this variable right here.
player just sets it to uh X uh if the player is O. Otherwise, it sets it to uh to O. Notice it's clear what this make move make move function is doing uh just by reading uh the code uh you know it's pretty much uh that this note right here. Um and that's what uh clean code is. It's it should read like English. Uh so I'm just going to delete this uh right here. Uh and and now like at this point we can implement these functions in in um in any order. I think I'm going to implement the cam move, the move, uh, and the next player because those are pretty easy. They're like just oneliners. Uh, so let me go ahead and, uh, and implement those. All right, here are the implementations.
Uh, this one, this one, and now we have to implement the uh, next status uh, function. This one's more involved. So we got to think high level first. What does this function do?
Uh, so let's write this down.
Uh so we first check uh for a winner in the row columns diagonals and antidagonals. So check for winner in the rows calls uh diagonals and anti-dagonals and if there is a winner then set a victory status.
uh and then um uh if there is a draw then uh set the draw status uh otherwise do nothing. We also have to make assumptions about the conditions under which a function is called like this function uh should only be called uh if a move can be made uh which requires the status to be uh ongoing. Um so if there's no winner or uh draw uh then uh we can expect the game to be ongoing. So we don't have to modify anything. Uh now again write the pseudo code. Um W is equal to roll winner uh or call winner or diag winner or anti-diag winner. Uh and then if uh there's uh a winner then the status uh you know is just going to be I guess like here we're not completely writing pseudo code uh but let's continue. So if draw then uh self.status status uh is equal to draw.
So this code uh is fairly understandable. It reads exactly like our description. Uh in fact, it might even be more understandable than the description itself. So let me delete uh the description. Uh and we didn't even think about the implementation details.
We were just thinking like high level, but all of a sudden like the implementation just kind of appeared.
And this is why it's so important to think in terms of interfaces. Um and so like another note is that we're delegating a lot of the work uh to these like to these winner functions. Um and also the draw function uh right here. So if these are correctly implemented then the function should also be correct. It's like if the previous steps are correct and the way you stitch them together is correct then the current step uh is correct. So now let's uh think about the uh signatures uh and whether each uh function should belong in the class or not. Uh so none of these like really modify like state um they should just take in a board and then return something. So these winner functions they should just take in a board and then return a winner. So like x or o if there is one otherwise they shouldn't return anything. Uh and then this draw should just return uh true uh if it's a draw and otherwise they shouldn't return anything. So let's uh give each of them the board.
Now we've broken our program down into subcomponents. It's a lot more understandable. Uh we could even get the AI to like generate these uh or like this. Uh in fact, if I wasn't recording, uh I I just get like the AI to generate everything after breaking it down um into interfaces. Uh and if you're building like production software, this is what you need to do. Break the program down into subcomponents. Figure out how they work. figure out how they interact together and then implement them. Each component should only have one responsibility. Uh, and you can implement like like the components yourself or or get AI to do it or get someone else to do it. It doesn't really matter as long as it obeys the interface. Uh, so I'm just going to go ahead and um and implement uh these.
All right, I've implemented them. Uh, and everything is now testable. Uh, like if you want to test the rowing function, so this one right here, uh, then you don't need to instantiate the class. If you don't need to make a bunch of moves, you can test it in isolation now. Uh so all you have to do is just call this uh uh row winner with some board. So let's do that. So um write the results row winner. Uh what kind of board do we want to give it? Let's do this X.
And let's just make everything empty for now.
And let's print the result. And let's run this.
And now we don't get anything as expected because there's no winner. Now let's add a winner. And there's X. Uh now maybe um two rows of winners. Uh okay. And let's change this to O. Uh and let's not let's do this. And there's O.
So uh yeah. So this works. Uh and now um I'm going to run uh or or rather I should say that um you can test like all these other functions like down below in isolation. um you just kind of like call it on some like sample boards. Uh but I'm going to delete this. Now I'm going to run the test cases and everything checks out. Now we have a modular program. We're comfortable moving on to the last phase uh which will require us to add support for variable uh board sizes.
Um and I've collapsed all these functions right here because uh whenever we uh make a modification uh we don't want to think about implementation details right away. You know that's just the pattern. We want to uh conceptually like understand what needs to change.
Again we're thinking high level. So like does does this need to change? Does like get game state? Not really. Does uh make move need to change? Uh no it doesn't.
What about next status? Uh well these functions definitely need to change and and so does the straw function. But uh this function itself doesn't need a change. None of these these two don't need a change either. This uh create game does need a change uh because we we need to give it uh this n right here.
Whoops. Uh got to give it n. We got to replace these three with ends. Uh and then this can't move doesn't really change, but like all of these um do need to change.
Uh so I'm just going to go ahead and like modify these. Uh actually I'll make this into a git repo and modify it so we can see the diff. Okay. Uh I've modified everything. Uh let's see the diff.
So instead of um like assuming 3x3 uh boards, these now work uh on uh the n byn case. Uh and I guess you don't have to worry like too much about the implementation uh details. You just need to know that these functions still obey uh the same interfaces which is um given a board they're they're just going to check uh like if there's uh winners uh or if there's a winner in the rows, columns, diagonals, anti-dagonals uh or if there's a draw. Uh it's just that the board can now be bigger. But if we scroll down um all that's changed uh over here is there's n and then this three now now became an n. Nothing else like everything else stayed the same. Uh so if the program is modular then making changes uh will be easy. it doesn't really impact the mental model and there shouldn't be any breakage. Uh but now let's run the tests and everything uh checks out. Um so that's it. That's that's going to be it for this project. Uh and this is basically like how you build um understandable like software. You first think conceptually. You lay out the components. You understand how they work and then you stitch them together. Don't start with the implementation. You got to plan ahead. Um and also like AI can like do the implementation once like everything is broken down. So it's really important that you develop your ability to think in terms of interfaces.
This is the mindset that will enable you to build systems at scale especially in the AI era. Uh but yeah, so that's going to be it for this video. Hope it helps.
Uh if you if you're interested in tech uh and you want to chat, please join my Discord. Uh links in the description below. I will see you next time.
Ähnliche Videos
Agentforce NOW AMA: Build with React and Salesforce Multi-Framework
SalesforceDevs
490 views•2026-05-28
How agent o11y differs from traditional o11y — Phil Hetzel, Braintrust
aiDotEngineer
450 views•2026-05-28
WEB TECHNOLOGIES UNIT-2 | Degree 4th sem BCOM Computers web technologies unit-2 full explanation💯✅
LearnwithSahera
1K views•2026-05-29
More tests are always better? How to use AI to identify tests that bring little value
Alliance4Qualification
335 views•2026-05-29
Search Algorithms Explained in 60 Seconds! 🤖💨
samarthtuliofficial
218 views•2026-06-01
People of Game of Thrones using JavaScript DOM
AltCampus
296 views•2026-05-30
Introduction to Problem Solving Part - 1 | Lecture 1 | Intermediate DSA
ascensionix
107 views•2026-05-29
So What's Odin Lang Even Good For
TechOverTea
131 views•2026-06-01











