Category Archives: CS-343

DESIGN SMELLS AND PATTERNS: WHY QUALITY CODE MATTERS

Writing code involves more than just making it functional, it focuses on creating solutions that are understandable, maintainable, and flexible. Yet, as deadlines approach and requirements change, our codebases frequently reveal subtle indicators that they may not be as robust as they appear. These indicators are commonly referred to as code smells and anti-patterns. In this blog today, we will explore the meanings of these terms, their significance, and how software developers can begin to identify and tackle them in their own projects.

What Are Code Smells vs Anti-Patterns?

A code smell is like a little red flag. It doesn’t necessarily mean your code is broken, but something might be off. Think of it as an indicator of hidden trouble.
An anti-pattern is a commonly used approach or structure that seems reasonable but tends to lead to problems. It’s like following the “wrong recipe” because it looks familiar.
In short, we shall term code smells are symptoms and anti-patterns are traps. Recognizing both helps keep your codebase healthy, especially as your projects grow or you work with others

Five Common Code Smells

Here are five code smells to be aware of, along with simple examples:

1. Duplicated Code

If you notice the same logic appearing in multiple locations, that’s a code smell. For example

def calculate_area_rectangle(length, width):
return length * width

def calculate_area_square(side):
return side * side

Here, calculate_area_square merely duplicates logic. Duplicated code complicates maintenance if a bug is present in one instance, it is likely present in others as well.

2. Large Class / Method

When a class or method attempts to handle too many responsibilities, it becomes difficult to comprehend, test, or maintain. For example, a User class that also manages discount calculations breaches the single responsibility principle. Instead, that functionality could be placed in a separate DiscountCalculator.

3. Long Parameter List

These are methods that require numerous parameters are harder to read and invoke correctly. For example:

def create_user(name, age, address, phone, email, gender, occupation):
pass

Organizing related parameters or encapsulating them within an object can simplify the process.

4. Feature Envy

When a method in one class predominantly interacts with the data of another class, the logic likely belongs in the latter. For example, a get_full_address method in the User class that extensively accesses data from the Address class should probably reside in the Address class.

5. Data Clumps

This refers to a collection of variables that consistently appear together such as street, city, state, postal code and indicates a lack of abstraction. Instead, they should be grouped into an Address class or struct. Having ungrouped data results in redundancy and inconsistencies.

Common Anti-Patterns to Avoid

Here are several prevalent anti-patterns and the reasons they pose risks:

1. Golden Hammer

Dependence on a familiar tool due to personal preference, even when it is inappropriate for the task at hand. For instance, utilizing a list comprehension for side effects such as printing in Python solely because of a fondness for list comprehensions.

2. Cargo Cult Programming

Imitating structures, patterns, or frameworks that you have observed without comprehending their purpose or applicability. For example, incorporating a decorator in Python that serves no significant function merely because other code examples included decorators.

3. Analysis Paralysis

Allocating excessive time to planning, resulting in no actual progress. While planning is beneficial, there comes a time when one must construct, test, and iterate. Over-analysis can hinder advancement.

4. God Object

A class or module that encompasses all functionalities—managing data, processing, displaying, logging, etc. This centralization undermines modularity and increases the risk associated with changes. An example would be a SystemControl class that logs errors, saves data, processes data, displays data, and so forth.

5. Spaghetti Code

Code lacking a clear structure or modularity, characterized by numerous nested loops and conditionals. This complexity makes debugging or extending the code exceedingly challenging. An example includes deeply nested if statements and loops within a single function.

Here’s why you should care as a aspiring developer or even as someone interested in code;

When you write code applying these ideas makes your work cleaner, more maintainable, and often higher quality.
When you show up for internships or team projects, knowing about code smells and anti-patterns gives you a professional edge,you’ll write code that is easier for others to work with. If you eventually lead or participate in code reviews, you’ll be able to spot and explain refactoring opportunities and not just “it works”, but “it works and is maintainable”. As your projects grow, technical debt can bite hard. Early awareness helps you avoid getting overwhelmed by messy code in bigger projects.

Conclusion

Recognizing code smells and anti-patterns isn’t about perfection, it’s about awareness and intentional improvement. By spotting the subtle indicators, you give your codebase and yourself a chance to evolve gracefully rather than crumble under its own complexity. If you want to take a next step: pick one small project maybe an assignment, or one module of your Android app and identify one smell you can fix. Refactor it. See how your code feels afterwards. Because when you clean up smells and avoid traps, your code becomes more than just a working program it becomes something you’re proud of.

References:

https://blog.codacy.com/code-smells-and-anti-patterns

From the blog CS@Worcester – MY_BLOG_ by Serah Matovu and used with permission of the author. All other rights reserved by the author.

The Importance of UML in an Agile World

The Unified Modeling Language (UML) has been playing a part in software development for years as it provided a standardized visual language for modeling the structure of complex systems. But there have been questions about UML and whether it is still useful because the software industry has shifted towards more iterative, flexible Agile methodologies, there have been questions about the relevance of UML. But the article explains that if you look at it closer then UML remains a valuable asset, especially when leveraged appropriately in an Agile context. UML has four main strengths which include visualization, abstraction, standardization, and design documentation. Visualization means that UML diagrams offer a powerful way to visualize and document the static structure and dynamic behavior of a software system. Abstraction is when UML supports modeling at various levels of abstraction, from high-level conceptual diagrams to detailed design specifications. Standardization is since it is a widely-adopted industry standard, UML provides a common language that can be understood by software professionals worldwide. Finally, design documentation means that UML diagrams can serve as a valuable reference for documenting the design of a system, which can aid in maintenance, support, and future enhancements.

Using these strengths there are many ways that UML can make its way into Agile environments. The first is ideation and communication, UML can be particularly useful during the initial stages of an Agile project, quick, lightweight UML diagrams can help the team visualize and communicate their concepts, leading to a shared understanding before diving into implementation. Next is agile modeling, rather than a complex upfront design, Agile teams can adopt a modeling approach where they create diagrams as needed through their current sprints. The third is architectural blueprinting, UML can play a role in defining and documenting the overall system architecture. By having a high level model, teams can ensure consistency and maintainability as the system evolves over time. The final one is knowledge capture and transfer. UML diagrams can serve as pieces for capturing and transferring info, particularly when gaining new team members or supporting the system in production.

The reason I chose this blog post to talk about is because we just recently did an assignment on UML and have talked a lot about it. During this time I always wondered why it was so important or what place it really had in a team of developers. Overall I believe that the blog itself did a great job at making me see why I was so wrong and what really was important. It can adapt so well over time and allows developers a way to help other members understand their work better and to communicate exactly what they are trying to accomplish. I plan to get better at using UML as a skill I can use in jobs to showcase Agile methodologies and hopefully it will help show not only a technical skill but also my ability to work more collaboratively in teams.

From the blog Thanas CS343 Blog by tlara1f9a6bfb54 and used with permission of the author. All other rights reserved by the author.

Refactoring and its Importance to Software Design

In my software construction, design, and architecture class we’ve focused a lot on (believe it or not), the design and structure of software. Software is typically quite intricate and designing it as efficiently and cleanly as possible is almost never accomplished the first time it is coded. “Code Refactoring and why you should refactor your code” by Lazar Nikolov is a great blog dedicated at explaining what refactoring is, why you should use it, and when you should use it.

Refactoring is just the process of identifying technical debt and code smells withing the existing program and modifying the code to be more optimized removing these issues without changing the user interface behavior. As Nikolov describes there are many objectives of refactoring such as increasing readability, maintainability, reusability, optimizing the performance, and enforcing code standards. There are many situations you should consider refactoring in. Such as DRY where you find and replace repetitive information with an abstraction that is less likely to change, or when working with someone else’s “bad” coding that you need to build on.

The key takeaway here is that no programmer does the job perfectly the first time. Programs constantly evolve and have changing specifications that must be met. A good programmer is one who can roll with those punches and change the code as needed. Our most recent homework assignment really focused in on this and had us refactor the code we we’re working with three different times each time using a different architecture. In doing so we learned each time how the previous code could be improves upon to function better and with less bugs even though the original code worked fine. Moving from the strategy pattern to the singleton pattern lastly to the simple factory pattern allowed us to see how each new version after refactoring solved a different problem from the previous. Even though they all worked fine we could see the optimization occurring.

Refactoring is certainly a concept I plan on carrying with me into the future. I’m not sure if there’s a good programmer out there that doesn’t use this concept constantly. Having the ability to constantly adapt my code to best suit it to not only its current task but any future ones that may arise is an incredibly good skill to have. I know it will help me not just as a student at Worcester State but as a professional software developer someday too.

From the blog CS@Worcester – DPCS Blog by Daniel Parker and used with permission of the author. All other rights reserved by the author.

CS343-01: Week (Quarter) Two

Software Constr – Blog Two

In class, we learned two acronyms. DRY which was Don’t Repeat Yourself and YAGNI which meant You Ain’t Gonna Need It. So, I was curious as to what others we had and why we had them in the first place.

When researching on why acronyms like DRY and YAGNI are important, I came across that “in the ever-evolving world of software development, clean, maintainable code isn’t a luxury — it’s a survival skill. As systems grow and teams scale, codebases can quickly become tangled, brittle, and expensive to change.” The acronyms are principles that help us write code that are sustainable and that even though they’re easy to understand, they’re powerful when applied.

Alongside DRY and YAGNI, there’s also KISS (Keep It Simple, Stupid). The KISS principle “encourages developers to avoid unnecessary complexity. Whether you’re writing a function or designing an entire system, simplicity is often the best strategy.” This is important since if there’s a lot involved in the project, then there’s a lot more risk of bugs when can result in the needless complexity, rigidity, etc. that we learned in class.

This principle was actually created by a systems engineer named Kelly Johnson who was working for Lockheed Skunk Works which was the team that developed the SR-71 Blackbird (“a retired long-range, high-altitude, Mach 3+ strategic reconnaissance aircraft,” according to Wikipedia). “His idea was simple: systems should be so straightforward that even someone with basic training could repair them under stressful conditions — like in combat. This philosophy translated beautifully into software, where complexity is often the enemy of reliability.”

I learned that DRY “was introduced by Andy Hunt and Dave Thomas in their 1999 book The Pragmatic Programmer. Their definition was concise but profound: ‘Every piece of knowledge must have a single, unambiguous, authoritative representation within a system.’” It helps reduce redundancy and speed up development in a project.

I learned that YAGNI worked as “a reminder to avoid building features or abstractions that aren’t immediately required” because of the encouragement it gives to “developers to resist the urge to ‘future-proof’ code based on assumptions about needs that may never materialize.” I also learned that YAGNI came from a thing called Extreme Programming (XP) and was popularized by Ron Jeffries, one of the original Agile Manifesto signatories. It became a core tenet of XP: ‘Always implement things when you actually need them, never when you just foresee that you need them.’” It helped prevent overthinking in engineering and keep the development focused on solving the problems of today rather than in the future.

Source: https://levelup.gitconnected.com/software-architecture-explaining-kiss-dry-yagni-with-practical-examples-in-typescript-9bf23c484816 

From the blog CS@Worcester – The Progress of Allana R by Allana Richardson and used with permission of the author. All other rights reserved by the author.

Software Architecture Patterns

Architecture of software systems is not something I’ve delved into very deeply in the past. For the most part, the systems I’ve worked on have been mostly self-contained and small-scale, and only recently, particularly in my work environment, have I been exposed to the importance and relevance of architecting the entire system in a smart manner, which involves much more than just the code lines within.

As I learn to develop larger-scale software, it becomes increasingly important for me to develop a capability of looking at the big picture, goals, and possible implementations of a desired software system. The number of individual moving parts just grows and grows when you need to accommodate logic, data, processes, and more, and I need to be as capable as possible of designing and implementing them, or otherwise working within them, while having an understanding of how they work, and how they affect what I’m making.

Software architecture concerns the overall structure of a system, including its components, relationships, and guiding principles.

The ultimate goal of thinking about your software’s architecture is to aid you and your team in creating the most performant, maintainable, scalable, and secure software systems possible for your use case and business requirements.

In order to learn more about architecture, I decided to take a look at a post on GeeksForGeeks that takes a look into the different types of architecture styles, their use cases, advantages and disadvantages, and inherent limitations.

https://www.geeksforgeeks.org/software-engineering/types-of-software-architecture-patterns/

The post explained how architecture patterns exist, just like design patterns do, and how they differ. Conceptually, the design patterns are lower-level implementation strategies, involving the individual components of a system, such as the Duck Simulator’s “factory” design pattern option. Architecture patterns, on the other hand, involve higher-level strategies for the entire software system, like the concept of client-server architecture, which will almost certainly now require some web-based components, or the concept of layered architecture, which involves splitting the system into four “layers”, the presentation layer, the business layer, the application layer, and the data layer.

Each architecture pattern has advantages and disadvantages just as the design patterns do. For example, the layered architecture pattern splits the system into four specialized parts, allowing for a more focused scope within each component, as in, the presentation layer is focused on UI components, and the data layer focuses just on data writing, retrieval, and storage.

Having a plan goes a long way when it comes to building software, and understanding architecture patterns is just another way to get better at planning, and working within, great software. I’ll continue to keep these concepts in mind as I create and work on more systems, and further my understanding of software architecture.

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

Unified Modeling Language (UML)

Hello everyone,

This week’s blog will cover Unified Modeling Language (UML) as this was a topic we recently covered in class and it was something that really left me in awe after learning about it so I wanted to write a blog about it. After finishing the homework about UML I realized how important of a tool it is for software developers and system designers. 

The author starts off the blog by giving a table of content to the reader. This allows them to get familiar with the structure of the blog, what it has to offer, and they can also jump on to a specific part that they want to read specifically. So UML is a standard visual language used in Software Engineering to model and design software systems. It helps developers, analysts, and stakeholders understand system structure, behavior, and interactions through diagrams. These can be extremely useful to people who are not familiar with coding and want to understand what the code does without being confused and lost when looking at it. The blog describes the purpose, significance, and the different types of UML, while also giving good advice and examples. On top of these, the author keeps a balance of technical explanation and keeping it simple for new learners. Later on the blog, he explains how UML closes the gap between technical and non-technical project members by providing a diagram which showcases the whole structure of the code and how everything is connected with each other. The article puts the history of how UML was created in the 1990s, and how the Object Management Group (OMG) took it as a standard. What I enjoy the most about this section is that it emphasizes why it is important, it improves communication, reduces misunderstanding, and helps in identifying design defects early. The blog then explains the various kinds of UML diagrams, like Class Diagrams, Use Case Diagrams, Sequence Diagrams, and Activity Diagrams. Both are discussed in detail along with their application, so it would be easy to understand when to use one over the other. The author also offers a step-by-step hands-on guide to creating UML diagrams, from deciding the purpose to using tools like Lucidchart.  The blog also has a dedicated section where it encourages the reader to practice and learn how to use UML. He states that it can be tricky at first, but with enough practice it will become easier to anyone. You can start off small and eventually you will get comfortable using UML when creating bigger projects

In conclusion, this blog was very informative and pertaining to my learning goals currently. Not only does the author describe what UML is, but he also takes readers through its actual uses, best practices, and even its limitations. Having this balance allows me to view UML as more than a diagramming scheme. It means thinking and planning effectively beforehand before starting to code..

Source: https://www.theknowledgeacademy.com/blog/unified-modeling-language/

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

Enhancing Code: Refactoring and Design Patterns

I chose the website Refactoring.Guru as my resource for this quarter’s blog post. This site offers an in-depth collection of material covering code refactoring and various software design patterns. The resource directly relates to course material in my Software Construction, Design, and Architecture class, as we recently completed an assignment that involved both refactoring and implementing three specific design patterns: Strategy, Singleton, and Simple Factory. I wanted to deepen my understanding of these concepts beyond the implementation done in my assignment.

Refactoring.Guru provides comprehensive guides on two core concepts in software development: Refactoring and Design Patterns.

Refactoring is the process of restructuring existing code without changing its external behavior, to improve readability and reduce complexity. This site thoroughly explains that refactoring is essential for resolving consequences of prioritizing speed over clean code, aka technical debt; and describes the various types of code smells and techniques for reducing them.

Design Patterns are reusable solutions to common problems found in software design. These patterns are sorted into three categories: Creational, Structural, and Behavioral; the website provides clear descriptions and examples of each type of pattern that falls into these three categories, including the Strategy, Singleton, and Simple Factory.

I chose this resource because I was amazed at the clear and concrete information it provided, and I felt the need for a more comprehensive foundation on these patterns outside of the practice the class assignment gave. I particularly enjoyed using the Singleton Pattern as it clearly visualized being the optimal choice for creating methods that respond to one instance class. Similarly, the Strategy Pattern was a great start in understanding how to refactor code by adding, swapping, and removing parts without needing to rewrite the entire program. This resource offers clear and visual explanations that help bridge the gap between how to implement a pattern and why it is the chosen solution in certain contexts. 

This website has, without a doubt, helped me better understand the reasons behind refactoring and the several types of design patterns. With the resources’ section on refactoring highlighting the seemingly tedious but essential effort of cleaning up code to prevent the accumulation of technical debt, it also helped me realize that refactoring is not just a fix for poorly written code or a skill to identify bad code, but is an essential part of writing good code.

As I continue completing in-class and homework assignments for this class, and develop and edit code in the workplace, I will refer to this website to not only identify the best design pattern, but to identify the design smells and technical debt- as these assignments help with strengthening those skills with pre-written code (that we then finish and/or refactor). I will use this resource to continue practicing design patterns and refactoring, to strengthen my skills and ability to select the right design pattern to refactor my code.

Resources:

https://refactoring.guru/ – Refactoring Guru

From the blog CS@Worcester – Vision Create Innovate by Elizabeth Baker and used with permission of the author. All other rights reserved by the author.

REST API design philosophy and constraints

Original Blog: https://stackoverflow.blog/2020/03/02/best-practices-for-rest-api-design/

For this post, I’ve decided to write about what qualities a REST API platform ought to have in order for it to best serve the clients that depend on it. I’ve chosen this topic since it relates to what I’m currently studying in my software and design class.

As of today, REST API platforms are among the most widely used kinds of web interfaces. This is largely because of the versatility they offer in what can communicate with the API. Because of this, some key characteristics and qualities have been noted as essential for most, if not all, REST API platforms to ensure no problems are encountered in using the API. In the blog, “Best Practices for API Design”, by John Au-Yeung, the author details some practices he feels are the most necessary.

The first listed quality is the JSON compatibility, which includes being able to receive requests in JSON and being able to respond in JSON. The main reason for this quality being essential are the fact that most networked technologies either do or can use it with minor adjustments, compared to other frameworks, like XML, which would require the transforming of data so that it could be used. This would be very cumbersome for both the client and the maintainers of the API, and is less preferable than just using an already widely used framework like JSON.

The second listed quality is to make sure the endpoint paths of the API include only nouns describing what an http method acting on that endpoint would affect. For example, a path for using the GET method on a collection of articles would just be called GET /articles/ as opposed to GET /retrievearticles/. Since the http method will always add a verb to the path name, extra verbs that just reiterate what the method does can clutter the syntax of the endpoints. While this quality is maintained, endpoints and their functions are clear throughout the whole API.

The third and final quality mentioned by the author that I’ll include in this post is use of logical endpoint nesting when making paths for related endpoints. This quality says that if there is related or grouped data that can be accessed, structure the paths so that it’s clear that the information is related. The example the author gave was when designing a path to access comments on a specific article, the path should resemble /articles/articles:id/comments. With this structure, it’s clear to the user where the information contained in comments in coming from, and how that information interacts with articles and a specific articles id. This quality is important because it minimizes the amount of possible confusion a user may experience when accessing child resources.

In summary, of the qualities the author chose to emphasize, the ones that stood out to me the most were the logical nesting of paths and the compatibility with JSON. The logical path nesting seems like it could also prevent the problem of users suggesting errors in the API itself, when in reality they’re just confused by the unclear path structure, and JSON compatibility just seems too convenient to not have, and way too cumbersome to operate without, especially if your API is seeing use on a large scale.

From the blog My first blog by Michael and used with permission of the author. All other rights reserved by the author.

Understanding Concurrency from a Beginner’s Point of View

Concurrency is one of those computer science topics that, in theory, makes sense but somehow manages to be a little confusing in practice. In Concurrency 101: From a Beginner’s Point of View, Mrinal gives a straightforward and step-by-step discussion on how languages such as Python, JavaScript, and Go handle more than one thing simultaneously. My favorite was the way the author explained concurrency not as “doing multiple things at the same time,” but rather as making progress on more than one task without getting in each other’s way.

The article starts by explaining the distinction between concurrency and parallelism, a difference that is essential for authors of responsive programs to understand. Mrinal then discusses the mechanisms that support concurrency: processes, threads, and event loops. Each of these has trade-offs, processes are heavier weight but safer, threads are lighter weight with the risk of race conditions, and event loops (like JavaScript’s) rely on non-blocking operations to stay efficient.

There’s a large section on synchronization and how programmers prevent “chaos” when threads are reading and writing shared data. I liked the presentation of mutexes and semaphores. The chef example for describing deadlocks made it easy to see how two threads might be waiting for each other forever. Mrinal does discuss practical solutions such as lock ordering, timeouts, and try-locks, all patterns we’ve discussed in CS-343 when we’ve talked about safe concurrent design.

The post then moves to lock-free programming and message passing and explains how atomic operations and the Actor Model can eliminate many synchronization problems altogether. I liked how Mrinal mapped these concepts to real systems like Go’s concurrency model and Apache Spark’s distributed processes, and how scaling depends on understanding which workloads are benefitted by which model.

I picked this resource because concurrency has been one of the more daunting topics for me. Having the opportunity to read a post that was written from the perspective of another student made it that much more relatable. The analogies, along with real engineering explanations, bridged the gap between textbook theory and real implementation.

I took away from this blog to conceptualize concurrency as orderly cooperation between tasks rather than chaos waiting to happen. It opened my eyes to how careful design choices, like tidy lock ordering or message passing, can make programs more correct and speedier. In the coming times, I will apply these lessons when I am working on multithreaded assignments or any program that demands responsiveness, like my Android application that I made this summer which communicates with a Flask backend. Having the fundamentals of concurrency under my belt will allow me to write cleaner, safer, and more scalable code.

Resources: https://mrinalxdev.github.io/mrinalxblogs/blogs/concurrency.html

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

The Rest APi

 

The article “What Is a REST API?
Examples, Uses, and Challenges”, published on the Postman blog, provides an
accessible overview of REST APIs. Rest Api works as a backbone in modern web
communication. It explains that a REST API (Representational State Transfer) is
a standardized way for systems to exchange data over the web using common HTTP
methods such as GET, POST, PUT, and DELETE. It briefly explains the history of
the rest api and the comparing to Simple Object Access Protocol (SOAP) api
which required strict message formatting and heavier data exchange while REST api
emerged as a lighter and more flexible architectural style built on standard
HTTP methods. The piece also informs best practices for using REST api like using
correct HTTP status codes, providing helpful error messages, enforcing security
through HTTPS and tokens, In the end, the article shows real-world examples
from well-known platforms like Twitter, Instagram, Amazon S3, and Plaid,
showing how REST APIs are used at scale in everyday applications.

As a software developer trying to be a
full stack developer, api calls were one of my weakest points since I am
struggling to understand how to use it effectively even though I tried to use
it in many areas. I had to ensure that I have a strong, up-to-date conceptual
foundation of what REST APIs are and how they are designed and used in practice
as I use. Since Postman is one of the leading platforms in the API ecosystem,
its educational resources provide an excellent reference point for gaining both
theoretical and practical understanding of how REST APIs work in real-world
development.

Even though the article was long , with YouTube
videos and hard time to understand everything, this article with postman helped
me to better understand the history and the usage of the rest api and its real-world
use compared to before. I learned that REST is not a technology or tool but an
architectural style that enforces clear separation between client and server,
promotes scalability, and ensures that each request carries all necessary
information. Later I plan to use this information to carefully use api as I plan
to create my own REST api endpoints that provide access to datasets and user
submissions while documenting things well unlike before. Ultimately, my goal is
to become comfortable enough with APIs that I can architect entire applications

article link: https://blog.postman.com/rest-api-examples/ 

From the blog Sung Jin's CS Devlopemnt Blog by Unknown and used with permission of the author. All other rights reserved by the author.