Author Archives: jwblash

The Criticisms of Design Patterns

Design Patterns have grown to become a standard in the field of Software Development ever since the Gang of Four published their book, Design Patterns: Elements of Reusable Object-Oriented Software in 1994. However, some people in the field of Computer Science have leveled criticisms towards Design Patterns for a few reasons, even if it is widely accepted that they are tools in the belts of developers at this point.

A legitimate criticism of them seems to be that many of the patterns are heavily language dependent, as some languages have easier work arounds for problems that present themselves in others. Peter Norvig, a director of research at Google, showed that 16 of 23 patterns from the Design Patterns book can be replaced solely by implementing them in Lisp or Dylan rather than C++ (page 9 of this PDF). Part of the argument here is that if languages don’t have the same design patterns, then those languages that do have more design patterns are requiring that developers find work arounds for their missing features.

Another issue that many seem bring up is that the emphasis on using design patterns results in developers relying on them too heavily. Similar to the Golden Hammer AntiPattern, once a developer (or team of developers) becomes comfortable with a tool or concept they end up attempting to cram the problems they’re given into some implementation that would allow them to use the solution they’re comfortable with. In this way, even if Design Patterns are intended with the intention of writing code in good practice, if they’re implemented when it isn’t necessary it can quickly turn sour.

The idea behind Design Patterns is that, if they are used correctly alongside correct Object Oriented Design principles, the patterns should emerge naturally. If you ever find yourself asking, “How can I use the Singleton Pattern here?”, then you’re misusing the tool in your tool belt. They are better viewed as teaching methods for successfully upholding good design in complex situations, in a way. If you’re writing code and it dawns on you that what you’re attempting to write is similar to a pre-existing design pattern, then you have a direction to follow. This article in particular gives a great example of an application of the template pattern, and shows how you’d get there in a natural way as opposed to forcing a pattern on a piece of code. 

From the blog CS@Worcester – James Blash by jwblash and used with permission of the author. All other rights reserved by the author.

A Brief Look at Mocking

We’ve played around with different testing concepts like mocks and stubs in class, however since we didn’t dive too far into it, I decided I’d look a little bit deeper into the subject of mocking. I found this great overview of it on Michael Minella‘s blog.

Before diving into why mocking is helpful, let’s look at the purpose of mocks in the first place and what they even are. In class we had an example where a student object had a transcript object, and in order to get the student’s remaining credits or current GPA, the student would reference the transcript’s methods. Something like this:

If we wanted to test the Student’s getGPA() method, it would involve calling transcript’s getGPA() method. However, we don’t want to test transcript’s method, we want to test Student’s. How do we know Student.getGPA() does the intended thing, which is call transcript.getGPA()? In his blog post, Michael uses the example of a test that uses the ArrayList object in Java. When we write a test that uses an ArrayList, we don’t want to test the functionality of ArrayList — we want to test our implementation of it and trust that ArrayLists function correctly. Mocks are designed to solve this problem.

A mock is a temporary object that is used in place of the real object that would be used during a test. The mock has default values for all of it’s data types, and so whether or not a test passes is not dependent on the state of the other objects or methods inside of it. In the case above, transcript.getGPA() would return a value of 0.0 if a mock transcript object had been set up beforehand. This is helpful because it allows us to remove the potential puzzle of the functionality of the transcript’s methods and solely focus on the what the student’s getGPA() is actually doing. 

There are plenty of different mocking libraries to choose from (we used Mockito in class) and they all function in slightly different ways. The subject of mocking is a deep one, and there are seemingly infinite other concepts like stubs, fakes, dummies, and more which can all be used to ensure that your tests test are as thorough and reliable as possible. 

From the blog CS@Worcester – James Blash by jwblash and used with permission of the author. All other rights reserved by the author.

AntiPatterns: Golden Hammer

Another day, another blog post about a concept from Sourcemaking.com, this time on the Golden Hammer AntiPattern.

Software Development is a field that requires continuous learning throughout your entire career. With the sheer amount of tools at your disposal, it can be daunting to try to expand your skillset. However, knowing how to utilize as many tools as possible is important to help make an effective and well-rounded developer. Not only that, being brave enough to drop the tried and true way of doing things for newer, more effective solutions is an important soft skill to have as a team.

We’ve all heard of the expression, “If all you have is a hammer, everything looks like a nail.”, and that’s the exact origin this AntiPattern. When a team fails to develop their knowledge and expand their skillset, they often fall back on the same process that they’ve used in the past. Sometimes, a significant financial investment has been made into training the team to use a specific product, and so they don’t want to let that methodology go to waste. That’s fine, except for the fact that there is a unique way to approach nearly every new problem that developers come across. Reusing old system design is a sure fire way to cause more problems than necessary for the development process.

There are countless issues with this approach — it’s like trying to fit a square peg in a round hole. In a way, teams will end up warping the problem in order to make their solution work, as opposed to designing a good solution for the problem. It’s self limiting too, because teams will only end up choosing problems that they feel comfortable with, relating back to approaches they have taken in the past. Not only this, but if the Golden Hammer is a particular product or tool made by another company, then the team can find themselves at the mercy of that company to continue support for that product.

Not only does this AntiPattern require a tremendous amount of refactoring (usually, a complete reworking of the product is necessary), it requires a change in the philosophy of the developer(s). Each and every member of the team needs to be focused on expanding their knowledge of shifting trends in technology, and there must be an emphasis on the exploration of new tools in the workplace with some leeway in deadlines as a result.

From the blog CS@Worcester – James Blash by jwblash and used with permission of the author. All other rights reserved by the author.

AntiPatterns: Spaghetti Code

Many AntiPatterns seem to arise when code structure is ignored and foundational concepts like those of OOPs are forgotten. Spaghetti Code is perhaps the most common and widespread of these, since it can come about so easily in nearly any program regardless of the language or paradigm. In a general sense, it is unstructured code that is difficult to read, edit, or use.

Spaghetti Code involves a very cluttered, messy design (or lack thereof). There are many moving parts which seem disorganized and generally readability is extremely, low even for the original developer. It’s much more easily found in procedural paradigms as Object Oriented paradigms were made partially to avoid this problem in particular. If Spaghetti code is found in an Object Oriented system, the structure often reflects that of a procedural program.

I’ve written about The God Class before, which is a concept that stems from similar errors, except in a slightly different form. Spaghetti Code differs from this in that the God Class has one central core class that makes extending and modifying anything more of a challenge than is necessary. Spaghetti Code generally has several large classes which run in a single, multistage process. Sometimes this kind of messy code can be found within other AntiPatterns, such as Lava Flow. Dead ends of routes taken with old projects can result in a jumbled mess of irrelevant code that is hanging around for no reason other than it is difficult to read.

So what can we do about it? Well, like many other AntiPatterns, the best solution is to take a preventative approach. Make sure that a clearly defined structure for the program is outlined before starting to develop. Make sure that when modifying the existing code, the developer adheres to the structure in place. If you’ve found yourself in a position where you need to refactor Spaghetti Code, it could potentially be a case of diminishing returns where trying to “fix” the program is more difficult than rebuilding it from the ground up. This is a massive waste of development time and money, since if a clear goal were in place to begin with the problem could have been avoided all together.

At the end of the day, a clear vision and game plan for the software you’re writing is the most important piece of development. Without a path to follow, problems become difficult to solve and solutions become difficult to implement — especially when developing a large scale software system.

From the blog CS@Worcester – James Blash by jwblash and used with permission of the author. All other rights reserved by the author.

New Instances in JUnit

Martin Fowler’s Blog is an amazing resource for someone breaking into the field of Software Development — his blog posts are extremely easy to read and are very educational. Even older content is still relevant and helpful to read through, like this article on the reasoning and design decision behind JUnit tests creating new instances for each test. As someone who has only a bit of experience writing my own Unit Tests, this was pretty eye-opening.

So why does JUnit create a new instance for each test, and what does that even mean? Each time you run a test, a new instance of each object used in the test is created. This means that in one test, if you create an object or assign a value, that change will not carry over into any other tests. The idea behind this is called isolation, and although it may seem counterproductive, it is extremely important. It ensures that no test should ever do something that would cause another test to fail.

So what exactly makes isolation so important? The point of Unit testing is to bend and stress the basic structure of the source code. If all tests were relying on a shared state which was dynamically changed between one another, each would leave behind data that would impact the other tests. You’d end up testing not just the source code, but you’d also be dancing around the different tests you had already written. If each test weren’t isolated, it would make the main objective — testing the product — significantly more complex.

JUnit in particular provides functionality to support this isolation and make the job of the tester easier — things like the setUp method. If you want each test method to create an Array with 5 elements, you would place that in the setUp method for it to be run prior to each test as opposed to having to rewrite that piece of code for each test you have. This helps keep each test isolated, whilst still providing every test with a shared base state from which to run.

If you’re like me, you had encountered this problem while tinkering around with JUnit and kind of accepted it without questioning the purpose behind it. It’s intuitive and makes sense that each test should be isolated from the others, but it is also important to ask “Why?” or “What would change if this were different?”. It gives insight into the JUnit framework, and helps make a more effective tester.

From the blog CS@Worcester – James Blash by jwblash and used with permission of the author. All other rights reserved by the author.

AntiPatterns: Lava Flow

If you’ve ever contributed to Open Source projects (or ever tried to code pretty much ever), the concept of Lava Flow probably isn’t very foreign to you. 

Throughout the course of the development of a piece of software, teams take different approaches to achieve their end goal. Sometimes management changes, sometimes the scope or specification of the project is altered, or sometimes the team simply decides on a different approach. These changes leave behind stray branches of code that may not necessarily align with the intent of the final product. These are what we refer to as “Lava Flows”.

If the current development pathway is a bright, burning, flowing stream of lava, then old, stagnant, dead code hanging around in the program is a hardened, basalt-like run-off that is lingering in the final product. 

Lava Flow adds immense complexity to the program and makes it significantly more difficult to refactor — in fact, that difficulty to refactor is largely what causes lava flow in the first place. Programmers don’t want to touch code that they don’t fully understand because they run the risk of interfering with the functionality of the working product. In a way, the flows grow exponentially because developers create loose work arounds to implement pieces of code that may not even need to be implemented at all. Over time, the flow hardens into a part of the final product, even if it contributes nothing at all to the flowing development path.

So what can we do about this AntiPattern? The first and perhaps most important thing is to make sure that developers take the time to write easy to read, well documented code that is actually relevant to the final project. It is far more important to take a preventative approach to Lava Flow, because refactoring massive chunks of code takes an exorbitant amount of time and money. When large amounts of code are removed, it’s important to understand why any bugs that pop up are happening. Looking for quick solutions without have a full grasp of the problems will just continue to accentuate the original problem.

I found out this AntiPattern through SourceMaking.com’s blog on it, which delves much deeper into the causes, problems, and solutions involved with this it. I strongly recommend checking out that post as well, as it is far more elaborate than mine and gives great real-world examples along with it.

From the blog CS@Worcester – James Blash by jwblash and used with permission of the author. All other rights reserved by the author.

AntiPatterns: The God Class

We can all remember back to writing programs in our Intro to Programming course, where (if you were learning an OOP language like Java) you placed nearly everything into the main method just for the sake of learning. Projects continued to be approached like that for awhile, until you learned about inheritance and class hierarchies and why putting everything into main is actually not the best idea. It removes the basic principles of OOPs and essentially turns the project into a procedural program.

That is essentially what the God Class, AKA the Blob, does. Any related classes that are used are generally there to store data, and there is a big central class that is core to the functionality of the program. The God Class contains both operations and data relating to an extremely large amount of other classes, and acts as a controller for all of them. They generally seem to arise when time constraints and specification demands are placed on people who already have a shaky foundation in OOP principles. Either that, or often times when writing code developers will add small bits and pieces to existing software that they’re using, and some classes (especially controller-type classes) end up getting a disproportionate amount of these small changes over time.

In terms of drawbacks, there are a lot. It makes updating infrastructure far more complex than necessary, and it makes seamlessly fixing bugs in that system extremely difficult. Blobs are hard to test since there are just so many operations that work together within them, and when you create an object in memory there may be a significant portion of its’ functionality that you’re neglecting which soaks up running times.

So what can we do to refactor a God Class when we see it? First, find methods within the God Class that deal with one another and group them together. If developers have been slowly adding functionality to a controller that has resulted in a Blob-type class, then there should be a good amount of operations within it that could be grouped together. Then, either move those groups of operations into classes which they call upon in some way or create new, smaller classes which perform in the same way. Through doing this, you can extend the functionality of existing classes and reduce the complexity of your Blob. In the long term, reducing God Class complexity will assist in future testing, refactoring and will prevent annoying bugs from popping up that intrude on your beautiful OOP system design.

From the blog CS@Worcester – James Blash by jwblash and used with permission of the author. All other rights reserved by the author.

The Testing (Automation) Pyramid

The Testing Automation Pyramid (sometimes just called the “Testing Pyramid”) is an Agile methodology that involves a heavy reliance on Unit Tests as opposed to UI-based testing. It’s referred to as a “pyramid” because the width of the layers in the pyramid refers to the ideal number of tests per layer. The bottom, widest layer is Unit Testing, the middle layer consists of service-related tests, and the tip of the pyramid represents UI Tests. A picture of the structure is shown below, sourced from Martin Fowler’s blog.

test-pyramid
Moving up the pyramid, the type of testing done costs more resources to execute and more time to assess.

Part of the reason why UI testing takes significantly more resources is because it involves interacting with and logging the operations of the interface in order to see where something may go wrong. Running through the operations of the UI to see where it breaks takes a very long time, as there are so many levels of abstraction between the UI and the underlying infrastructure, and so much functionality within User Interfaces. On top of this, as the product is updated and refactored, tests derived from the original UI interface becomes obsolete, making the lifespan of higher-level tests shorter than those aimed towards the low-level structure of the system.

This is why Unit Tests are so good. They’re a cheaper (in terms of both resources and time) alternative, and they provide a means of testing the actual root of the issue. Unit Tests are preventative and they ensure that a bug presenting itself in the UI level stays fixed, rather than allowing the bug to manifest itself in a variety of different ways.

There is quite a bit of criticism of this model, as if it goes unchecked it ends up as the so called “Ice Cream Cone” anti-pattern, where a small layer of exploratory manual testing above the UI testing layer ends up becoming mandatory manual testing, which becomes both a resource and a time sink. This is far better explained by viewing Alister Scott’s blog post on it over at his blog, WatirMelon.

Martin Fowler, whose blog I found this concept on and referenced earlier, summed it all up in a pretty wonderful way: “If you get a failure in a high level test, not just do you have a bug in your functional code, you also have a missing or incorrect unit test.” Martin’s blog post elaborates on the idea much better than I’m able to, and his blog is extremely readable and has really great content. I’ll definitely be using it as a resource in the future.

From the blog CS@Worcester – James Blash by jwblash and used with permission of the author. All other rights reserved by the author.

Your Interfaces Are Your Responsibility

This week, I looked through the Google Testing Blog and spotted a great post regarding your job as a programmer in writing good interfaces. I thought it touched on some great points and used some great examples, so here I am, writing about it. The blog post is part of a series of posts from Google called “Code Health”, which essentially outlines some of their standards for code quality.

“Code Health: Make Interfaces Hard to Misuse” uses an example of an empty Vector which has a “num_slots” slots available for use. Marek Kiszkis, the author, outlines two ways to write this class. The first way relies on the person who implements it to manage the expansion of the number of slots of the vector. They must check the slots remaining before adding into it to ensure that it has the room for a new item. The second way the Vector class is written has the Vector automatically expanding by a certain number of slots as items are added in. The implementer has very little control over the function of the Vector, however the Vector’s lack of flexibility can be a desirable outcome, as misuse much more difficult. The author provided a few different examples beyond this of easy-to-misuse Interfaces, such as requiring the caller to run initialization functions, perform cleanup, etc.

The article is finished off with a reminder that, while making interfaces this way is a good thing, you still need to be selective with this methodology. Sometimes writing an interface in a “overly-defensive” way will result in needlessly complex code, where implementation is more difficult to execute than necessary. The documentation is equally as important as the structure of the code, and keeping that in mind will help you write usable, stable, and effective code for others to utilize.

I found this blog post surprisingly relevant to my current course-load. In both this class (CS-443) and the Software Architecture & Design class (CS-343), will be implementing interfaces much more frequently than we have in previous courses. Having a better understanding of safe and effective ways to writing them will be extremely useful in the long run.

From the blog CS@Worcester – James Blash by jwblash and used with permission of the author. All other rights reserved by the author.

The Importance of Names

I’ve heard a lot of great things about “Clean Code” by Robert “Uncle Bob” Martin, and when I saw that the Coding Blocks Podcast had done a small series reflecting on the material of the book, I jumped right in.

Clean Code (although I haven’t read it yet) is a book that aims to set a standard in software craftsmanship, so that code isn’t lost as a result of being difficult to reuse, refactor, or even… well, read. The podcast reflected on Chapter 2 of the book, Meaningful Names. Allen Underwood and Michael Outlaw discussed major points that the chapter touched on and their personal experiences with each.

The segment that may have had the most impact on my outlook towards this subject was one of the first ones in the podcast — that the names of variables and methods should be as descriptive as possible, so that you don’t necessarily need to write a comment that explains what it does. This seems self explanatory, but I’ve already caught myself feeling compelled to comment every variable I declare in order to explain the differences between nondescript declarations like numDays and dayNum. Even if it’s just a small personal project, getting in the habit of writing effective variable names is a practice to start sooner rather than later.

They made another great point later on during the show too — Don’t be afraid of long variable/method names! So far in my educational experience, I don’t think I’ve needed to bother with a program that was more than ~500 lines total. In this case, it’s pretty easy to scroll to find what you’re looking for in each class. However when you’re dealing with a full software program, having a variable name that is easily searchable can save an enormous amount of time.

Certain topics touched on, like the “Hungarian Method” for example, I was completely unfamiliar with. I think standards like that may have been more niche or were perhaps prevalent before my time writing code. I agreed with what they said about it in the podcast, and I think the idea of a common naming convention is a good one however having code that is clear and easily readable is a better alternative.

This series of podcasts were really good, so I’ll likely be writing about it a lot more in the near future. There was a whole lot more that they went over, and it definitely made me interested in reading this book.

Here‘s a link to the episode on their website, check it out!

From the blog CS@Worcester – James Blash by jwblash and used with permission of the author. All other rights reserved by the author.