Category Archives: CS-343

Smelly and Debt

I recently read an article on Opsera titled What Is Code Smell? that explores the concept of code smells and how they relate to technical debt. The article explains that code smells are indicators of deeper issues in software design, like redundant code, overly complex functions, or lack of proper documentation. While these smells don’t necessarily cause bugs, they can make the code harder to maintain or extend in the future. Technical debt, on the other hand, refers to the trade-off between short-term efficiency and long-term code quality. It’s like borrowing from the future to meet deadlines now, but it eventually has to be repaid with interest—usually in the form of extra work to fix the issues caused by the shortcuts taken.

I chose this resource because it gives a practical explanation of two topics that I’ve encountered in my software engineering classes: design smells and technical debt. These are concepts that seemed theoretical at first, but this article helped me understand how they show up in real-world projects. As I start working on my own coding assignments, I can see how these issues might impact my projects if I don’t pay attention to them early on.

The article made me realize just how crucial it is to identify and address code smells early in the development process. For example, the article points out that long methods and duplicated code can be a sign of poor design that will slow down future changes. At first, I thought that refactoring or improving code design was something only necessary when a project was nearing completion. But now I understand that addressing these problems early can save a lot of time and effort in the long run.

What really stood out to me was the connection between technical debt and long-term project maintenance. As a student, it’s easy to think that as long as the code works, it’s good enough. But this article emphasized that taking shortcuts to meet deadlines may create technical debt that leads to problems later, such as bugs or a codebase that’s difficult to work with. I’ve already seen this in my own projects—trying to push through a solution quickly, only to realize later that the code is harder to manage than I expected.

In the future, I plan to pay more attention to clean code practices. I’ll aim to refactor code regularly and avoid taking shortcuts that might seem like a quick fix but could lead to bigger problems. This approach will not only improve my coding skills but also make my future projects more maintainable.

Resource:

What Is Code Smell? – Opsera Blog

From the blog Computer Science From a Basketball Fan by Brandon Njuguna and used with permission of the author. All other rights reserved by the author.

Understanding SOLID Principles: A Guide

As a student learning software design, I’ve heard about the SOLID principles in class, but I wanted to dive deeper to understand how to actually use them. I came across a blog post called “SOLID Principles — The Definitive Guide” by Midhun Vincent on Medium, which breaks down each of the five principles in a way that makes sense for someone new to object-oriented design. The guide was really helpful and lined up well with what we’re covering in my course, so I thought it would be a good opportunity to see how these principles could improve my coding now and in the future.

The article explains the SOLID principles, which are five important guidelines for creating object-oriented software that’s easier to understand, maintain, and extend. The first principle, the Single Responsibility Principle (SRP), says that each class should do only one thing, making it easier to maintain and modify. The Open/Closed Principle (OCP) suggests that classes should be open for extension but closed for modification, meaning you can add features without changing the original code. The Liskov Substitution Principle (LSP) ensures that subclasses can replace their parent class without breaking the system. The Interface Segregation Principle (ISP) advises creating small, specific interfaces rather than large, general ones. Finally, the Dependency Inversion Principle (DIP) suggests that high-level modules should depend on abstractions, not low-level modules, which makes the code more flexible. These principles help make code cleaner, more modular, and easier to adapt over time.

I picked this article because, while the SOLID principles are useful, they can seem pretty abstract at first. The post explains them in a way that feels practical, with examples that make it easier to apply the principles to real-world coding problems. Plus, the examples connected well with the projects I’ve worked on in my course, especially when it comes to organizing code and making it easier to debug. Seeing how these principles prevent code from becoming too messy gave me a new way of thinking about my own assignments.

My Takeaways and Reflection

Before reading this post, I knew the basic ideas behind SOLID, but I wasn’t sure how to apply them in my own code. Now, I get why each principle is important and how they can save time by reducing debugging and refactoring. For example, the Single Responsibility Principle made me realize that I often give classes too many responsibilities, which complicates fixing bugs. By applying SRP, I can keep things simpler and reduce errors.

Looking ahead, I plan to use these principles in my projects, especially the Open/Closed Principle and Interface Segregation Principle. I can see how they’ll help me write code that’s easier to update and adapt. Understanding SOLID will definitely give me a strong foundation as I take on more complex projects in the future.

Resource:

View at Medium.com

From the blog Computer Science From a Basketball Fan by Brandon Njuguna and used with permission of the author. All other rights reserved by the author.

Anti-Patterns

Source: https://www.freecodecamp.org/news/antipatterns-to-avoid-in-code/

This article is titled “Anti-patterns You Should Avoid in Your Code.” It specifically mentions six of them, being: Spaghetti Code, Golden Hammer, Boat Anchor, Dead Code, Proliferation of Code, and the God Object. An anti-pattern, in regards to software development, is an example of how not to solve a problem in a codebase. They are not a positive thing, they are examples of practices to avoid in the development process. Anti-patterns lead to technical debt, code that you have to eventually come back to and properly fix later. Spaghetti Code is the most common, it is code that doesn’t have much structure. It is called Spaghetti Code because everything is difficult to follow, files are located in random places, and when visualized in a diagram, it appears to be a jumbled mess, much like spaghetti. Golden Hammer references a scenario where you follow a certain process that doesn’t necessarily align perfectly with the project but still works well enough. This may not seem like a large issue, but is obviously not the best practice to follow because it’ll cause performance issues in the long run. You should always use a process that is the best fit for your project, even if you need to teach yourself or learn something new. Boat Anchor is when developers leave code in the codebase that isn’t actively being used in the hopes of it being needed later and thus not requiring much effort to implement when it is eventually needed. The main problem with this is when it comes to maintaining the code. It leads to the question of what code in the codebase is unused and what is being actively used. Trying to fix a bug in the system on code that isn’t even being used is a time waster. Dead code is code that doesn’t look like it’s really doing anything, but it is being called from many different places. This leads to problems when trying to modify the code because no one is unsure what is actually dead. Proliferation of Code is about objects that have the purpose of invoking a more important object, meaning it doesn’t really do anything on its own. The action of invoking the more important object should be set to the calling object. Lastly, the God Object is an example of an object that does too much. Objects should only be responsible for doing one thing, referencing the Single Responsibility principle in SOLID. 

I chose this particular source because I appreciated the way examples were clearly given along with the 6 examples of anti-patterns, and upon reviewing the syllabus the topic “anti-patterns” seemed interesting. When you’re learning computer science a lot of the time you’re learning about things that you should do and not about things that you shouldn’t do. I really enjoyed reading about these 6 examples of common mistakes that developers make in industry. It’s important to both recognize good and bad practices to ensure that your projects are properly optimized. I can definitely see myself referencing anti-patterns when designing code in the future so my code can easily be maintained. 

From the blog CS@Worcester – Shawn In Tech by Shawn Budzinski and used with permission of the author. All other rights reserved by the author.

How REST API’s Shift Front-end Development

11/16/2024

REST is a crucial topic in APIs in which I just began to learn about this semester. Before this, I had never heard of REST API so I assumed it would be a challenging concept to grasp since I had no prior knowledge regarding this style.

This text dives into the definition, explanation, and exploration of what REST is, how it is used, and how we can get the most out of it in certain services. The text highlights the importance and nuances of REST API’s while still idolizing their importance of implementation.

Initially, during classes I found the material hard to grasp since I had no idea as to what Rest was and how it worked. However, everything began to make more sense when we started working with the hands-on assignments involving actual API calls.

I learned that with certain API calls you are able to retrieve, post, edit or delete information from the backend. These important methods are called HTTP methods which play a key role in manipulation, addition, or removal of information.

A couple key concepts that I learned based off of the reading are that REST APIs are cacheable, which are essential for improving performance and managing network traffic due to its cache technique. The reading also gives insights into how API’S are considered a layered system, in which it allows you to add proxies and gateways. These are very important concepts to keep a mental note on for the future as working in a frontend environment, especially when accessing backend data.

I expect to use these resources for building websites or even mobile applications, ideally when scalability and flexibility play an important role on what I am working on. I also learned that Resp API’s work alongside Node.Js and Express.Js. Node.Js is a back-end JavaScript runtime environment, while Express.Js is a web application framework for Node.Js. This relatively new information to me, due to my experience only using C++, Java, and Python for specific applications.

Rest API’s can be tested by integrating parameters and seeing how the output compares to the expected output, while also ensuring the correct error codes are being returned for methods like GET, POST, and others. The text also mentioned endpoints, and while I grasp the basic understanding, there is still more to learn in order to increase my confidence with this REST APIs Overall, I expect to use this knowledge and information in future jobs, as per my interest in software development, and in my personal projects. Additionally, I learned a bit more about swagger, which was introduced in class to demonstrate the GET, PUT, DELETE, and POST methods of the Rest API.

Source: The REST API Handbook – How to Build, Test, Consume, and Document REST APIs

From the blog CS@Worcester – Cinnamon Codes by CinnamonCodes and used with permission of the author. All other rights reserved by the author.

Misconceptions with OOP

I chose the blog post, “People Don’t Understand OOP” by Sigma because it addresses recurring challenges in programming, specifically around OOP. Understanding how to improve my approach to OOP principles would help me write cleaner, more effective code that’s easier to maintain and adapt over time. Not following these concepts has led to messy code in previous years. Personally, I feel like I made a lot of these mistakes when I first started coding, however as more classes have gone by I have been able to break some of these bad habits. Unfortunately, there are times when I will make these mistakes when coding without thinking so that is what led me to choose this blog post, so I can learn how to not make these mistakes in the future.

The blog post  explores common misunderstandings surrounding Object-Oriented Programming (OOP). The author, Sigma,  argues that misconceptions often stem from oversimplified metaphors and an incomplete grasp of fundamental principles like encapsulation and abstraction. Frequent mistakes include equating OOP with buzzwords like inheritance and getters/setters, while neglecting its core concepts such as bundling related state and behavior into cohesive units (objects) and minimizing dependencies through proper encapsulation.

The post highlights that encapsulation is not merely about hiding internal state but about reducing interdependencies and ensuring modularity. Public properties, often critiqued for exposing internal states, are likened to getters and setters in their inability to prevent object coupling. The author points out that real-world OOP is much more nuanced, involving trade-offs that depend on the problem domain and language constraints. A detailed comparison of popular languages, including JavaScript, Python, Rust, and Go, demonstrates varying implementations of OOP features like inheritance, subtyping, and encapsulation. 

From the article, I was able to rethink my use of OOP principles and highlighted that simplicity and adaptability should be the goal when programming. Going forward, I plan to be more thoughtful about whether OOP concepts like inheritance are necessary or if simpler, more flexible design choices would work. The article taught me that well-designed OOP should evolve naturally rather than forcefully adhering to principles. This perspective will help me develop solutions that adapt to change more easily, making my work in software development more efficient and adaptable. After reading, I feel like I will be able to not make as many mistakes that lead to inefficient use of OOP creating a better and more efficient workflow when coding.

From the blog CS@Worcester – Giovanni Casiano – Software Development by Giovanni Casiano and used with permission of the author. All other rights reserved by the author.

Blog Post Week 10

This week, I found an article questioning the relevancy of UML as Agile development processes are becoming more and more used today. This was an interesting article for me to read as it points out some of the flaws with trying to use UML while developing software with Agile, but also a couple of potential ways it can still be useful. The overall notion I got from reading this article was that UML has it’s time and place, but it is certainly becoming a thing of the past as developers start to lean more toward an Agile development process.

The article states that in an Agile environment requirements are typically not defined in detail prior to starting the project, as well as the design of the software. As the project progresses, the requirements and design will usually evolve over time. Also, formal documentation during a project isn’t as much of a necessity while going through an Agile development process. These three big components of Agile clash quite a bit with trying to implement UML as UML pretty much requires the exact opposite of these three components. Basically, you can’t define the design and details prior to the project because of insufficient information which you would need with UML, and it would also need a lot of effort to update the UML diagrams as the project evolves.

There are a couple ways UML diagrams could still be useful as listed in the article as well:

Once development is completed, it may be helpful to use UML diagrams to support the system. Using UML to define and standardize the architecture would also be another reason to still practice it.

I think, as I stated earlier, there is a time and a place for using UML. Obviously, if you haven’t adopted an Agile development process then UML could still be on the table to use; most people do use Agile now though. Because of this, you can certainly still use UML diagrams, but if you want it to be in an efficient manner, it should be used in one of or both of the ways mentioned directly above. It’s still great to have the knowledge of most certainly, as UML from what I’ve read and heard other people speaking isn’t completely outdated, but it definitely isn’t going to be something worth stressing over if you’re not the most knowledgeable on how it works.

From the blog CS@Worcester – RBradleyBlog by Ryan Bradley and used with permission of the author. All other rights reserved by the author.

Studying Fundamental Design Principles in Java

This week, I am sharing a blog post related to software design principles written by Alex Klimenko, a well-versed Java developer with experience in building applications, performance optimization, and multithreading. This blog was selected based on the relevance to our course topics and the relation being drawn to Java. Please consider reading Alex’s full blog here.

Klimenko’s post covers three main principles DRY, KISS, and YAGNI, all of which are vital for avoiding common coding pitfalls and ensuring that we are writing code that others will use and that our future-selves can be proud of. The writer’s description of these principles allowed me to grasp the concepts on a deeper level and learn about how they can really make a difference when properly implemented.

The DRY principle is an acronym representing the phrase “Don’t Repeat Yourself” which Klimenko also equates to “Do It Once”. This blog explains this concept by focusing on the root, which is that no repetition leads to less code, resulting in less errors, which means that the code, itself, is easier to maintain and update throughout time. Klimenko encourages the use of encapsulated utility classes and methods for common tasks, the use of polymorphism and inheritance to avoid duplicating code, and employing design patterns like the Template Method to refactor common behaviors.

The KISS principle can be spelled out as “Keep It Simple, Stupid” and really sticks out to me as I know I have encountered issues in this realm previously. This principle has the goal of favoring straight-forward solutions over unnecessarily complex solutions. To do this in Java, Klimenko provides many implementations ranging from encouraging clear and concise naming conventions, following Java’s best practices such as those from Java Code Conventions and Java Language Specification, and making use of standard libraries and frameworks.

The YAGNI principle represents the phrase, “You Aren’t Gonna Need It” which, in software development, equates to the concept of avoiding adding functionality/complexity to code until it is required by the customer’s current specifications. The writer phrases this as avoiding “speculative development” or thinking about future needs that are not yet even in existence. A few of the ways Klimenko relates this principle to Java is by encouraging a minimalistic class design, lean dependency management, and avoiding premature optimization.

After reflecting on all that this blog has helped me to understand, I have become much more aware of some of the poor qualities that likely exist in my own code, but I also feel like I am prepared to begin attempting to apply these concepts in my work so that I can gear myself towards becoming a better programmer with sound principles. Mastering these principles will take years of practice, but to begin applying them now, as a student, I can ensure that my approach to coding and the implementation will constantly be improving.

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

SOLID

SOLID is an acronym for a set of design principles for object-oriented programming that is used to help developers create flexible, efficient, and easily maintainable software. I think the article “SOLID: The First 5 Principles of Object Oriented Design” by Samuel Oloruntoba and Anish Singh Walia does a great job explaining the SOLID principles. I plan on using these principles in the future to further develop my code and to make sure it is easy to read and understand.

Here is what each of the letters in SOLID stand for:

S: Single Responsibility Principle (SRP)
O: Open-Closed Principle (OCP)
L: Liskov Substitution Principle (LSP)
I: Interface Segregation Principle (ISP)
D: Dependency Inversion Principle (DIP)

SRP states “A class should have one and only one reason to change, meaning that a class should have only one job.” Essentially this means that any object or class should be made for one specific function in order to better understand the code.

OCP states “Objects or entities should be open for extension but closed for modification.” The article states that “This means that a class should be extendable without modifying the class itself.” I think this article does a great job explaining what all of the different principles mean as well as giving examples for each of them. I strongly recommend using this website if you’re trying to learn about SOLID.

LSP states “Let q(x) be a property provable about objects of x of type T. Then q(y) should be provable for objects y of type S where S is a subtype of T.” At first, this really confused me. After doing some research and coming across this website, I began to understand this principle more. In simpler terms, it means that every subclass should be a substitute for their parent class. If you need examples to see how this would work, I highly recommend looking at the linked article.

ISP states “A client should never be forced to implement an interface that it doesn’t use, or clients shouldn’t be forced to depend on methods they do not use.” This principle states that software should be broken down into smaller, more specific parts. This is so it doesn’t depend on code it doesn’t use.

DIP states “Entities must depend on abstractions, not on concretions. It states that the high-level module must not depend on the low-level module, but they should depend on abstractions.” In simple terms, both high-level and low-level modules should depend on abstractions, and abstractions should not depend on details.

Link to article: https://www.digitalocean.com/community/conceptual-articles/s-o-l-i-d-the-first-five-principles-of-object-oriented-design#dependency-inversion-principle

From the blog CS@Worcester – One pixel at a time by gizmo10203 and used with permission of the author. All other rights reserved by the author.

Response Codes

In class after learning about a few select HTTP response codes, I wanted to look into the whole library of possible codes to get a better understanding of how website calls work and the potential errors that come with them. The blog I chose to read from gave a brief introduction to why knowing the meaning of the response codes is important for managing or using a website. Before going into the specific definitions of each code, the author states the main takeaways at the beginning of the article which helps the reader know what to look out for as they read ahead.

The codes are representations of the types of responses between the web server and the browser. Every time you use a new URL an HTTP code is generated. The author goes on to explain how making sure you have successful HTTP codes is a good way to promote a website because search engines use the HTTP response codes to determine if that URL will show up as a result.

Next is the part of the article that shows how the first of the three digits are grouped and defined, which I didn’t know and is helpful to know. Some that we didn’t go over in class was 100 codes that are for Informational responses and 300 for Redirection. There is then a reference table provided that gives the corresponding code and definition for each code. The author then goes into more detail about how search engines use these codes to determine what pages get recommended to users.

I think that for myself and how I tend to learn best is by looking up libraries of every possible response/function/use for something and deepening my understanding of a topic and knowing how it works and why it was made that certain way. It will also be helpful as both a developer and a user because now when I see an HTTP response code, I will know what it means and what I would need to do to fix or get around the problem. I also learned how important HTTP response codes are for increasing your website traffic and another reason to have efficient web code for something that I wouldn’t have thought of. Doing outside of class and self-directed research on class topics is very helpful to connect different topics together as well as how they relate to work that is done in the field

Common HTTP Response Codes Explained – Neil Patel

From the blog CS@Worcester – Computer Science Blog by dzona1 and used with permission of the author. All other rights reserved by the author.

The Importance of Design Patterns for Programmers

The article I chose for my blog entry is titled “Design Patterns” from Refactoring Guru. Design patterns are tried-and-true solutions to recurring problems in software design; they act as adaptable blueprints to guide programmers on how to solve design problems effectively in code. This article introduces design patterns, breaking down what they are, their history, and why they are valuable in object-oriented programming. Additionally, it covers why design patterns have become essential for developers, offering a common language for communicating solutions to complex design challenges.

Refactoring Guru’s article is structured into several sections, including “What are Design Patterns?”“History of Design Patterns”“Why Should I Learn Design Patterns?”, and “Criticism of Patterns”. The website offers a straightforward breakdown of why design patterns are essential, teaching programmers how to approach various challenges in object-oriented design. By establishing common concepts and practices, design patterns create a shared language for developers, enabling them to communicate and collaborate more efficiently.

The article also categorizes design patterns into three main types: creational patternsstructural patterns, and behavioral patterns. Each category serves a different purpose in software design:

  1. Creational Patterns – These focus on creating objects in a way that supports flexibility and reusability, ensuring that objects are created efficiently and consistently to allow the project to scale.
  2. Structural Patterns – These organize classes and objects into cohesive structures, making it easier to expand and modify systems. They help parts of a system interact smoothly while staying independent.
  3. Behavioral Patterns – These improve communication and responsibility-sharing between objects, streamlining interactions to reduce complexity and make the system easier to manage.

After reading this article, I have a much deeper understanding of software architecture, especially within object-oriented design. Initially, I chose this topic because I wanted to enhance my understanding of design patterns for a homework assignment. Although we had a class discussion on the topic, I found myself struggling to grasp the purpose of design patterns fully. Learning about the intent behind patterns, including why they are named and applied in specific ways, has helped me see design patterns as as the core in building flexible, maintainable code.

In the future, I plan to use design patterns as a guideline and blueprint for project planning and implementation. I appreciate how design patterns provide a structured approach to problem-solving in software, allowing me to develop systems that can grow and change with ease. Additionally, I value how design patterns enable programmers to collaborate more effectively. By using a shared vocabulary, developers can discuss complex solutions more simply, making teamwork smoother and more efficient.

Overall, this article from Refactoring Guru has not only broadened my understanding of design patterns but also shown me how these patterns are a crucial part of becoming a proficient software engineer.

Sources:

https://refactoring.guru/design-patterns

Citation:

Design patterns. Refactoring.Guru. (n.d.). https://refactoring.guru/design-patterns 

From the blog CS@Worcester – CodedBear by donna abayon and used with permission of the author. All other rights reserved by the author.