Category Archives: Programming

Choosing the Right Open Source License

Choose an open source license

For this week’s self-directed professional development, I explored the topic of choosing open source licenses, which is a fundamental but often overlooked part of releasing software. I based my reading on ChooseALicense.com and supporting resources that explain how permissive licenses, copyleft licenses, and public domain-style licenses differ. What I found most interesting is how a license doesn’t just define legal rules — it reflects the values, intentions, and goals of a developer or a team. Software licensing shapes how a project evolves, how a community forms, and how contributions are handled over time.

Open source licenses fall into a few broad categories. Permissive licenses like MIT or Apache 2.0 give users almost complete freedom to reuse the code, even in closed-source commercial products. Copyleft licenses like GPL ensure that any derivative work must remain open source under the same license. And options like the Unlicense or CC0 place code essentially in the public domain, allowing anyone to use it with zero restrictions. Before this week, I assumed licensing was just a legal formality, but now I understand how strongly each license type influences collaboration and long-term project direction.

I chose this topic because licensing is directly connected to the work we do in Software Process, especially when we talk about transparency, collaboration, and project ownership. As future developers, we will eventually publish our own tools, libraries, or contributions. Knowing how to license our work is part of being a responsible member of the open source community. Many people assume that posting code publicly means anyone can use it, but without a license, nobody can legally copy, modify, or reuse it. That detail alone made this topic worth exploring, and it helped me rethink how important explicit permissions are.

One thing I learned is that choosing a license is really about choosing a philosophy. If a developer wants to share knowledge broadly, enable commercial use, and reduce friction for adoption, a permissive license makes sense. If the goal is to ensure the code stays free for everyone and cannot be closed off by others, a copyleft license protects that intention. The reading made me think carefully about what I would want if I released a personal project. Personally, I lean toward permissive licenses because I want people to build on my work without worrying about legal constraints. But I also understand why larger community-focused projects might choose GPL to preserve openness.

Going forward, I expect licensing to be something I pay more attention to in both school projects and professional work. As software engineers, we’re not just writing code; we’re shaping how others can interact with it. Licensing is part of that responsibility. This topic helped me better appreciate the intersection between technology, ethics, creativity, and law — and it reminded me that releasing software is more than just pushing code to GitHub; it’s about defining how that code fits into the larger ecosystem of open source development.

From the blog CS@Worcester – Life of Chris by Christian Oboh and used with permission of the author. All other rights reserved by the author.

Refactoring Code

When looking for some ideas with what to write about for this blog post, I settled in on refactoring code. For starters I know what it is and why we do it, but I wanted to go more in depth by looking at other resources and what they have to say about it. One of the first sources I came across was a blog post called “How to create a culture of continuously refactoring code?” by Stas Wishnevetsky. This post from Medium revealed something that for some reasons wasn’t so obvious to me and this was that refactoring isn’t a one and done kind of thing. Instead, it is more of a routine and should be done as one to keep code maintained properly and to make sure it remains easy to use.

The first thing that really struck me when reading this article was talking about code like it is something physical and biological. This comparison was made to show how code can “decay” and “rot”. While the code itself doesn’t break down and fall apart with time, there are multiple reasons that make it seem like it does. These reasons include: coding abilities improving over time, business needs and scale fluctuating, and deliberate tech debt. The article then goes on to explain why we should refactor and the end goal of maintaining stability and creating improvement.

I guess I have never had the need to deal with refactoring my code since most the time I program one time assignments and never had the need to upkeep some kind of program. I have, however experience my abilities improving while creating a project and have had some parts be sloppy while later improvements are better done. I suppose I should have gone back and refactored those early parts but the bottom line is that I’ve never had the need to. I would also run into problems trying to make small changes which would be risky in my program. This is one of the many pains explained in the article I read and makes lots of sense.

I know going forward in my career refactoring will become very prominent in my work and understanding it more now makes me feel better about it. This also really shows the amount of effort that is put into big programs we use on a day to day basis. Starting the practice of constantly and consistently refactoring my code, even simple projects, will be super beneficial for me going forward.

From the blog CS@Worcester – Works for Me by Seth Boudreau and used with permission of the author. All other rights reserved by the author.

Version Control: Why It Matters in Software Development

Version control is something I’ve used before in classes, but I never fully understood its importance until I read the Atlassian article, “What is Version Control?” (https://www.atlassian.com/git/tutorials/what-is-version-control). I selected this resource because Atlassian explains technical concepts in a way that feels practical and industry-focused, which fits perfectly with what we are learning in CS-348. Since this course emphasizes collaboration, documentation, project organization, and professional tools, I wanted to learn more about how version control actually supports real-world software development.

The article defines version control as the practice of tracking and managing changes to code. What stood out to me is that version control isn’t just for “saving work”, it’s a full system that captures every change, who made it, when it was made, and why. Atlassian highlights how this creates a long-term project history that developers can search through, compare, or revert. This directly connects to our CS-348 topics like software maintenance, project management, documentation standards, and team collaboration, because version control supports all of these practices behind the scenes.

The resource also explains how version control allows teams to work on separate branches, make experimental changes, fix bugs, or build features without interfering with one another. This connected with my experience in this course because when we work on group projects or assignments, version control prevents us from overwriting each other’s work. The article also discusses merge conflicts, and reading about it made me feel better about the moments when I’ve run into conflicts myself. Instead of seeing them as mistakes, the article made me realize they are a normal part of teamwork and software development.

One major takeaway for me was the idea of traceability. Every commit tells a story, not just about the code, but about decisions, goals, and teamwork. This encouraged me to treat commit messages more seriously so that my future teammates (or even future me) can understand the purpose behind changes. The article made me realize that version control isn’t just a technical tool; it is a communication tool. This is something I didn’t appreciate before reading it.

This resource affected how I view my future practice because version control is required in almost every professional software environment. Reading about how teams rely on it to avoid lost work, manage parallel development, and maintain high-quality software helped me understand why CS-348 emphasizes collaboration tools, project organization, and documentation. Going forward, I plan to use branching more intentionally, commit more frequently, and write clearer commit messages. I also want to apply what I learned outside of class by using version control for my personal and club-related tech projects.

Overall, this article helped me connect the technical skills we practice in CS-348 to how real development teams work. It showed me that version control supports not just code, but communication, teamwork, and professionalism — all skills I want to continue developing.

Source

Atlassian. What is version control. Retrieved from https://www.atlassian.com/git/tutorials/what-is-version-control

From the blog CS@Worcester – Circuit Star | Tech & Business Insights by Queenstar Kyere Gyamfi and used with permission of the author. All other rights reserved by the author.

Code Can be Dirty?

Unfortunately, yes

The above code is positively awful to look at, read, try to understand, and generally poor practice. Recently, in this semesters Software Development class, we have moved away from project structures, and into clean code. What makes it clean, why is it important, and related topics.

Why clean?

Clean code provides an easy reading experience for anyone looking at it. This include people later working on something released years ago, as well as the person writing completely new code for the first time. Every example of code can benefit from being clean. Coding cleanly enables readers to understand what the code is doing, and makes it easy to follow mentally. As well as this, clean code can make better code, as spotting mistakes is made easier when you know where everything should be.

What makes code clean?

Clean code is code that is easy to read, understand, and modify because it expresses its intent clearly and avoids unnecessary complexity. It uses meaningful names, small and focused functions, and consistent structure so that another developer can quickly grasp what it does without confusion. Clean code avoids duplication, hides internal details, and keeps responsibilities separated so each block does one thing well. It favors simplicity over cleverness, documents why decisions were made, and is organized in a way that makes future changes safe, predictable, and maintainable.

In the wild

This video is a perfect example of how clean code, and specifically refraining from nesting your code too much, is a good habit to form. The video explains that multiple layers of if statements, loops, and conditional branches make code harder to read, maintain, test, and debug. The creator argues that nesting increases cognitive load because developers must track several scopes at once, and it often signals that a function is trying to do too many things. The video recommends techniques such as using early returns, inverting conditions, and extracting complex inner blocks into smaller, well-named functions so the main “happy path” remains flat and easy to follow. Overall, reducing nesting leads to cleaner, more understandable, and more maintainable code.

I chose this resource as it was a fun video that I found ‘in the wild’ while simply scrolling, and felt that it closely aligned with principles we have been learning in class.

In conjunction with in class learning, I have been swayed to become a ‘never-nester’. I would like to put into practice this behavior, and am excited to maintain clean, readable code in future projects.

This concludes my mandatory blog post of Quarter 3 for the semester.

— Will Crosby

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

REST API Parameters and Filters

This past week in class, we were working on a homework assignment on REST APIs. In the first part of the homework, we had to create new endpoints for the inventory path. The part I struggled with was writing the query parameters. I was pretty confused and felt like I was going in headfirst to something I didn’t understand. I found a site that explains the API’s parameter syntax to help. 

For path parameters, the name of the parameter is the same as the one in the path.

For query parameters, the name is not in the path and can be anything. 

The body of the parameter is the exact same. It needs a name, a declaration of if it’s a path or query parameter, if it’s required, a description, and the format of the input. 

After reading through the site, I realized I was over-complicating it, and all I had to do was use the same format as the already created parameter bodies and alter it to what I needed. 

————————————————————————

The next part of the homework assignment was to use GET methods to filter for results. I did not end up completing this part of the assignment, but I was still curious on how it worked. I found a site that explains all the ways you can filter for results, like having an attribute be equal, less than, or greater than a value. 

To filter for an attribute with a specific value, use this line: 

GET /path-name?attribute=value 

You can link filters with an &:

GET /path-name-1?attribute-1=value-1&attribute-2=value-2

Less than, less than or equal to, greater than, and greater than or equal to is achieved by the shorthand lt, lte, gt, and gte, respectively. Greater than would be shown like this:

GET /path-name?attribute_gt=number-value

The homework asks us to filter for guest age in the right path, using equal to, less than, less than or equal to, greater than, and greater than or equal to. To solve this, I would use the GET method with the guests path and the appropriate ending, like:

GET /guests?age=40
GET /guests?age_gt=40

————————————————————————

Understanding the format and syntax of REST APIs will be very useful for the Software Development Capstone next semester. I understand parameters, how to create schemas, how to reference the schemas and error codes, which are all extremely useful for future projects and in a job setting. As we continue to learn how to use REST APIs and expand our knowledge, I feel comfortable adding REST API design and implementation into my skillset.

From the blog CS@Worcester – ALIDA NORDQUIST by alidanordquist and used with permission of the author. All other rights reserved by the author.

Understanding Design Patterns: Creational, Structural, and Behavioral

Hello everyone, and welcome to my blog entry for this week! Technically, not a blog entry since I am just re-doing the one, I previously posted.

Last weekend, I listened to the podcast from the Coding Blocks Podcast (codingblocks.net). I’ve always been curious about how experienced developers structure their code to make it easier to maintain and scale, so this seemed like the perfect topic to explore. The episode focused on design patterns, specifically the three main categories: Creational, Structural, and Behavioral. Listening to it gave me a new appreciation for how these patterns help solve common software design problems and make codebases more adaptable over time.

Summary of the Podcast

The episode, which runs for about 50 minutes, features developers Michael Outlaw, Joe Zack, and Allen Underwood discussing how design patterns provide reusable solutions to recurring challenges in software development. They describe Creational patterns as those that handle object creation in a flexible way, Structural patterns as those that organize and relate classes and objects, and Behavioral patterns as those that define how objects communicate and share responsibilities.

They shared several examples, such as the Factory Method (a Creational pattern used to create objects without specifying exact classes), the Adapter (a Structural pattern that allows incompatible interfaces to work together), and the Observer (a Behavioral pattern that lets one object notify others when its state changes). What I liked most was how the hosts emphasized that patterns aren’t rigid rules, they’re practical tools developers use to make their code more consistent and easier to maintain.

Why I Selected This Resource

I chose this podcast because I wanted to deepen my understanding of how large software systems are organized. I’ve often heard about design patterns being essential for professional software engineering, but I never had a clear idea of how they were actually applied. The podcast stood out because it explained patterns in an approachable way, connecting them to real-world examples like GUI systems, game engines, and web frameworks. It helped me see that these patterns appear everywhere from database connections to event handling, and that learning them is key to writing scalable, professional-grade code.

Personal Reflections: What I Learned

After listening, I realized that design patterns are really about thinking ahead.

  • Creational patterns reminded me that object creation should be flexible, not hard-coded.
  • Structural patterns showed me how organizing relationships properly can make systems easier to extend.
  • Behavioral patterns highlighted the importance of communication between objects and how good design reduces dependencies.

What stood out to me most was how design patterns encourage better decision-making. They don’t just make code work, they make it work better over time.

Application to Future Practice

Moving forward, I plan to start identifying patterns in the code I write. I want to experiment with the Singleton pattern for managing shared resources, like configuration files, and use the Strategy pattern when implementing algorithms that can be swapped dynamically. Understanding these patterns will help me approach programming challenges with more structure and confidence, and will prepare me for real-world software development where scalability and design quality matter most.

Citation / Link

Outlaw, Michael; Zack, Joe; and Underwood, Allen. Design Patterns Explained. Coding Blocks Podcast, 2019. Available online at codingblocks.net.

This podcast helped me see how Creational, Structural, and Behavioral design patterns provide a common language for building better software. Listening to it last weekend gave me new insights into how thoughtful design decisions can make a project more flexible, maintainable, and ready for growth.

From the blog CS@Worcester – Rick’s Software Journal by RickDjouwe1 and used with permission of the author. All other rights reserved by the author.

Testing Smarter, Not Harder: What I Learned About Software Testing

by: Queenstar Kyere Gyamfi

For my second self-directed professional development blog, I read an article from freeCodeCamp titled What is Software Testing? A Beginner’s Guide. The post explains what software testing really is, why it’s essential in the development process, and breaks down the different types of testing that developers use to make sure software works as intended.

The article starts with a simple but powerful definition: testing is the process of making sure your software works the way it should. It then describes several types of testing like unit, integration, system, and acceptance testing and explains how each one focuses on different levels of a program. It also introduces core testing principles such as “testing shows the presence of defects, not their absence” and “exhaustive testing is impossible.” Those ideas really stood out to me because they show that testing isn’t about proving perfection it’s about discovering what still needs to be improved.

I chose this article because, as a computer science student and IT/helpdesk worker, I deal with troubleshooting and debugging almost daily. I’ve always seen testing as something that happens after coding, but this article completely changed that mindset. It made me realize that testing is an ongoing part of development, not a one-time task before deployment. It’s a process that ensures software is not only functional but also reliable for real users.

What I found most interesting was how the author connected testing to collaboration and communication. Writing good test cases is like writing good documentation, it helps other developers understand what the software should do. The idea of “testing early and often” also makes a lot of sense. By catching issues early in the process, developers can save time, reduce costs, and prevent bigger headaches later on.

Reading this made me reflect on my own coding habits. I’ve had moments in class where my code worked “most of the time,” but I didn’t always test for edge cases or unexpected inputs. Moving forward, I plan to write more tests for my own projects, even simple ones. Whether it’s a class assignment, a group project, or a personal program, I now see testing as a chance to build confidence in my work and improve how I think about quality.

Overall, this article helped me understand that software testing isn’t just about finding bugs it’s about building better software. It’s a mindset that values curiosity, patience, and teamwork. By applying these lessons, I’ll be better prepared not only to write code that works but to deliver software that lasts.

***The link to the article is in the first paragraph***

From the blog CS@Worcester – Circuit Star | Tech & Business Insights by Queenstar Kyere Gyamfi and used with permission of the author. All other rights reserved by the author.

From UML to Design Patterns: Refactoring the Duck Simulator

Hello everyone, welcome back to my blog! In my previous post, I explored object-oriented design basics and the importance of UML diagrams for understanding class relationships. This week, I applied that knowledge to a practical assignment by refactoring the Duck Simulator project using several design patterns, and I want to share what I learned from the process.

Introduction

UML diagrams provide a visual blueprint for software systems, helping developers understand relationships, dependencies, and responsibilities of different classes. While useful on their own, combining UML with design patterns allows us to translate those visual models into flexible, reusable, and maintainable code. In the Duck Simulator project, I used UML to identify repetitive behavior and then applied Strategy, Singleton, and Factory patterns to improve the system’s design.

Using UML to Identify Problems

Originally, the Duck Simulator consisted of an abstract Duck class and subclasses like MallardDuck, RedHeadDuck, RubberDuck, and DecoyDuck. Each duck implemented its own fly and quack methods. My UML class diagram made it clear that this design was repetitive: multiple subclasses had similar or identical behaviors. This repetition violates the DRY (Don’t Repeat Yourself) principle and makes the system harder to maintain or extend. The diagrams highlighted the exact areas where behavior abstraction could be applied, providing a clear roadmap for refactoring.

Applying the Strategy Pattern

The first refactor I implemented was the Strategy Pattern, which separates the fly and quack behaviors into FlyBehavior and QuackBehavior interfaces. Each duck is assigned a behavior object rather than hard-coding methods. Using UML, I could visualize how Duck classes now depend on behavior interfaces, not concrete implementations. For example, RubberDuck now uses the Squeak behavior, and DecoyDuck uses MuteQuack. This change made it easy to swap behaviors dynamically and reduced duplicated code across subclasses.

Using the Singleton Pattern

Next, I noticed that all ducks shared identical behaviors like FlyWithWings and Quack. To avoid creating multiple unnecessary instances, I applied the Singleton Pattern. UML helped illustrate that each behavior class has a static instance and a getInstance() method. This ensured that ducks reused the same behavior object, saving memory and improving consistency.

Implementing the Simple Factory Pattern

Finally, I created a DuckFactory to centralize the creation of ducks with their associated behaviors. UML shows a clear dependency from the simulator to the factory, encapsulating construction logic and removing manual behavior assignments in the simulator. This simplified code maintenance and improved readability, while maintaining all Strategy and Singleton benefits.

Reflection

This assignment reinforced how UML and design patterns complement each other. The diagrams helped me see problems in the design, and patterns provided proven solutions. After completing the refactor, the Duck Simulator is now modular, maintainable, and extensible. I can confidently add new duck types or behaviors without touching existing code. Personally, I learned that UML isn’t just documentation, it’s a tool that guides better design and code structure.

Resources

While exploring this assignment, I also reviewed a great resource that breaks down the concepts from Head First Design Patterns in a clear and structured way. You can find it here on GitHub. It helped me connect UML representations with real-world code implementations, especially when applying the Strategy Pattern in my Duck Simulator project.

From the blog CS@Worcester – Rick’s Software Journal by RickDjouwe1 and used with permission of the author. All other rights reserved by the author.

Reflection on “Coding Standards and Guidelines”

by: Queenstar Kyere Gyamfi

The GeeksforGeeks article “Coding Standards and Guidelines” highlights the importance of writing code that is clean and consistent. It also underlines the need for code that is easy to understand. It explains that coding standards are a set of rules and conventions that help developers maintain clarity and quality across a project. These standards cover areas such as naming conventions, indentation, code structure, comments, and documentation. The article emphasizes that following standards is not about limiting creativity. It is about making sure that everyone working on a project can easily read and maintain the code. It also points out that coding guidelines help prevent errors. They make debugging easier. They ensure that software projects remain manageable as they grow.

I chose this resource because I’ve noticed how quickly group projects can become messy. Each person having a different coding style contributes to this messiness. I’ve always cared about writing code that works. I’ve started realizing that how the code looks and reads is just as important. This is especially true in team environments. This article stood out to me because it clearly explained the purpose behind coding standards.

One key lesson I learned from this article is that consistency builds trust among developers. When everyone follows the same structure, it becomes easier to understand, review, and modify code written by others. The article also reinforced the idea that good code should be self-explanatory. For example, meaningful variable names like totalPrice or userCount communicate intent better than short, unclear ones like x or val. I also learned how proper indentation and spacing make code more readable and reduce the risk of logic errors that come from misaligned statements or missing braces.

Reading this resource made me reflect on my own coding habits. Sometimes, when I’m rushing to finish an assignment, I skip comments or mix naming styles without thinking about how confusing it might be later. Now, I see that writing clean code is an investment as it saves time when debugging and helps others understand what I meant. I also want to use tools like linters and formatters to automatically enforce standards in my projects.

Overall, this article helped me understand that coding standards are not about perfection but they are about communication. Clean, organized code reflects professionalism and respect for the next person who will read it. It reminded me that in software process management, technical skills and teamwork go hand in hand. Writing code that others can easily follow is one of the best ways to contribute to a project’s long-term success.

LINK TO RESOURCE:

https://www.geeksforgeeks.org/software-engineering/coding-standards-and-guidelines/

From the blog CS@Worcester – Circuit Star | Tech & Business Insights by Queenstar Kyere Gyamfi and used with permission of the author. All other rights reserved by the author.

From Inheritance to Strategy: Lessons from the Duck Simulator

One of the primary obstacles in software design is ensuring that code remains easy to maintain and extend. Initially, inheritance seems like the clear answerplacing shared code in a superclass and allowing subclasses to override as necessary. However, as demonstrated in the classic Duck Simulator example, relying solely on inheritance can result in fragile designs.

From Inheritance to Strategy

In the first version of the Duck Simulator, all ducks derived from a base Duck class. This approach worked until we introduced unique ducks like RubberDuck (which squeaks instead of quacking and cannot fly) and DecoyDuck (which does neither). Suddenly, we found ourselves needing to override or disable inherited methods, leading to duplication and design issues such as viscosity and fragility. Transitioning to interfaces helped to declutter the design, but it also required us to replicate code across similar ducks. The true breakthrough arrived with the Strategy Pattern,

We extracted behaviors like flying and quacking into separate classes (FlyWithWings, FlyNoWay, Quack, Squeak, MuteQuack). Now, ducks possess behaviors rather than inheriting them. These behaviors can be altered at runtime, and new ones can be introduced without changing existing code. This transition underscored the principle of favoring composition over inheritance and illustrated the Open-Closed Principle: code is open for extension but closed for modification.

Design Principles in Action

The exercise reinforced several essential principles: High Cohesion: Each behavior class excels at a single task. Low Coupling: Ducks are indifferent to how they fly or quack, only that they can delegate to a behavior. Encapsulate What Varies: Changes in behavior are contained, not dispersed across subclasses. Collectively, these factors enhance the design’s flexibility and maintainability.

UML: Clearly Communicating Design

We also engaged in the practice of illustrating designs through UML diagrams. In contrast to code, UML offers a higher-level representation that clarifies relationships: Associations (for instance, a Student possessing a schedule of Course objects). Multiplicity (for example, a student may enroll in 0–6 courses). Inheritance and interfaces (such as Faculty extending Employee and implementing HasCourseSchedule). Tools like PlantUML enable us to create these diagrams in Markdown, facilitating easy adjustments and sharing.

Key Takeaways

Relying solely on inheritance frequently results in fragile designs. The Strategy Pattern addresses this issue by encapsulating behavior and employing composition. Guiding principles such as High Cohesion, Low Coupling, and Open-Closed promote cleaner designs. UML diagrams provide us with a common language to convey and analyze code. What began as a straightforward duck simulator evolved into an insightful lesson on the significance of design patterns. By embracing the Strategy Pattern and utilizing UML for design modeling, we discovered how to construct systems that are not only functional but also resilient, adaptable, and easy to maintain.

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