Category Archives: Week 4

Apprenticeship Patterns: The White Belt

Christian Shadis

2/26/2022

In the apprenticeship pattern The White Belt, Hoover and Oshineye explore the importance of maintaining a beginner’s mindset even when already a subject matter expert. They attribute this largely to creativity and open mindedness in problem solving: a programmer who is an expert in Language A should act as though they are a complete beginner in Language B to avoid their prior knowledge restricting them from learning all techniques and conventions of the new language.

The whole pattern seems counterintuitive at first, but a small example illustrates the concept more clearly. If a Java programmer wanted to join two lists together in Python, but by only using their Java knowledge, their solution would undoubtedly be far more complicated than a simple list comprehension that Python allows. Putting aside prior knowledge in favor of re-learning problem solving methods would allow that same programmer to utilize Python’s list comprehensions. In a more general sense, by ‘taking off the black belt’ and ‘putting on the white belt’, a developer can learn best practices and technically efficient problem-solving techniques in any language, which will further bolster their overall programming skills and employability.

This pattern also shifted my perspective toward my education so far at Worcester State. Over the past few years, I had found myself frustrated with the methodology of the Computer Science department, which I believe is rooted in giving students exposure to as many elements in the software development world as possible. My frustration lied in the fact that we, for the most part, didn’t do very deep dives on any language or technology. After reading this pattern though, I realize this approach was about showing us as many different things as possible to prepare us to do just what this pattern teaches: learn new technologies and languages as your career develops, rather than becoming a subject matter expert and looking at the rest of your development career through the lens of that subject.

I hope to use this pattern throughout my career, but more specifically I plan to implement this pattern while I continue to learn Object-Oriented Programming languages, especially Python. Most of my OOP code has been written in Java, yet I consider myself fluent in Python. This is a clear example of letting my knowledge in Java prevent me from re-learning object-oriented programming in Python, which would harm my performance in a Python assessment or interview. In this case, and throughout my career, I will make the decision to set aside my knowledge to re-learn the fundamentals through a separate lens to enrich my understanding of the subject.

Reference:

Hoover, D. H., & Oshineye, A. (2010). Emptying the Cup. In Apprenticeship patterns: Guidance for the aspiring software craftsman. O’Reilly.

From the blog CS@Worcester – Christian Shadis' Blog by ctshadis and used with permission of the author. All other rights reserved by the author.

Concrete Skills Pattern

For this week’s apprenticeship pattern, I did a reading on “Concrete Skills”. Concrete skills are a pattern that I feel like I am currently experiencing. Concrete skills is about acquiring and maintaining skills that enables you to be ‘trusted’ by companies so they’re more likely to hire you. Concrete skills are supposed to reassure future team members that you are capable of doing the tasks that would be assigned by you and wouldn’t need to be babysat during the process. These types of skills are considered to be the basic of any programing language or knowledge. These are usually tested when you are being interviewed by current software engineers at a company that are simply just testing your knowledge. A great solution to anyone who has this problem is to work on side projects and casually review how basic functions work in your chosen language.

My initial reaction after reading this pattern is that it is a reflection of what I am currently experiencing. Since I have limited experience in the professional field of software engineering, I am currently requiring hiring managers “to take a leap of faith” in choosing me to work at their company, as the book says. The reading was quite interesting and very useful. Interesting because I can relate to what it is talking about and useful because it helps me with my current job hunt and figuring out ways to tackle this issue. Even before reading this pattern, I’ve been trying to practice more concrete skills and building side projects that will help me with the journey of becoming a software engineer.

The pattern has not changed the way how I view my profession because I already had an idea of how HR and the process works. The hard part of any job is getting selected for the interview process and for me, since I have no real type of internships, it is much harder. I do however have that I’ve worked in companies with good positions but they’re not entirely “software engineering” related. Therefore, I am constantly practicing my skills and working on side projects that I can showcase on my resume and be able to answer questions that are thrown at me if I were to get selected for an interview.

From the blog CS@Worcester – Michael's Developer Blog by michaelchaau and used with permission of the author. All other rights reserved by the author.

The White Belt

For this week’s blog post, I have decided to look at the apprenticeship pattern “The White Belt”. This chapter talks about how you have gained a deep understanding of your first language and have become confident. However, you are struggling to learn new things and it has become more difficult to learn new skills. The main idea of this chapter is to wear a white belt and forget everything you have been taught thus far and learn from someone with a blackbelt. Dave H. Hoover & Adewale Oshineye, the authors of the book, say on this, “Wearing the white belt is based on the realization that while the black belt knows the way, the white belt has no choice but to learn the way”. (Dave H. Hoover & Adewale Oshineye). As discussed in the text, when you take this approach in learning some new material this will accelerate your learning process tremendously. When you take this step towards ignorance, you can express yourself idiomatically and gain a far better understanding of your new knowledge. This way when you consider both what you learned and your old knowledge you have developed productive insights in both fields.

What I found interesting about this pattern was that it’s like what we learned in the chapter “Your First Language”. In that chapter it mentioned finding a main language but not forgetting about what you learned in the past. With this chapter we can apply both knowledges and expand on our main language. By being able to take a step back you can develop your skills in a way that I didn’t eve think about. Now knowing this knowledge, it has made me rec consider what I would be doing out in the real world at my profession. If presented with a problem that I have no past knowledge about, instead of trying to guess what the solution to it would be I can ask someone who knows, a.k.a a blackbelt, and expand my knowledge of the subject. With everything I Have learned I both chapters, this gets me excited to go out into the world and gain more knowledge to become a “blackbelt”.

Book: Apprenticeship Patterns, Dave H. Hoover & Adewale Oshineye

From the blog CS@worcester – Michale Friedrich by mikefriedrich1 and used with permission of the author. All other rights reserved by the author.

CS 448 Post #1

I wanted to do my first post on the first pattern we are given in chapter 2 because it is the start of delving into the patterns we will be working with after chapter 1 and start of chapter 2 introducing what the book will be about. The first pattern here is “Your First Language”, and it talks getting started with programming languages and how you can start and improve at working with one. It is recommended to start with one language and take time to learn and get used to it so that you are fluent in it. Solving problems using this language can also help you gain experience and get a better understanding. You will want to spend enough time with the language to become fluent in it, but keeping the introduction to the book and chapter 2 in mind, you don’t want to get stuck with it and instead want to be able to learn other languages after the first one.

I think that it is smart to focus on one language when starting out before moving onto others, and having problems to solve with that language can be very helpful at understanding and working with that language. It reminded me of doing worksheets or assignments in school for a subject after doing studying and some practice. It is also good to not start trying to learn multiple languages at once because some of what you learn from them may start to get mixed up, and starting with one language before moving onto others and possibly doing multiple languages simultaneously is the smarter route to take. In my past CS courses, we were taking time with a language before moving on the next one, working on and solving problems with that language. Because of that, I have seen how effective this way of learning languages is.

I thought that this was a great first pattern and problem to go over after the first chapter and the second chapter’s introduction, since this book is going to go over many other patterns in this chapter and later chapters, and this pattern covers the starting point for readers and programmers learning new languages.

From the blog Jeffery Neal's Blog by jneal44 and used with permission of the author. All other rights reserved by the author.

Practice, Practice, Practice

This week I chose to write about Practice, from the Perpetual learning portion of the book. I think that this is an important topic because practicing is important in any skill or craft.

As a Software Apprentice, practicing is crucial. Practice will help me develop concrete skills in new areas. Concrete skills are necessary to land my first job. And the author poses the problem that my daily programming activities do not give me the oppurtunity to learn by making mistakes. This last part is not true for me. I do have the oppurtunity to make mistakes quite often.

One thing that Dave mentions is that practicing has to be done in a relaxed environment. So personal projects outside of work are an important part of the software craft. This makes sense to me. Because when programming for work. There are calls, meetings, and deadlines.Coding for school projects is similar. But if I am practicing for my own sake, I can relax and focus on learning. Dave also mentions to carve out some time everyday to practice. This makes a lot of sense to me. At the end of the pattern, Dave recommends that I complete the same excercise from scratch, once a week.

Over the winter break, I had some spare time one my hands, and I decided to take on a personal project. I wanted to learn about the React framework, so I decided to build a calculator with React. I made a calculator website one year before with vanilla JavaScript. It was nice to be able to learn at my own pace. And I had to remind myself that I was coding to learn, and it was okay that the project took me longer than expected. This was a good learning experience. I made an app that does works as expected, and I have something new on my GitHub. So practicing helps me to achieve the skills, and as long as I put the code in a public place, the projects become part of my resume. Creating personal projects will be part of my coding journey, and one of my favorite parts too.

From the blog CS@Worcester – Jim Spisto by jspisto and used with permission of the author. All other rights reserved by the author.

Craft over Art

This apprenticeship pattern discusses how software developers should prioritize placing their desire to give useful products to customers over their desire to create novel and fantastic code. Given the choice between using a simpler, proven solution and taking the opportunity to create something innovative and artistic, software developers should always choose the latter. This is because if software developers are to be considered craftsmen, then they need to focus on the craft. If a software developer loses their job because they keep creating beautiful code that customers simply do not find useful, then they have left the craft. This does not mean that the software products developed can not be beautiful, they can be, but they also must be useful and provide value to the customer. This apprenticeship pattern is about how software developers should develop the ability to sacrifice beatify for utility when it is necessary.

However, this apprenticeship pattern is not only about sacrificing art for craft, but it also encompasses the idea that the craft should always maintain a certain level of quality. Every piece of software produced should meet a set of standards. Being able to hold on to these standards will ultimately help develop an understanding that beauty and utility are not opposites, but interdependent. The more important a piece of software is, the more important that the software be of high quality. To achieve quality work, software developers must constantly make tradeoffs between beauty and utility. However, the tradeoffs we make might not always be the right ones, and so learning how properly refactor and repair code is essential to fixing our mistakes and correcting the balance that is desired.

I think this is an important apprenticeship pattern to learn because every software developer needs to have the skill of being able to strike a balance between beauty and utility in their code if they wish to be craftsmen in the craft of software development. I personally never gave much thought about striking a balance when writing code before reading this pattern. However, from now on I will start reconsidering how I should prioritize my desires when writing code to try and strike the right balance between usefulness and art.

From the blog CS@Worcester – Fadi Akram by Fadi Akram and used with permission of the author. All other rights reserved by the author.

One Step Backward, Two Steps Forward

“You have to spend money to make money.” – Peter Griffin (Family Guy)

This quote is probably one of the most familiar antitheses to the idea of “one step forward and two steps back”. Alongside this week’s reading of “Apprenticeship Patterns”, we are going to figure out how retreating into our competent “safe zones” can actually be a beneficial way to make progress into unknown territory.

In essence, the pattern describes about finding an “acceptable limit” of disregarding challenges in order to polish up on familiar material. By finding patterns in previous progress, we can empower ourselves to embrace the challenges of the unknown. It is important to note that the “limit” is respected – going too far ahead into the unknown leads to a lack of progress from ignorance. Retreating too far into the safe zone causes another lack – from fear.

I understand that taking some time to work on an easy, familiar project is a great way to create a productive sabbatical. To be honest, I have been practicing this pattern long before reading up on it; making familiar homework assignments and simple games has been a hobby of mine. Plus, once skills are learned with a “back of our hand” level of proficiency, it makes the mind bored with these tasks – it craves something more novel, no matter how challenging.

“Retreating Into Competence” stresses that we must make the regression quickly turn into progression, otherwise we may end up in a rut. While I don’t necessarily disagree, I wonder if there is a way to “charge the catapult” for an even greater forward effect. Exactly how far can we pull back on our efforts towards familiarity in order to shoot ourselves among the star s of the unknown? Is minimizing our refreshment emphasized because the “catapult method” has a short charge limit? My interest for these questions makes me want to experiment with the pattern (this would be best done in conjunction with some Breakable Toys).

In order to use this pattern professionally, I need to start thinking about time. Every moment of the past that I can regress to, was at one point “an unknown future destination”. Figuring out the methods on reaching these past points can lead to notes for successful exploration of a project’s future. Analyzation of the past should be done as scientifically as possible; getting wrapped up in the nostalgia of success or wallowing in the failure will cause us to miss the future that lays ahead.

Fun fact: this pattern itself is a “regression”; I am doing it by using a token to go back to Week-4.

From the blog CS@Worcester – mpekim.code by Mike Morley (mpekim) and used with permission of the author. All other rights reserved by the author.

Junit and Temporary Files

               When working with a Java program, one of the strongest tools to ensure it is functioning is Junit testing. Junit testing makes it easy to take a glance and see if all properties of your code are functioning correctly. Despite this however, at the end of the day, the product must be able to seamlessly accept and output data in a usable form. Therefore it is important to understand how to use temporary test files when using Junit.

              Andrew Binstock’s post fits in with regards to the currently assigned homework which sees us utilizing test classes and modifying them as the code is refactored. These tests allow us to ensure that the written code is working properly. To build upon this idea the post linked below presents the idea of Junit testing with temporary files to read and write to. Within this post is sample code which creates temporary files in and out of Junit testing.

Below we can see a snippet of code from the original blog post which shows temporary files being used in a Junit test. (Andrew Binstock)

import org.junit.jupiter.api.*;
import org.junit.jupiter.api.io.TempDir;

import java.io.*;
import java.nio.file.InvalidPathException;
import java.nio.file.Path;

import static org.junit.jupiter.api.Assertions.*;

public class TempFilesJUnit5Test {

Path path1, path2;
File file1, file2;

/* This directory and the files created in it will be deleted after
* tests are run, even in the event of failures or exceptions.
*/
@TempDir
Path tempDir;

/* executed before every test: create two temporary files */
@BeforeEach
public void setUp() {
try {
path1 = tempDir.resolve( “testfile1.txt” );
path2 = tempDir.resolve( “testfile2.txt” );
}
catch( InvalidPathException ipe ) {
System.err.println(
“error creating temporary test file in ” +
this.getClass().getSimpleName() );
}

file1 = path1.toFile();
file2 = path2.toFile();
}

               Within the second homework assignment we can see that Junit tests are used to ensure that the different classes of ducks and working properly and that the data output is correct. Some of the Junit tests scan the output file and compares it against the expected output. While this is useful to ensure the code works, it is also important to consider that not everyone will want their output confined to the terminal. This program could very easily be modified to output to a text file for data collection purposes. Testing this with Junit would allow the creator to ensure that data is being retained properly before running the program in a real case scenario.

Testing with temporary files was previously an underutilized method of testing due to older hardware being much slower and older drives using spinning magnetic disks rather than modern solid state storage. In the post we see the author discuss this dated policy and encourage the use of test files to create a more thorough testing method. Some might want their output in a text file or as an output to a front end for a website. Junit tests with temporary file allow you to test for this functionality as these temporary files can be created, read from, written to, and are all deleted at the end of testing to keep drive space free from clutter.

Bibliography:

Binstock, A. (n.d.). Working and unit testing with temporary files in Java. Blogs.oracle.com. Retrieved October 11, 2021, from https://blogs.oracle.com/javamagazine/post/working-and-unit-testing-with-temporary-files-in-java.

Working and unit testing with temporary files in Java (oracle.com)

From the blog CS@Worcester – George Chyoghly CS-343 by gchyoghly and used with permission of the author. All other rights reserved by the author.

Factory Method vs Abstract Factory

For this week’s assignment, exercise #2, I had an opportunity to refactor a poor design of Duck Simulator using the factory pattern. It was nice that I could approach this design pattern step by step and learned its definition by understanding why I had to create an abstract method or why I had to create a factory class. Moreover, after skimming through a long chapter, Chapter 4. Baking with OO Goodness: The Factory Pattern, although there are many important definitions in this chapter, I believe that there are two concepts that I shouldn’t miss, the factory method and the abstract factory. Both are new tools that I need to know what they are and how to apply them to a design.

Furthermore, for better understanding, I also wondered what was the difference between factory method and abstract factory. Although, the textbook has a comparison between those two concepts, but for myself, it was long and difficult to follow till the end. So, I did a few searches to see if there were any good resources that I could take a quick look at for my question. I found a good blog, called Factory Method vs Abstract Factory. In this blog, the writer makes some comparisons to show the difference between factory method and abstract factory. Through the blog and the textbook, I know that both concepts are used to encapsulate object creation, and they apply the dependency inversion principle by allowing coders to decouple code from concrete classes . On the other hand, the two concepts differ in many ways. First, the number of products produced is different. The factory method is used to create only one product while the abstract factory is used to create families of related products. Second, for the factory method, the object creation is decided by subclasses (depending on inheritance), whereas the abstract factory has a separate class to creates a family of products, then its object can be passed to client class for using (object composition). Next, it is the level of abstraction. Since the abstract factory are at higher level in abstraction, we can use factory methods to create products in factories.

For myself, this is a resource worth referring to because its concise, well-organized content helps readers easily distinguish the difference between the two concepts. Thanks to this resource, I got a better understanding of the factory pattern, especially the abstract factory and factory method, which is really helpful for my diagram design latter.

From the blog CS@Worcester – T's CSblog by tyahhhh and used with permission of the author. All other rights reserved by the author.

Just Another Scripting Saying

Ever since the beginning of my programming career, I have had a plethora of professors provide several sayings that were helpful to becoming a better software engineer. One particular saying was acquired only a few weeks ago, during my Software Construction course. The saying goes: “YAGNI”, or when extended beyond the acronym: “(Y)ou (A)in’t (G)onna (N)eed (I)t”.

YAGNI is a useful term when considering one particular coding smell: Needless Complexity. Novice programmers often believe that they need to somehow squish every keyword, conditional statement and data structure into one massive, impressively diverse program. Yes, it is definitely useful to be knowledgeable in all of these areas. However, an advanced understanding of programming requires that one not only knows the skills, but also when to use them.

The article listed below (created by legendary software engineer Martin Fowler) explains the various reasons why YAGNI is so important. Specifically, it explains different kinds of “costs” related with unnecessary complexity: Costs of building, repairing, delaying and carrying the software. Considering these costs is such a crucial factor due to the fact that software should be designed to be cheap for the producer, yet effective and “easy-to-use” for the customer.

Understanding YAGNI, and its effectiveness against needless complexity, is invaluable to achieving proficiency in software design. The class does not want us to build products “per se”; rather, it already expects that we can build the block from the get-go. Instead, this class focuses on “whittling away” at the back-end block to create something more beautiful and beneficial.

If anything, based on the material that Martin Fowler has presented to us, we need to take a look at our code and ask ourselves: “is this really necessary?” Do we really need this exception case if the chances of achieving the error make the lottery look like a safe bet? Are these security features needed when a simple password check can cut the mustard? Cutting down on needless complexity is a rather easy smell to work on, since the problem is based on our ability to work harder than we really need to. Instead of remembering every last line of code, we should remember the abstract ideas, and learn how to translate/implement them.

In conclusion, I believe that “YAGNI” is an essential saying that every programmer should know by heart. In addition, I strongly believe that the sooner a junior programmer can learn this rule, the better off they’ll be in the world of software design. The best way to avoid certain coding smells (such as viscosity) and technical debt is to instill proficient programming practices that avoid these problems to begin with.

Link: https://www.martinfowler.com/bliki/Yagni.html

From the blog CS@Worcester – mpekim.code by Mike Morley (mpekim) and used with permission of the author. All other rights reserved by the author.