Registration date:
Post count: 32
My name's Stuart and this is my personal blog, I'll be recording what I learn at the Software Guild here.
All Posts
Edit Profile

Posts from this user

Managing Cognitive Load or: How I Learned to Stop Worrying and Love Unit Testing

tuzgai posted at

We just hit the one month mark in this course and I think I've identified the biggest issue my classmates are running into - managing cognitive load. When you're making an application of non-trivial size, there's a lot to keep track of! There's the overall architecture, the implementation of each component, the user experience and so on. I think that, much like [how we think we can multitask but can't really](https://hbr.org/2010/12/you-cant-multi-task-so-stop-tr), we think we can hold a whole large program in our heads, but can't in reality.

I've been helping a number of people in my class with their project and the common theme is that they're always jumping around through their code chasing bugs, changing the architecture on the fly and generally feeling chaotic and overwhelmed. This was me not too long ago! But now, I'm generally not too stressed about these projects. Part of this is definitely because I have a head start in programming experience, but I think a big part is that I've given up on holding the whole thing in my head and rely on tools to help me stay organized and focused.

Much like how object oriented programming allows for separation of concerns between modules of your codebase, diagramming and unit testing allow for separation of problem solving and writing code. When you only have to hold one relatively small part of the problem in your head, life is easier and you work faster and hit fewer bugs. This might not work for you, but it's been a huge deal for me - give it a try!

Diagramming Before I write a line of code, I step back and solve the problem on paper or in diagramming software. I sketch out the classes and methods I need and their relationships and if the user interaction is complicated I do a little flowchart to organize my thoughts. None of this is necessarily for anyone but me, but what it lets me do is work out what the overall problem is and the steps to solving it before I get tied down reading the docs for BigDecimal or whatever. Once my diagrams are done, I can move on to implementation and know that if I am ever unsure of how things are supposed to fit together, there's an easy reference nearby. I don't ever think "Ok, what needs to happen next?" because I can just look at my reference. This has saved me a lot of time and energy.

Unit Testing Unit testing works just like diagramming but on a method level. Here's a frequent workflow for writing a method I see in my classmates (and in myself before I learned unit testing two weeks ago ;)).

1. Write a void method signature with no inputs

2. Write part of an inner loop, then go back to add the relevant inputs for the method signature

3. Go back to the code that calls the method to look at what it needs to return, update that.

4. Fiddle with things until Netbeans doesn't have any red lines.

5. Write a tiny console interface to test the method by hand

6. Jump around between the previous steps fixing things until it seems to work. This is a chaotic approach and means that your method is never truly finished - there's always the chance that you hit a big either from the method being incorrectly written or from a mismatch between your understanding of its behavior and it's actual behavior. In contrast, here's a workflow with unit testing.

1. Determine the desired inputs and outputs for the method. You now understand the shape of the problem.

2. Write unit tests to match your understanding of the problem.

3. Write your code.

4. Run unit tests and fix your code until they all come back green.

This approach gives you the opportunity to think deeply and understand the problem at hand before trying to solve it. It also gives you an easy answer as to when you're done. Finally, you can move forward and write code that depends on the method with confidence. It's unlikely (depending on the quality of your tests) that the method will behave in an unexpected way - you have already proven to yourself through your tests that it works correctly.

tl;dr Embracing diagramming and unit tests has been like night and day for the way I write code. Where I once jumped around tackling whatever problem interested me first and chasing bugs as they arose, I now make a plan and execute it with dramatically fewer bugs and delays. As a bonus, I finish the day feeling fresher since I wasn't constantly straining trying to hold the whole project in my head. If you're learning to code and don't do these things, give them a try!

Last edited Permalink

Another update + dependency injection writing exercise

tuzgai posted at

Now that we've had some time back in the classroom I think the class is feeling a little better about things. It helps that the material this week is pretty light, so people have been able to focus on getting up to speed on their projects. I do have an anecdote to share:

Yesterday we were given a small group exercise where we used stream operations to determine whether a given hand of cards was a poker hand. We found the three of a kind pretty challenging, it didn't neatly fit into the methods we knew, even though we knew we could do it easily in a for loop. With my encouragement to not give up, we spent another 10-15 minutes reading up on the available stream operations and collectors and eventually found the groupingBy collector and worked out how to process the set it returned. I did this with a lot of hitting . in netbeans to look at options from the suggestions and googling javadocs.

At the end, one of the people in my group said "Huh, so research is really important?" and had an expression like he'd found a new superpower. It was really exciting to see that revelation and to help encourage him to not give up on problems but keep working away and researching solutions. I'm ahead in the class, so I'm glad that I can role model problem-solving techniques and help everyone push forward.

Anyway, here's my writing exercise on dependency injection:

Dependency injection is an encapsulation strategy that allows the various classes of a project to be initialized with their dependencies in the constructor with the parameters from an external source, rather than called directly from the class. This allows us to more easily manage dependencies and potentially swap them out as needed.

For example, when testing a component we can construct it with a stub dependency set up specifically for testing - this allows us to test our component independently of its dependencies. Another example is that we might want to develop our application with a simple file-based memory system and then switch to a database later. To achieve this, we will use the Spring framework's dependency injection capability. Essentially, we will declare all of our classes and the arguments to their constructors in an XML configuration file and call Spring to inject these dependencies into our app. This way, in our previous examples we can have a 'release' config, a 'testing' config and 'db' and 'file' configs rather than doing a bunch of work in code to manage these.

Last edited Permalink

Week 4 Update

tuzgai posted at

I'm starting to have more work to do in class and less time to blog, which is probably a good thing. But also, we've had sort of a weird week.

Last Tues-Thu were work from home days, as the weather in MN was far too cold for anyone to be outside. We had online meetings with our instructor twice each day, but much of the day was left for independent work (while the instructor was available via slack). While I personally have a lead and wasn't really hampered by the disruption, a number of my classmates are pretty worried that they didn't master the material on unit testing and the service layer as well as they might have otherwise.

To compound that, our instructor was out on planned leave again this Monday and we didn't get a sub. This means we had another day with more course material open to us but no instructor to help us review/work on the weekend project and another day of our precious 12 weeks mostly lost.

Tension was high in the classroom today! Most of the class is starting to fall behind and whether or not it had a big impact the number of disruptions giving people an excuse to point at is not helping them progress. Hopefully things will get back on course tomorrow. I do think that everyone has a good shot at success and as a class we're not as far behind as we feel, based on the new material that was just opened up.

But! I hear some people still haven't finished their week 1 and week 2 projects and worry that they're just not going to be in a position to finish the first 6 weeks in time to start the second 6 weeks. In the meantime I'll just keep doing my best to stay ahead and help my classmates if they have questions.

Last edited Permalink

Writing exercise: MVC

tuzgai posted at

As you might have noticed from my earlier posts, I had a headstart on this writing exercise.

The model-view-controller (MVC) pattern is a design patterns popular for managing CRUD (create-read-update-delete) applications. That is to say, it is useful for projects that involve viewing, editing and storing data. MVC allows for a clear *separation of concerns*. Each component handles just one category of task, which means that each layer can be coded and edited separately.

- The model consists of a number of data access objects (DAOs) and data transfer objects (DTOs). It is concerned entirely with storing and accessing data, whether it be just to internal memory or storage. The DTO is used to expose this data to the rest of the application, all layers can access it.

- The view handles user interface and nothing else. If the application needs to display information to the user or collect information from them, the view layer takes care of it.

- The controller is the brains of the operation, it directs program and data flow between the view and model. Where the view displays things and the model stores them, the controller says what to display and when to store things. Frequently in Java the view and model layers will be abstracted for the controller through interfaces.

This means that you can design your controller, model and view independently and as long as the model and view obey their respective interfaces, everything should work. This loose coupling is very useful when scaling your application, as many team members may be interacting with each layer and having everything mixed together would quickly become untenable.

While this pattern is useful for CRUD applications, it encounters limitations when you need to apply business logic to its interaction, as this logic doesn't cleanly fit into the model, view or controller. To support this logic, we use a service layer that sits between the model and controller. The service layer handles logic like validation of input data - when there's a service layer, the controller interacts with it instead of directly with the DAO. MVC is just one design pattern, but since most web applications are essentially about handling and displaying data it is very popular for that purpose. Most web frameworks are based on a variation of the MVC pattern.

Last edited Permalink

Day 10 Service Layer

tuzgai posted at

For our weekend project we re-implemented the code-along with a little extra - an edit feature. The project was to implement a text-based DVD collection that would add, remove, edit and store to a file (aka a CRUD app) using the MVC pattern. I'm pretty happy with how mine turned out - I made an extra little menu to display the data to be edited with options for how to edit it. My code review went well, I wasn't given any changes to make.

Service Layer For a CRUD (create, read, update, delete) app that just manages data, the MVC pattern works quite well. We have a dumb DAO that just manages data, a smart controller that runs the show and a UI that UIs. Many applications have more than just CRUD functionality through, they may need to apply business logic such as "no duplicates" or "give the 100th user a prize".

For this, where does the logic fit? Obviously not the UI. It sounds like too much work for the controller, which is supposed to just manage and not do work. Similarly the DAO is supposed to be dumb and fast, it shouldn't be doing all this logic. Enter the service layer. This new layer sits between the controller and the DAO to apply business logic.

With a service layer, the controller no longer has access to the DAO, it instead makes similar calls to the service layer. An important service layer tool is the service layer exception. These operate just like other exceptions, but let the controller know that there was a problem with the business logic of the proposed operation rather than a direct data problem or another runtime exception. The service layer can also do other validation, logging, etc functions. Anything that feels like it doesn't fit in the MVC layers probably fits in the service layer. To make this happen, the service layer frequently will interact with more than one DAO.

Last edited Permalink
Newer Posts Older Posts