Category Archives: Week 10

The Long Road

 When working on an open-source project, get in the habit of downloading the latest version of the code (preferably from their source control system) so you can review its history and track future developments. Take a look at the structure of the codebase and think about why the code is organized the way it is. Take a look at the way developers organize their code modules to see if it makes sense, and compare it to the way they might have used it. Try to refactor the code to understand why its coders made the decisions they did, and think about what the code would look like if you were the one coding it. Not only will it give you a better understanding of the projects; Also make sure you can build those projects. If you’ve found a better way to do something, you’re ready to contribute code to the project. Inevitably, as you go through the code, you’ll come across decisions you completely disagree with. Ask yourself if the developers of the project might know something you don’t or vice versa. Consider the possibility that this is a legacy design that needs to be refactored; And consider whether making a toy implementation for the relevant feature would help clarify the issue.

You end up with a toolbox filled with all sorts of quirks that you’ve collected from other people’s code. This will hone your ability to solve small problems more quickly and quickly. You’ll be able to tackle problems that others think are impossible to solve because they don’t have access to your toolbox. Take a look at the code for the Git distributed source control system written by Linus Torvalds, or any code written by Daniel J. Bernstein (known as DJB). Programmers like Linus and DJB occasionally make use of data structures and algorithms that most of us have never even heard of. They’re not magicians — they’ve just spent their time building bigger and better toolboxes than most people. The great thing about open source is that you can look at their toolbox and make their tools your own. One of the problems in software development is the lack of teachers. But thanks to the proliferation of open-source projects on sites such as SourceForge. Net and GitHub, you can learn from relatively representative code examples from the world’s programmer community.

In ODS, Bill Gates says: “The most subtle test of programming ability is giving the programmer about 30 pages of code and seeing how quickly he can read through it and understand it.” He realized something very important. People who quickly learn directly from the source code will soon become better programmers because their teachers are the lines of code written by every programmer in the world. The best way to learn patterns, idioms, and best practices is to read the open-source. Look at how other people to code. It’s a great way to stay relevant, and it’s free. — Chris Wanstrath at Ruby 2008 [

Pick an open-source project with deep algorithms, such as Subversion, Git, or Mercurial source control system. Browse through the project’s source code and jot down any algorithms, data structures, and design ideas that seem novel to you. Then write a blog post describing the structure of the project and highlighting the new ideas you’ve learned. Can you find a situation in your daily work where the same idea can be applied?

From the blog haorusong by and used with permission of the author. All other rights reserved by the author.

What is Gradle?

Today I will be writing about Gradle and the article “What is Gradle?” on the Gradle, inc website. Gradle, as explained by the company, is a build automation tool that is open source. Gradle can build almost any type of software due to its flexibility. Gradle build scripts have three phases, initialization, configuration, and execution. First, it sets up the environment. Then it constructs a task DAG or Directed Acyclic Graph to decide which tasks need to be ran in which order then executes these tasks. Gradle runs on JVM and depends on the user to have JDK installed in order for it to be used. This is a plus for people have have used the Java platform because you can use standard Java APIs in the build logic. This article is everything you need to understand what Gradle is and how it works. It first gives an overview, split into a summary and five subheadings explaining more into depth on how it functions. After the overview it gives “Five things you need to know about Gradle” which discusses key factors that makes it different than other build automation tools. I selected this topic because we have been using Gradle in class, but I never fully understood its use and how it works. This article answered exactly that. The article is by Gradle inc, so there wont be a more accurate article on what it is and its functionalities. I personally found this article easy to read. As mentioned in my prior blog posts, I like when the reading is split up into subsections and headings. This makes it easier to keep track of what the article is talking about and keeps the information organized. There is not more than 4-5 sentences per subsection which keeps it to the point. Also, the diagrams provided do an excellent job on displaying what the subsection is trying to convey to the reader. For example, their diagram of the DAG that Gradle makes to determine the order of task to be completed is split into two parts. One shows an abstract model for a general view, then it gives an example for a standard java build. By giving the abstract and the practical example, it gives you two diagrams in which you can make a connection to better understand what they are trying to explain. Overall, I recommend this article. I had learned a lot about the tool and will be more confident using it in the future now that I understand its use and how it works.

Source: https://docs.gradle.org/current/userguide/what_is_gradle.html

From the blog CS@Worcester – Austins CS Site by Austin Engel and used with permission of the author. All other rights reserved by the author.

The Single Responsibility Principle

One of the topics of this class that I don’t know much about is SOLID. Most of the programming I have done has been very small projects that do not necessitate the use of very many design principles. This is not to say they should be applied but they add quite a bit of extra work to something that doesn’t require very many lines otherwise.

Because of my lack of experience with it, I chose to learn a little more about SOLID starting with the “S” – Single Responsibility Principle. I found an article from stackify.com to explain it further.

The principle is self-explanatory. Uncle Bob describes it as “A class should have one, and only one, reason to change.” This is important because it makes your software easier to implement and prevents unexpected side-effects of future changes.

When a class has multiple responsibilities, these responsibilities are no longer independent of each other. If one responsibility needs to change, the more often the class needs to be changed. This may not seem like a big deal but if some things depend on the changed class you may need to update dependencies of recompile dependent classes. To avoid having to change many components to make a single change, give each class only one responsibility.

It also makes your code easier to understand. If there is a problem somewhere it is easier to isolate the problem.

While each class should have one responsibility, this shouldn’t be taken too far by, for example, making each class have only one function.

The article also provides some real-world examples showing the Single Responsibility Principle in action.

I am often guilty of violating this principle. For a project I once made a Pokémon battle simulator. Looking back now I really broke this principle with that one. I had a class to make Pokemon objects and another to do everything else. Because it was for a database course, I connected to the database and had a battle method all in that class.

For the final project I will have to make sure I do my best to stick to the SOLID principles and not get caught in just making the code work. Because it is a group project, I need to be sure the code is easy to understand to others and not just myself. The Single Responsibility Principle is a big part of that.

From the blog CS@Worcester – Half-Cooked Coding by alexmle1999 and used with permission of the author. All other rights reserved by the author.

5 Design Patterns Every Engineer Should Know

As I was browsing YouTube, a video appeared in my recommended videos titled “5 Design Patterns Every Engineer Should Know” from someone named Jack Herrington. Thinking it would be good review I clicked on the video. I wanted to see if were familiar with the five patterns in the video.

The video discusses patterns from the “OG” design pattern book: Design Patterns by the “Gang of Four”. The five patterns are the Singleton Pattern, the Façade Pattern, the Bridge/Adapter Pattern, the Strategy Pattern, and the Observer Pattern. He explains all of these in order as he goes through the video.

Of these, the only one I was unfamiliar with was the Observer Pattern. He explained it simply as there being a publisher and a subscriber with the subscriber listening for events from the publisher.

Something from the video I found interesting was a compiler as an example of the façade pattern. Often you can’t access all the parts of a compiler and it is abstracted to be usable to you as a consumer of that product.

Below the video in the comments, someone mentioned the Head First Design Patterns book. I remember looking at this book in class before and it reminded me to go find it and look at it further. Unlike the Gang of Four book it is written in Java so I have a bit of an easier time understanding what is going on in the book.

This video was helpful as a reminder that there are many design patterns and many resources to help learn them. The final project includes using design patterns so I will look back at these resources to identify what patterns will be helpful in the situations I encounter as I work on the project.

 It was also a helpful reminder that design patterns are not necessary everywhere. Many people in the comments posted about knowing when to use design patterns. There are tradeoffs and consequences to using certain design patterns and it is important to take these into account when choosing to use a pattern in a situation. For example, using the singleton pattern makes life simple. Using it for something like a database driver makes accessing data easy, but it also makes your system inflexible. Whoever is the consumer that is using the database driver also has to have that on their computer to be able to access the database.

From the blog CS@Worcester – Half-Cooked Coding by alexmle1999 and used with permission of the author. All other rights reserved by the author.

YAGNI Design Principle & Redundancy

Photo by Nataliya Vaitkevich on Pexels.com

Oftentimes, when programming in an object-oriented language, I have the issue of unintended redundancies. I write things to be too verbose; long variable names (studentClassId, carManufacturerName), with unnecessary complications, methods and variables that could easily be removed from my code without losing anything. My reasoning in these cases is always ‘this will make my code easier to read’, or ‘specificity is always a good thing’, but more often than not, this results in messy code with complicated loops and if-statements, where a simpler approach would be much easier to work with in the long run. Over time, larger projects can get to be a huge issue, the more convoluted the code becomes, the harder it is to look at and understand after a few days.

A good example of this problem would be to imagine a simple program which simulates various cars. Instead of having a central car class which handles the definition of a car, (wheels, doors, engine etc), I might have a car class which has instances of wheel, door, and engine classes, which have their own instances of ‘wheelTireType’ (which can be one of three types of wheels), and also similarly needless complication for the doors and engine.

While being specific can be a good practice some of the time, I tend to take it overboard sometimes and end up making classes like ‘carDoorType’ when I could have just as easily had an integer ‘numberOfDoors’ variable and gotten the same effect without introducing an extra, functionally useless class.

When reading an excerpt from Google’s testing blog, I found the principle of YAGNI (“You Aren’t Gonna Need It”) to be of interest. The idea is that you should keep an eye out for unnecessary code and remove it/refactor your code without the unneeded parts. The blog post gives a good list of “code smells” associated with the YAGNI design principle, including code which never executes (“Just in case” code), code which is only executed by tests, and is never used in the actual running of the program, and variables which are redundant.

Out of all of these issues, I definitely struggle the most with redundancy, and recognize that it is something I need to work on overall. Many times while writing Java code, I have created methods and classes simply out of the belief that I “may” need them later on and that this saves me time spent creating these classes later. While this makes sense at the time, coming back to the code later I just end up with a lot of unused classes which end up getting deleted anyway, negating any time savings.

I suspect that going back to some old projects and attempting to refactor them with the YAGNI design principle in mind would be a good way to practice. While it seems rather self-explanatory at first, I think that approaching projects with the intent of preventing redundancy will produce considerable improvements in any future designs going forward.

Site Referenced: https://testing.googleblog.com/2017/08/code-health-eliminate-yagni-smells.html

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

What’s the difference between JavaScript and Java?

 What is Javascript?

It’s a scripting language that runs in a browser, and Javascript can do almost anything on a Web page:

HTML can be manipulated, providing a tool to change HTML at runtime. Events can be attached and executed, in line with the idea of event-oriented programming. The data verification function verifies the validity of the form of data when submitting the form. The operation of the client’s browser: forward, backward, refresh, jump, open a new window, print, etc. Cookies can be created and used.

What is Java?

Java is a programming language introduced by Sun. It is an interpreted language with syntax rules similar to C++. Java is also a cross-platform programming language. The program written in Java language is called “Applet” (small application program). After compiling it into class files by the compiler, it is stored in the WWW page and marked on the HTML file accordingly. As long as the client software of Java is installed, the client can run the “Applet” directly on the network. Java is well suited to enterprise networks and Internet environments and is now one of the most popular and influential programming languages on the Internet. Java has many remarkable advantages, such as simplicity, object-oriented, distributed, interpretability, reliability, security, structural neutrality, portability, high performance, multithreading, and dynamism. Java dispenses with C++ features that do more harm than good and many that are rarely used. Java can run on any microprocessor, and programs developed in Java can be transmitted over the network and run on any client.

Different data types

Java has eight data types: byte, short, int, long, float, double, char, and Boolean, while JavaScript has three data types: number, String, and Boolean.

In addition, there are differences in Java and Javascript variables.

They are positioned differently

Unlike Java, which is a completely object-oriented programming language that requires you to design objects before you can write in Java, JavaScript is an object-oriented scripting language that provides developers with built-in objects, making it easier and less time-consuming.

Link in different ways

Unlike Java, which USES static linking, where object references must be made at compile time and the compiler needs to implement strong type checking, JavaScript USES dynamic linking, where object references can be checked at run time.

Different USES

The most essential difference between them is their usage. At present, Java is widely used in PC terminal, mobile terminal, Internet, data center, and so on, while JavaScript is mainly used to embed text into HTML pages, read and write HTML elements, control cookies, and so on.

Java and JavaScript have different strengths and different specialties. The Java arena is programming, while JavaScript’s heart is in Web pages, where it can do almost anything.

Sourses:

https://www.upwork.com/resources/java-vs-javascript-what-is-the-difference?gclid=Cj0KCQiAwMP9BRCzARIsAPWTJ_G1ymcXEZzbxXRSv4C38P8hTynhLvbfWVea1UEjHNZfbiRwSMScx9kaAgftEALw_wcB

From the blog haorusong by and used with permission of the author. All other rights reserved by the author.

The Power of Functional Programming

As I have started to learn some about Javascript, I am very intrigued by the new territory and the strangeness that comes with it, at least for someone like myself, with most of my experience coming from object oriented programming languages like Java and C. As I now know, Javascript is a functional programming language, which has some fundamentally different structures and uses. For this reason, I have started to looked into the usefulness of functional programming, as languages like Javascript and Python are quickly on the rise. I found an article on Xiaoyun Yang’s personal blog entitled Why Functional Programming From A Developer Productivity Perspective which has helped me make some more sense of the intent and uses of functional programming. The article starts with basic info on FP, stating how object oriented programming came to popularity in the 80s with the use of GUIs and how, “it’s easier to program things that use a fixed number of operations for an unlimited number of operation,” but how now, “stateful programming is more of a liability” since, “there is an increasing emphasis on asynchronous, distributed, multi-core and cloud computing.” The article then dives into FP design patterns, which explain its usefulness. The intent is for functions to act as, “pipes for data to travel through,” with Higher Order Functions taking functions as input, and polymorphic function adding to reusability and versatility. The first pattern is the Loop Pattern. The emphasis is on abstraction. In the example, for loops are used for arrays of different types, and the goal is to get rid of the type by, “[parameterizing] the loop action as a function parameter and the initial value as a data parameter.” This provides for the reusability of the function in different contexts. The next pattern is Types. The article compares Scala being type-safe to Javascript. This means, “you can impose the argument type and return type when you first define your function in Scala.” This means for non-type-safe languages like Javascript, the onus is on the programmer to ensure clashing types do not lead to errors. While sometimes type inference in Javascript can be convenient, it can create problems when working with different types. The third pattern is Monads. This means that one can use monads instead of, “hard coding error handlers,” with a monad essentially being a wrapper. There are so many errors to worry about when handling user input, so this is advantageous. The last pattern is Monoid. An example is given for a function to find is any strings in array(s) are not empty. It shows that whatever order the arrays are given to the function, or wherever the unempty string exists, the function still works, preserving associativity and commutativity. Monoid laws help verify correctness. The article finishes by stating that FP promotes reusability and modularity through abstracting functions. This is all new to me and I hope this knowledge helps me soon, as the next language I intend to learn will be a FP language like Javascript or Python. It is essential to keep up with the fast-paced world of computer science.

From the blog CS@Worcester – Marcos Felipe's CS Blog by mfelipe98 and used with permission of the author. All other rights reserved by the author.

Uses, Drawbacks, and Additions to JavaScript in 2020

Photo by cottonbro on Pexels.com

In web development, the development of web applications (software accessed through a web browser) and even game development, JavaScript is used to add interactivity and function to what would otherwise be static webpages, and to create software which runs entirely within users’ web browsers. And while JavaScript is undoubtedly useful in the contexts of web and software development, there are some aspects of the language which I feel are somewhat lacking compared to other programming languages.

For one, compared to its namesake Java, JavaScript is somewhat lacking in terms of its ability to create objects. While objects are a part of JavaScript, creating classes is very nonspecific compared to Java. For example, say I want to create an apple class in Java and in JavaScript, for Java, I would need to create a separate class file:

public class Apple {
   String color;
   public Apple()
      {
       color = "red";
       System.out.println("I am a " + color + " apple!");
      }
}

Whereas with JavaScript, it would look something like this:

class Apple {
  constructor() {
   this.color = "red";
   console.log("I am a " + color + " apple!");
  }
}

While not being strongly typed does have advantages (flexibility of variables, ability to write code which returns a different type depending on context/necessity) I prefer the strong typing of languages such as Java and C#. Strong typing helps to make code more readable, without specifying the type of a variable before using it (ie: var fruit = “apple”;), it can be unclear what a variable is intended for at first glance (especially if there are many similar variables storing similar values). With strong typing, you are always clear on what type of data is meant to be stored inside of a particular variable, (int studentID is clearly only meant to store integer values, while String studentName is only meant to store String values).

JavaScript continues to grow and develop as a language, and new features are constantly being implemented. When reading about some of these new features being added to JavaScript this year, I found a blog post discussing some of the more interesting features which were implemented in 2020. The post served as a good introduction, and offered clear information about each of the new additions discussed.

Private & Static Fields

Something which was absent from JavaScript was the ability to use access modifiers for fields. This year, the ability to use private, or static fields was added to JavaScript; private fields will allow for greater security and the ability to ‘wall off’ access to certain fields, while static fields will allow for the creation of ‘class-scope’ attributes.

BigInt

Another complaint which I have had about JavaScript is the fact that JavaScript only has one number type. While the introduction of the BigInt type does not solve this issue, it does allow for larger numbers to be represented in JavaScript. It functions similarly to the Java ‘Long’ datatype, in that it can store very long number values.

While JavaScript is still missing some features which I enjoy from other languages, these recent additions make it more versatile than ever, and JavaScript continues to be the de-facto language for developing anything interactive on the internet.

Site Referenced: https://www.telerik.com/blogs/latest-features-javascript-ecmascript-2020

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

Refactoring

https://www.agilealliance.org/glossary/refactoring/#q=~(infinite~false~filters~(postType~(~’page~’post~’aa_book~’aa_event_session~’aa_experience_report~’aa_glossary~’aa_research_paper~’aa_video)~tags~(~’refactoring))~searchTerm~’~sort~false~sortDirection~’asc~page~1)

This week we’ll be covering refactoring which is a very simple but also very important concept to software design similar to models, the topic I covered last week. The reason why I’ve chosen to talk about refactoring is because while it’s a topic that hasn’t been specifically covered in class; I have had experience learning about a form of refactoring in this software process management class I’ve been taking. According to the link above, refactoring is the process of improving the overall structure of a program’s source code. However, this does not mean that the functions of the program are altered in any way. For example, the interface is not improved on, bugs are not fixed, and code isn’t outright rewritten to change the behavior of the program. Refactoring instead cleans up and organizes the source code in order to be more easily readable and understood. An example of this would be simplifying the two lines “answer = 2 * 5;” and “answer = answer * 8;” into the line “answer = 2 * 5 *8”. This change simplifies the code and makes it easier to understand at a brief glance. On a smaller scale, refactoring can be used to remedy code smells and remove duplication. But on a larger scale, refactoring can alter large bodies of code towards different design styles such as object oriented or functional.

The benefits to refactoring do not end at organization and raising code readability. Refactoring also encourages the use of reusable design elements and code modules. These reusable elements and modules highlight the structural similarities and differences in each code module. Refactoring also improves attributes of code that cause easier maintenance like length, duplication, coupling, cohesion, and cyclomatic complexity. Since refactoring often simplifies source code, the length and complexity are also often times lowered which again makes code easier to read. In order to efficiently refactor code, the dependencies (cohesion) and independencies (coupling) of each module will have to be highlighted in the overall structure of the code. And in the case of duplication, it has already been stated that refactoring can remove it from source code. All of these benefits return back to the intended purpose of refactoring, improving the overall structure of a program’s source code by cleaning and organizing it. It’s a form of proofreading and revising code but also comes at the risk of accidentally changing the behavior of a program. So individuals using refactoring should have a good grasp on which part of their code does what in order to avoid that issue.

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

Don’t be Overwhelmed by Refactoring

As I’ve mentioned previously, I taught myself how to code a few years ago. I’ve learned a lot more since then, but I’m always learning. The other day, I had an assignment for another course that involved going back and refactoring old code. Since it was so bad, I’d like to discuss it.

Concept

The code itself is a terminal based Java calculator. I imagine it was really tricky for me at the time considering the way in which I implemented it. I didn’t know about the static keyword nor about how to use methods. This serves as a great example of what not to do:

The Original Code

Now, the code itself is so horrendously bad that I have to get creative to even display it. So here’s a few entertaining lines. Keep in mind the entire program is within the main method:

int load;
double num1, num2, ans;
boolean on, autoclose, autocontinue, loading, numchecking, divide, multiply, add, subtract, other, help;
String in, in2, in3, in4, in5, operation, fa, status1, status2, status3;
char op;

Now, a sane person might ask “Why are there so many variables and why are many of them named so badly?” Well the reason is because I didn’t use methods. I used variables to separate control flow. I also find it funny that I had a String for every user input rather than just reusing one, as well as the fact that I declared all variables at the top for no reason. Here’s an example of that horrible control flow in action:

in = input.next();

if (in.equals("/")) {
	divide = true;
	numchecking = true;
	operation = "divide";
	fa = "by";
	op = '/';
}

else if (in.equals("*")) {
	multiply = true;
	numchecking = true;
	operation = "multiply";
	fa = "by";
	op = '*';
}

I would ask for input, set these variables, and then later on:

if (numchecking) {
	Thread.sleep(1000);
	System.out.println("Enter your first number.");
	num1 = input.nextDouble();
	System.out.println("Enter another number to " + operation + "  " + fa + " " + num1);
	num2 = input.nextDouble();

	if (divide) {
		ans = num1 / num2;
	}
	if (multiply) {
		ans = num1 * num2;
	}
	if (add) {
		ans = num1 + num2;
	}
	if (subtract) {
		ans = num1 - num2;
	}

	Thread.sleep(3000);
	System.out.println("Calculating...");
	Thread.sleep(1000);
	System.out.println(num1 + " " + op + " " + num2 + " = " + ans);

I have no idea why I used if else previously but not here. I can understand I didn’t know how to use a switch statement yet I guess. Anyway, I used Thread.sleep() to add artificial delay for some reason in the program. This code I’ve shown is pretty tame honestly. Notice the line counts. I recommend taking a look at the original source code so you can really appreciate how horrible it is. Unfortunately, I had to convert the .java file to a .docx file to upload it to WordPress:

The Refactoring Process

I find myself fall into the same hole: When I realize I can do something in a better way but it’s large and intimidating, I prefer to start from the beginning rather than modifying the current product. Sometimes, that is extremely useful and you just need a solid clean start. However, often that’s overkill and wastes time. I tend to do that even in video games.

As an example, one of my all time favorite games is Factorio which is an indie game about building factories and trying to automate everything. The goal of the game is to get the game to play itself. Anyway, I have over 500 hours in this game and I haven’t actually reached the end goal of launching a rocket. It’s not because I don’t know how to do it or I die too quickly. It’s because I’m never satisfied with my factory layout or my world generation settings. When it comes to world generation, I do actually have to start over. When it comes to factory layout, I could take the time to manually replace the entire layout and keep my current research. Despite that, I almost always start over.

The saving grace with code is that, when its scale is manageable, it can be incredibly fun and relaxing to refactor. Sometimes it’s tough to get started but once you do, it’s a really fun time. I honestly had less trouble refactoring as I did with the assignment itself. The assignment wanted me to make a change based on a guide. Make the change, write it down, and continue. However, I fell into refactoring and made change after change extremely quickly. With code this bad, it was really easy to just aim at one thing and make 40 changes that all fit into unique categories. So I prioritized refactoring the code well over documenting it well.

Virtually all of those variables I had before are gone. Here is the refactored beginning of the code:

private static final String[] OPERATORS = {"+", "-", "*", "/"};
private static Scanner scanner;
private static boolean autoContinue;
private static boolean autoClose;
private static boolean continueOnce;

public static void main(String[] args) {
    boolean programIsOn = true;

You’ll notice I made use of static variables. I only have one variable in the main method and it controls the loop of the program. Other variables are now in methods or simply don’t exist. I even created an array of operators to allow for easier expansion of functionality later on, despite the fact that I’ll almost certainly never come back to this project. I also have 3 booleans on 3 separate lines. This is my personal preference, but with only 3, I would understand simply writing: private static boolean autoContinue, autoClose, continueOnce; I just tend to lean on keeping things on separate lines. Although now that I’ve written that, I kind-of do prefer that. Although it would mess up the width aesthetic going on because it’s such a wide line.

Before, I showed part of how I took in user input and managed arithmetic operations. I set a bunch of variables and handled it later. Here’s how I manage it now:

private static void handleOperations() {
    String operation = scanner.next();
    System.out.println();

    if(isArithmeticOperator(operation)) {
        arithmeticOperation(operation);
        return;
    }

    switch(operation) {
        case "help":
            help();
            continueOnce = true;
            break;
        case "exit":
            autoClose = true;
            break;
        default:
            System.out.println("Sorry, I don't understand that operation. Try again.");
            continueOnce = true;
    }
}

I created a method to handle it that is called in the main loop. It has good variable names, uses a switch statement, and calls methods that have descriptive names. It could be better but it is leagues better than what it was before. Originally in the refactoring process, I had:

private static boolean doUserRequestedMethod() {
    switch(scanner.next()) {
        case "/":
            divide();
            break;
        case "*":
            multiply();
            break;
        case "+":
            add();
            break;
        case "-":
            subtract();
            break;
        case "help":
            help();
            return true;
        case "exit":
            autoClose = true;
            break;
        default:
            System.out.println("Sorry, I don't understand. Try again.");
            return true;
    }

    return false;
}

It returned a boolean value to allow the loop to continue if it needed to, such as if the user entered an unknown command. I replaced that with global (static) variables to control that. I renamed the method for clarity, and I created a single arithemticOperation() method to avoid code repetition. However, that function itself needed a switch statement, so rather than check the operation twice, I split off the arithmetic operations from the original switch statement in a way that allowed me to add more arithmetic operations in the future. I’m pretty happy with that solution.

Lastly, since I showed how the numbers are calculated originally, I should show that in the refactored version. First I have to check if the input was for an arithmetic operation:

private static boolean isArithmeticOperator(String potentialOperator) {
    for(String operator : OPERATORS) {
        if(potentialOperator.equals(operator))
            return true;
    }

    return false;
}

This was part of why I created the OPERATORS array, so that I could avoid a long boolean of &&s. Then for the actual calculation:

private static void arithmeticOperation(String operator) {
    System.out.println("Enter a number: ");
    double leftOperand = scanner.nextDouble();

    String partialEquation = leftOperand + " " + operator + " ";
    System.out.print(partialEquation);

    double rightOperand = scanner.nextDouble();
    double result = leftOperand;

    switch(operator) {
        case "/":
            result /= rightOperand;
            break;
        case "*":
            result *= rightOperand;
            break;
        case "-":
            result -= rightOperand;
            break;
        case "+":
            result += rightOperand;
            break;
    }

    System.out.println(partialEquation + rightOperand + " = " + result);
}

Again, you’ll find decent variable names and a more clear control flow. Obviously this code isn’t flawless but that’s not the real goal in refactoring. The point of refactoring is to create an improvement. You’ll never have perfect code, but you can always improve your code. This is pretty analogous to life itself. Recognize the value and functionality currently there, recognize that you will never be perfect, but always aim to be better.

Here is the current state of the refactored code. It’s honestly amazing how much better it is:

Conclusion

Refactoring is not something to be feared; it should be enjoyed. There is something very relaxing about it if you enter it with the right mentality. Focus on small things you can easily tackle that would make a big improvement and do that. As you slowly cross off changes you need to make, it’ll become more manageable and more readable. In that program above, I cut the number of lines in half after refactoring. I can actually read it and understand what it’s doing. It should be satisfying to go through and make progress towards simplicity and organization. You just have to want it.

From the blog CS@Worcester – The Introspective Thinker by David MacDonald and used with permission of the author. All other rights reserved by the author.