Apprenticeship -- Days 7-10

December 7th, 2018

Week 2 - RubyMonk, pairing, and code deletion

This past week was quite enjoyable. I worked on my tic tac toe game, completed tutorials from RubyMonk, and paired with two other 8th Lighters.

Tic Tac Toe

My first assignment is a tic tac toe game in Ruby. I decided to make some planning notes. I started at a high level that considered the expectations of the assignment. This was really used to look at the game flow overall and user expectations during the game, such as seeing a board and having scores validated. After thinking about the requirements for the assignment and the game flow, I planned for three classes based on game flow: Board, Player, and PlayGame. Then I made a list of responsibilities for each class. Based on the responsibilities, I made a list of methods and their respective goals for each class. For example, the PlayGame class was basically the brain of the game, responsible for the game loop, initializing the board and players, determining whether or not to continue the game, and switching player turns. Some methods for PlayGame included: game_over? winner? draw?

I thought this planning would answer my questions about responsibilities and goals, but I started doubting these responsibilities. Should the winner be determined by the board or the player? Should the collection of player movements be kept by the board or the player? How would these classes be connected? What data would live in classes and how would it be accessible to other classes? I told another apprentice about these doubts and he said, "If you're brave enough to pair with someone this early on, I think it would really help!" I thought I was brave enough for a pairing. I reached out to see if anyone would be available and two people arranged some time to connect.

Pair Programming

Pair programming isn't a requirement for me yet, but everyone encourages pairing. I set up two separate sessions, one with an apprentice (Thomas) who had already completed the tic tac toe requirement, and one with an engineer (Cyrus) who is also one of the dedicated instructors for the apprentices.

Following Thomas' suggestion, I started the sessions by providing context of my assignment, discussing areas that I was currently working on, and describing my current roadblocks. From there we looked at the code and the tests. It was nice to talk things out with Thomas and just bounce different ideas of each other. Thomas said that my tests were great, but he challenged me to think about the internal representation of the board of if that data should be public or private. He mentioned that a class should be an abstractions of data and that data shouldn't be directly tampered with. Thanks to Thomas, I figured out that I was testing for functionality that hadn't yet been implemented.

My other session was with Cyrus. I "finished" writing the tests and code for the Board class before our session. Some of the methods were a little funky, but I thought it was a good start. At the start of my session with Cyrus, he looked at my work and asked that I delete everything. Um, okay. I thought I made some great progress over these past couple of days, but ... okay. I was hesitant at first, but after a few seconds of panic, I deleted everything. "And there is no need to worry, because you committed everything", he said. I told him that I hadn't even initialized a git repo yet, to which he replied, "Well, this is a great lesson in why you should commit your work". Ah...I wanted to cry and laugh at the same time, but I just got over it. He also suggested that I think about another approach to writing code. I was focused on planning all of my methods up front, then writing tests/code. He said that this approach was very close to waterfall programming, which is not effective and results in a ton of bugs. He suggested that I instead focus on the context of specific stories. His approach seemed to mirror standard client interactions, where you discuss upcoming features with a client and create specific stories to meet a specific end goal. Cyrus had a systematic approach, which included setup with git and continuous integration tools. So the main focus for our session was setting up a repo, allowing access to Travis CI, and creating a readme that included a status report from Travis CI. We also created a Board class that rendered the physical board. My initial Board only considered an array of strings that could be replaced by markers from players.

Overall

I met with my mentor, Byron, on Friday. We discussed my overall approach with this assignment and he brought up some points that I should think about going forward with the assignment. He first pointed out that there are broad design approaches to coding in general, including what's known as Top-down and Bottom-up. Top-down started with the big picture and then smaller elements based on how a user would perform actions. It seems like this approach would first be focused on the interface. The Bottom-up approach is based on the data that would be available for an application. This approach seems to be focused on data models and access flows, and finally thinking of how that access would be implemented through the interface. I realized that the approaches of each person I would pair with would have their prefered approach based on these two schools of thought. The keyword there is preference; there is no right or wrong approach, but I can learn to recognize these approaches and their values/tradeoffs.

Byron also challenged me to think about anti-patterns within OOP and the information that objects would send. He suggested that I make a map of classes and think about the communication that would take place among these classes. He said that making notes was a great start, but that my notes were too detailed and that my classes were not "dumb" enough. Classes only needed to know enough to do their own job. So we did a little white boarding to map out my classes and their respective responsibilities. This led to me realizing that my PlayGame class had too many goals and responsibilities. We started breaking down these goals into other classes. We also made a communication flow chart which showed where classes would get the information they needed to fulfill their roles. At the end of the session, I had four additional classes and the methods they would most likely need. I realized that, in my head, I had a user experience flow chart, but I hadn't thought about the communication flow between the classes. These were two separate things.

Wow, what an action-packed week! I really enjoyed how everyone was supportive throughout my pairing experiences. I learned about a continuous integration tool and how to connect it to GitHub. I also learned about two design approaches: Top-Down and Bottom-up. I plan to find some articles of these approaches. Next week I'll continue with my game by working on the Board (a fresh Board), RulesKeeper, and InputValidation classes.