Author Archives: jwblash

Design Patterns: Proxy

Earlier this semester in my Software Design class, we had an assignment where we were to choose to write a report on either the Proxy, Facade, or Decorator design patterns (or any combination of the three, for extra credit). I had chosen the Decorator pattern, and due to the amount of assignments I had due I never went back to examine Proxy or Facade. So I’m here to do just that with the assistance of Sourcemaking’s article on it, starting with Proxy.

The Proxy is a structural design pattern that adds a wrapper to an object so that the object itself doesn’t suffer from excess complexity. There are actually a large number of reasons where this is useful. Sometimes objects get excessively resource heavy, and you don’t want to instantiate them unless absolutely necessary. Sometimes you’d just like an extra layer of protection from the access of an object for the sake of security or for general ease of use. Consider getter and setter methods for an example — you don’t want open access to the data within your object, so you make the data private (hidden from outside access) and you instead create public methods for retrieving and change the data of the private variables. In a way, getter and setter methods are mini proxies. Of course, the difference is that proxies are meant to be entire objects in themselves.

For a real-world example I’ll reference Sourcemaking’s article. In order to make a payment, someone would use the funds that they have in their bank account. Instead of needing to add methods such as “makePayment()” to their account and increasing the Account’s complexity, it is possible instead to pay with a check which can indirectly access the funds of the account. In this example, the check is the proxy to the Account class. Here’s a UML-like diagram:

Taken from Sourcemaking.com

The Proxy design pattern serves many purposes and is perhaps one of the easiest design patterns (in my opinion, of course) to understand and use. It’s very similar to Decorator in structure (which I did a project on earlier this semester) but its’ implementation is slightly different. Decorators are used to add new functionality to an object, whereas the Proxy is designed to encapsulate existing functionality into another, “adjacent” object.

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

An Introduction to Code Reviews

In my Software Quality Assurance & Testing class, we recently did a group-based code review of a simple Sir Tommy Solitaire program that my professor wrote a few years ago. It was a really fun and interesting group activity that I enjoyed quite a bit, so I decided to look more into common Code Review practices to get a better understanding of how to conduct them in a better way. This article written by Trisha Gee I found on DZone.com was a great resource for learning more about them.

First and foremost, the most important thing to remember when conducting code reviews is that your job is to view the code within the parameters of the project you’re working on. For example, if your company uses Checkstyle and prefers Google Java Conventions vs Sun Code Conventions, then the team must keep that in mind when reviewing code. All reviews must be viewed through a lens that corresponds with the vision of the project at hand.

When you’re actually conducting the review, what are the easiest things to look for? The article from DZone mentioned these four topics:

  • Formatting: Things line curly braces, spacing, line breaks. 
  • Style: Is the code laid out in a logical way (variable declarations near their usage, etc.)
  • Naming: Are naming conventions upheld throughout the program? Are they descriptive enough?
  • Test Coverage: Are there tests that cover the code and what it interacts with?

However, there are plenty of tools that exist to mitigate the potential errors which come from these easily spotted issues. Humans aren’t so great at noticing minute details — something that machines are perfect for. Formatting tools like Checkstyle that I referred to earlier will usually ensure that formatting standards are upheld, and tools like JaCoCo can assist test coverage (we’ve used both of these in class and it’s remarkable how helpful they are).

Really, the job of the reviewer is to focus more on the design choices and quality of the code. Not only should the code run, but it should be readable, maintainable, it should be written with good design principles in mind. Are any parts reused, are design patterns used in elegant ways or do they needlessly increase complexity?

I haven’t quite yet read through all of Clean Code by “Uncle Bob”, but from what I know it seems like many of the principles in that book are ones that should be deeply considered when conducting a code review. I think anyone looking for further elaboration on the topic of Code Reviews should read both the article I found on DZone (and other DZone material, frankly), and Clean Code — it’s as popular as it is for a reason.

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

Design Patterns: Iterator

I’ve been discussing AntiPatterns quite a bit lately, so I elected to switch it up and talk a bit about Anti-AntiPatterns, aka Design Patterns. As a quick recap: If AntiPatterns are common bad practice traps that developers/teams can fall into, then Design Patterns are good practices which help guide them to either avoid AntiPatterns, or to lean towards a more efficient solution.

One design pattern we’ve used many times in my Data Structures class is the iterator, and personally feel as though it was never fully explained to the class as to what an iterator even really is, let alone why we were writing one. This post from Sourcemaking.com helped a lot in terms of learning what the use of them is.

As covered in the article, there has been a push in recent programming towards something called “Generic Programming”, and the iterator is a core idea within it. An iterator is an attempt to abstract out the traversal of data items in a data structure into a separate thing. The usefulness of this is outlined by an example given in the article:

“As an example, if you wanted to support four data structures (array, binary tree, linked list, and hash table) and three algorithms (sort, find, and merge), a traditional approach would require four times three permutations to develop and maintain. Whereas, a generic programming approach would only require four plus three configuration items.”

– Sourcemaking.com

So essentially, your iterator is an object in itself that handles the job of traversing through the objects in a list. A real-world example of this may be the AM/FM radio controls in your car. The radio stations are the objects in a list, with their station name and frequency (or channel, I suppose) as their data. The iterator would be your “scan” button, which skips over the stations with fuzzy signals in order to reach the next one whose frequency is available to you, while all you did was press the one button. Each station is a data point in your list (your data structure) with a station name and a frequency. You, the driver, don’t need to know anything about the details of the stations you’re scanning over, because the iterator (the scan button) handles that for you when finding the next available station.

The article from Sourcemaking has several really great UML diagrams and other examples to pick apart which help elaborate on the subject even further. I highly suggest visiting their website to read more about it — they have detailed explanations on almost every type of AntiPattern and Design Pattern I’ve looked into so far.

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

Testing vs. Debugging

If you’ve been immersed in the tech industry for any amount of time, the difference between Testing and Debugging is probably pretty clear to you. The two concepts are interlocked and cannot exist without one another, even if they are very different. I recently found this article which outlines the differences between them, the purposes of each, and some tips to help with the debugging process. To start off, let’s examine a really great graphic they used to describe the differences: 

As shown above, testing is a process usually maintained by a dedicated team (or at least a few individuals who assist the development team). The job of the tester is to ensure that the product adheres to guidelines, and that it doesn’t execute in any way that it isn’t supposed to. Tests can be automated or manual (or a mix of both), and are intended to not only find an incorrect result, but also to find specifically where the failure happens and what may result from it. Given this information, the correction of the error becomes much easier.

So then what exactly is debugging? Once the testing team observes a failure, they bring that failure to the attention of the development team. It is then again the job of the development team to run through a few instances of the error and find out what exactly is going wrong, attempt to fix that issue in a way that still adheres to the project guidelines, and then resubmit it to the testers. If the testers find an issue, it is no longer their responsibility to ensure that a solution is found. It is the development team’s job to figure out what is going wrong and implement a good solution — and that is debugging.

A lot of this is probably common knowledge in the field, however “debugging” is a term that is haphazardly tossed around (kind of like “refactoring”) that I feel its’ meaning is easily lost. Especially for those breaking into the field or students just learning about what these concepts are, having loose definitions can be confusing. Essentially, if you’re fixing a known error, you’re debugging the code. If you’re trying to find errors, you’re testing your code.

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

Choosing Testing Techniques

I recently landed upon this article, which is essentially an introduction into software testing. It gives a great overview of why different types of testing techniques are important, what different types aim to achieve, and the ins-and-outs of each.

The last section though is perhaps the most interesting, as I think it covers a topic that we haven’t discussed quite as much in our testing class (although my professor would probably beg to differ) — different reasons for choosing each type, and what may influence your choice.

In this article, the author mostly reflects on outside influences as opposed to outlining which technique to use to solve technical challenges best. I suspect this is because each technique has its pros and cons in each technical situation. Some influencing factors are:

  • The Type of System/Software App
  • Regulatory Standards
  • Customer Requirements
  • Type/Level of Risk
  • Test Objective
  • Tester’s Skill & Knowledge
  • Time and Budget
  • Development Life Cycle
  • Previous Testing Experience

By now, I’ve learned that different companies/teams will follow different testing paradigms (usually they’ll implement several of them, to be more accurate). There doesn’t seem to be an industry standard, and I’ve heard that even things like code reviews aren’t necessarily used everywhere. What I find interesting about the points listed above is that it gives some insight into the reasoning and motivation behind why teams may choose different techniques to implement for their particular scenarios.

For example, some software systems may work better with static vs dynamic testing as their primary methodology, and some (although probably most) would prefer a decent blend of each. Obviously the time and budget for the development cycle of the app will influence how rigorous the testing process is, which will influence what specific techniques teams implement as well.

Another interesting point I felt the article made was that the customer may actually have a preference for how they want their product to be tested. I think this was an interesting point because, while a customer probably wouldn’t say “I want you to use more white-box testing”, their requirements may actually require the team to modify the tests that they had intended to use in indirect ways.

I felt as though this article was an interesting overview of different ideas in software testing, from the different types of testing, to the advantages and disadvantages of each, to the reason behind choosing which one may be best. This website, Test Automation Resources, seems to have a lot of interesting and easy-to-read testing articles. I’ll likely be reading more from it 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.

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.