After a few years of using mainly one language to accomplish programming assignments, I will certainly admit to becoming complacent with Java. If I was asked to write pseudocode, my mind immediately begins object orientation and even begins running through some of the Java syntax. While this can be helpful, as I feel my ability to think in Java means that I may be well on my way to becoming bilingual, there are also many drawbacks to complacency.
Applying this Java-like thinking to problems in other languages or under other frameworks is where problems may arise. Rather than being open to discovering and developing new skills, the existing knowledge becomes a hindrance to learning. Attempting to apply existing knowledge to problems of a different sort or in a different language may slow progress, and make learning even more difficult and frustrating.
The solution offered by Hoover and Oshineye in Apprenticeship Patterns is to put on The White Belt and allow oneself to be ignorant by putting aside accumulated knowledge and experience, leaving no choice but to learn the way through trial, error and reflection. Treating new learning opportunities in this way allows for more deeper understanding and helps to create more smooth communications with members of the existing community.
While I would have previously described myself as open minded and always willing to learn, I believe that The White Belt pattern has helped me see a more valuable way to approach new learning. I will certainly be using the ideas of Hoover and Oshineye the next time I attempt to learn a new programming paradigm.
Something that has certainly been engrained in my programming brain is that code should be as easy to reuse as possible, and this is done through the use of objects in what is known as object oriented programming. In my very first programming class I used Java and most of the academic programming that I have done since that point has also been in Java. Java is a self-described “general-purpose, concurrent, strongly typed, class-based object-oriented language.” As a result of its object-oriented nature, one cannot learn to program effectively in Java without learning how to program in an object-oriented manner. While object-oriented programming can often allow for the efficient reuse and maintenance of code, it may also overcomplicate things in certain instances. Knowing when and where to step away from an object-oriented approach to programming can be important to creating something that is easy for others to understand and build from.
In a Coding Horror post titled “Your Code: OOP or POO?” from March 2007, Jeff Atwood explains why programming in a way that considers fellow programmers who may work with your code after you is more important than mindlessly creating objects for the sake of creating them. Atwood goes on to explain why it is the principles of object-oriented design that are truly important. These are things like encapsulation, simplicity, and the reusability of your code. Atwood stresses that if you attempt to “object-ify” every concept in your code, you will often be introducing unnecessary complexity. He uses an interesting metaphor that compares adding objects to adding salt to a dish – “a little goes a long way.”
It must be made clear that Jeff Atwood and all of the other programmers that he mentions in his post are not against OOP. Rather, they are against the abuse and misuse of OOP by those who do not understand where and when creating objects is beneficial and where it is simply cumbersome or clumsy. Object-oriented programming is an extensively powerful tool for creating projects that are reusable and easily maintained or changed. What is important to take away from Atwood’s post is that it is the way that new programmers are being brainwashed into thinking that every piece of code that they write must somehow become an object lest it be poor programming is what actually causes problems. Although never directly stated, I took Atwood’s post as a call to educate new programmers about the potential pitfalls of writing overly complex object-oriented code in place of a simpler alternative that does not involve objects.
A thought that occurred to me recently while following procedures for testing using the boundary value testing method is, “What would happen if I tried values for inputs of an incorrect type rather than whatever values the particular testing method called for?” While simple test procedures such as normal boundary value testing clearly leave much to be desired, more comprehensive testing methods such as robust equivalence class testing seem to cover most of the potential sources of input errors, right? I think not. It was often difficult to fight my intuition and desire to choose test values that did not necessarily line up with the testing procedures covered in boundary value or equivalence class testing procedures. This desire to choose what to test and how to test it based simply on experience and intuition is whats known in the software quality assurance field as exploratory testing, and it is an extremely powerful method of testing when used properly and appropriately.
In a Let’s Talk About Tests podcast titled “Players gonna play play play play play,” from September 21, 2017, Gem Hills talks about the benefits of getting familiar and gaining a better understanding of a program simply by “playing about,” with the program itself. Hills argues that sometimes simply using the program and applying knowledge from previous experiences with similar programs or with the development team itself can often provide a software tester with potentially revealing test cases that would be missed if the tester was relying solely on a testing framework. In her post, Hills references Richard Bradshaw, perhaps better known as the “Friendly Tester.” Specifically, Hills talks about attending one of Bradshaw’s talks at the BBC in August where he spoke about how “having a play” with a program can become far more impactful by simply recording the results and tests, effectively turning this play into exploratory testing.
One of the reasons that Hills cites for playing with a program with no real agenda is that, “[She] is not confident that [she’s] tested everything but [she’s] not sure what [she’s] missing.” I found this point especially telling. This is exactly how I felt when I was writing test cases for the boundary value testing assignment, as if I was sure that I was missing something, but unsure as to exactly what it was that I was missing. It would therefore seem to make sense to me that I should begin playing around in an attempt to discover what it is that I am missing. Perhaps it is simply that I am lacking the appropriate testing method, and performing some exploratory testing provides insight into an effective method. It is possible, however, that a bug exists in the program that cannot be found by applying any number of testing procedures. In these cases, exploratory testing, or “playing about,” is the only effective testing tool.