Category Archives: CS@Worcester

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.

Polymorphism in Object-Oriented Programming

Polymorphism was one of those programming words that used to sound scary the first time I ever heard of it. It literally means “many forms” but in OOP, it’s not as scary-sounding as it is. It’s basically when the same method or function can be something different based on what object it’s being called from. As soon as I started reading over some examples, it made a lot more sense.

Think of it like this: an individual might be a class student, a home sibling, and maybe a work employee. Same person, various role depending on context. In programming, polymorphism enables us to do one thing with one function that changes its behavior depending on the object.

There are two main forms of polymorphism. Compile-time polymorphism (or static) is solved before the program ever runs. That generally happens with method overloading, where you have multiple versions on the same method name with different parameters. The compiler figures out which one to invoke. Operator overloading is another example, like using “+” for numbers and strings too.

Then there is runtime polymorphism (dynamic), resolved as the program is running. That is what happens with method overriding. A case in point is a parent class Shape that has a method draw(). Subclasses such as Circle and Square override draw() to do something else. When you call draw(), the program picks one that matches the actual object.

First of all, I used to confuse this with inheritance. They definitely go hand in hand, but they are not one and the same. Inheritance is when you are copying another class’s code. Polymorphism is when you have the same method name but have different action.

A lot of people also think that using polymorphism, especially the runtime kind, makes programs really slow. I used to believe that too, but it turns out that’s not really the case anymore. Modern compilers are built to handle this kind of thing quickly with tricks like virtual tables, so the performance hit is tiny. The trade-off is worth it because you get cleaner code and way more flexibility, so worrying about speed here feels kind of outdated.

I’ve read about this and it struck me how many times I’ve made my own code overly complicated. In Java, for example, I used to create a whole bunch of methods with unique names when I could have done overloading. I also blocked overriding in subclasses because I believed that it would be slow. Now I know that not just is that fine, it’s the correct thing to do most of the time.

In the future, I’d like to use polymorphism more intentionally, especially in my Android applications. It’ll be a tremendous assistance if new functionality is introduced in the future because I won’t need to begin anew. That, to me, is the beauty of OOP, it’s not just about making things function, but making them simpler to maintain and extend in the long run.

Resources:

https://www.cincom.com/blog/smalltalk/polymorphism-in-object-oriented-programming/

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

Git and Its Significance in Modern Software Development

I decided to write my first self-directed post about a blog I found regarding Git and its significance in software development. During our course thus far, we have spent quite the amount of time learning Git; more importantly, why it exists and how to use it. This blog summarizes the importance of Git in modern software development. Prior to its creation, there was not a feasible or reliable way to maintain code amongst developers. This led to inefficient workflows and harder collaboration that may have impeded a developer’s ability to contribute effectively to a project. The blog claims that 85% of developers believe that Git’s introduction and adoption have made collaboration much easier than it was before. It later talks about what Git is, how to set it up and some basic use cases. The author writes about some common issues with Git such as merge conflicts and how to integrate it into your IDE. Later on, the article highlights some best practices such as meaningful commit messages or committing small changes, rather than many large changes at once.

For beginners to Git like me, this was useful to reinforce what we have learned in class so far. I chose this resource to learn more about Git outside of class. I had previously heard of Git and GitHub from prior usage of the Internet, though, I had no idea how it was used or how prevalent it would be within the computer science field. Since Git was a newer topic for me and one that I had not touched upon in my 7 years of studying information technology and computer science, I wanted to look more into it outside of class to get a better grasp on it. I feel that after reading this blog, I am more comfortable using Git than I was before. For me, I love to learn new things, and I find that learning something from multiple different angles is often most effective for me. Using this in combination with the lectures and practice from class has been a useful resource for me to improve my Git skills. Within the realm of software development, knowing Git, or at least how version control systems work, is imperative to being successful within the field. Even outside the field, knowing collaboration, effective communication, and teamwork is essential, since computer science is rarely an independent field. I also feel more confident after reading this article, knowing the best practices and common issues that I may run into while working in the field. Overall, this article was extremely effective in expanding my understanding on Git and version control systems.

The link to the article can be found here: https://blog.rheinwerk-computing.com/gits-significance-in-software-development

CS-348
CS@Worcester
Quarter-1

ZG

From the blog CS@Worcester – zach goddard by Zach Goddard and used with permission of the author. All other rights reserved by the author.

Why Polymorphism is so Important in Programming

Polymorphism is one of those terms you hear in Computer Science that sounds confusing at first and overly complicated, until you find out you’ve probably been using it this whole time. “Polymorphism in Programming” by Johnathan Johnson is a great blog detailing exactly what it is and how it works. It gives a nice clear definition that’s easy to understand and then lists out the different types you’ll encounter along your programming journey.

Polymorphism is essentially just a process that can perform multiple tasks depending on the context of the situation. There are many forms of polymorphism as well such as Subtype (Runtime), Ad hoc (Compile-time), Parametric (Overloading), and Coercion (Casting). I won’t get too in-depth on each of these as Johnson has already done a great job of this in his blog.

The key takeaway here is that polymorphism allows you to program an interface, not just an implementation. What I mean is by creating an interface or superclass it doesn’t matter what type the object being called is you can just call the method on it. For example, you could have a list of Shape objects that can hold a circle or a square or whatever shape you want, and you can call draw() without caring which specific subclass you’re dealing with. Because of this code duplication can be severely cut down due to multiple objects using the same method all stored in the superclass.

This is similar to what we saw in class with the Duck superclass and all the subclasses with different duck types. As long as you were calling a method stored within the superclass it didn’t matter which subclass you were calling it on. Even if the subclass had overridden the method, you would just be running into ad hoc polymorphism as the program would be switching the version of the method used to that of the one stored in that particular subclass.

Even though I’ve been using polymorphism for years through my career here at Worcester State it’s good to finally learn what this practice is actually called. It’s also good to learn that there are forms of it I wasn’t always using when I could of and instead took the less efficient route to solve my problem. The concept is integral to time efficiency and when programming time is incredibly important in a lot of ways.

I plan on taking this newfound knowledge with me through the rest of my career here as well as whatever the future holds for me.

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

Object Oriented Principles

This blog is based on “OOP Principles: What is Object Oriented Programming?” from Full Stack Foundations. The article has a clear understanding of the four core pillars of object-oriented programming. That being encapsulation, abstraction, inheritance, and polymorphism. It also explores how these principles tie into more advanced design ideas such as composition over inheritance and more.

The article begins by explaining why OOP is valuable, emphasizing that it organizes code into modular blocks that bundle together data. OOP helps developers manage complexity in large systems. It then talks about encapsulation as the practice of hiding code and exposing only interfaces, which helps reduce unintended interactions. Abstraction is explained as representing concepts with simplified models. Inheritance is presented as a practice that allows new classes to build upon existing ones, enabling reuse of behavior. Finally, polymorphism is described as the ability to treat different classes as instances of a common base type, making systems more flexible and adaptable. Later in the article, the author connects these principles to design patterns, noting that good object design avoids fragile hierarchies.

I chose this article because it’s connection to our class, discussing design concepts. OOP is a key topic in this course, from abstraction and encapsulation to design principles and patterns, and I thought this blog was a good representation of OOP. It struck a good balance between the basics of OOP and the many ideas that are needed to think about design in a professional way.

Reading this article reminded me that OOP is more than just syntax like classes and methods. The discussion on abstraction and encapsulation stood out the most to me because in my past projects and classes I often never thought about the exposure of too many details of a class, either through public fields or otherwise. The article emphasized that clean abstraction is essential for maintainability. I also appreciated the warning about inheritance. The article shared the idea that using composition over inheritance can prevent problems and lead to more flexible ideas.

The main takeaway for me is that OOP is an idea that allows code to be built clean and modular rather than something that has to be perfected up front. In future assignments and projects, I want to be more aware about the principles of clean OOP coding. I also plan to make better use of interfaces and encapsulation so that classes depend less on concrete implementations. This resource gave me a refresher on these ideas and hopefully I can build systems that are easier to maintain and improve upon.

https://www.fullstackfoundations.com/blog/oop-principles?

From the blog CS@Worcester – Coding with Tai by Tai Nguyen and used with permission of the author. All other rights reserved by the author.

My Journey Learning Git

When I first started learning Git, it honestly felt like a different language. Everyone else around me seemed to know what they were doing cloning repos, branching and pushing changes to their remote repositories. I’d hesitate before every command, worried that I was about to break something permanently. Reading guides like DataCamp’s roadmap for beginners gave me … Read more

From the blog CS@Worcester – BforBuild by Johnson K and used with permission of the author. All other rights reserved by the author.

Understanding UML (Unified Modeling Language)

When I first came across UML in our class activity projects, I often felt lost trying to understand it. There were so many different diagram types, rules, and notations that I struggled to keep track of them all. At first, the symbols looked like a foreign language, and I wasn’t sure how they connected to … Read more

From the blog CS@Worcester – BforBuild by Johnson K and used with permission of the author. All other rights reserved by the author.

UML Diagrams With PlantUML

Week 5

This week I chose to expand my knowledge on UML class diagrams in PlantUML. I referred to the PlantUML website where they go over every command that is available to use and how they work. I wanted to read up on class diagrams to prepare myself for creating them in the homework assignment on UML diagrams and for refreshing my knowledge on UML. 

The website goes through all the types of elements you can create, relationships between them, putting labels on relations, defining visibility, adding methods and variables, and how to add notes. 

-The UML block is contained in “@startuml” and “@enduml”. In the dev container we used in class it is contained in ““`plantuml" and ““`”.
-To create a class, use “class <name> {<body>}”. If you want to make an abstract class or interface, you would do “abstract <name> {<body>}” or “interface <name> {<body>}”. 
-To define visibility modifiers for attributes and properties, use + for public, – for private, # for protected, and ~ for package private. By default, the diagram will show these symbols in colors and shapes, but that can be changed if wanted. A static attribute is defined with
“{static}” before the name.
-The site shows a lot of ways to create notes and all the things you can do to change them, like location, size, color, line breaks, etc, which can be useful to categorize notes in your diagram. 
-You can also change the colors of classes and elements, which can help to organize as well.
-Another element you utilize is arrows, when a class is defined, you can say “implements <class>” or “extends <class>” and it will automatically use the correct arrow. But, you can create your own arrows for associations by using “–>”, “-[bold]->”, “-[dashed->”, “-[hidden]->, or “-[plain]->” with the class names on either side. Notes can be attached to arrows as well. For example: Order “many” –> “1” Customer

I referenced the site a lot while doing the UML homework for a refresher. While working on the base assignment, I was cross referencing a lot to make sure I was doing it correctly, but when I got to the advanced assignment, I felt a lot more confident and comfortable with creating UML diagrams in VSCode and only needed to reference it for creating static variables. 

UML diagrams are essential for smooth code developing and finding any structural issues before you’re too deep in a project. Having the knowledge and practice to create them will definitely help me outside of this class. Using PlantUML is now something I feel like I can say I can do in real life. In the future, if we make more diagrams in class or if in a job they ask me to make one, I feel comfortable telling them I can make one.

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

UML in A Sequence of Learning Events

Lately, I’ve been having trouble with UML Sequence Diagrams. So, I decided to do further research to better understand the subject.

Due to learning about it in class, I have some prior knowledge about the subject. First, there’s the actor which is usually represented by a stick figure. The actor essentially acts as a user stand in. The rest of the classes are participants. Think of them as a path the actor has to walk across. The diagram shows the path that the code takes when the user executes the code.

I used this article for reference: Sequence Diagrams – Unified Modeling Language (UML) – GeeksforGeeks

It’s a beginner’s guide to UML sequence diagrams. It defines an UML sequence diagram and all vocabulary associated with it. It then informs how to one and the pros and cons of using one.

The first thing I started to better grasp was lifelines. I used to think lifelines were the solid lines but they depict an individual participant. Lifelines represent each instance in a sequence diagram. They are displayed in rectangles and go by their name and type. They are similar to actors but portrays objects internal to the system.

I also learned more about the messages. I knew that solid lines output messages and dashed lines returned them. I didn’t know that a solid line and a dotted represent synchronous messages and a single dotted line represent asynchronous ones. Synchronous messages wait for a reply before the interaction can move forward. Imagine if to people were moving boxes to a truck. Person A hands a box to Person B who puts it the truck. Person A must wait until Person B signals that they are done with their task. On the other hand, asynchronous messages don’t need to wait for a reply so Person A would just hand Person B the box without waiting for a signal.

So, to summarize what I learned. the diagrams are just a different way to demonstrate the code. It’s a communication tool between developers, managers, stakeholders, project managers and clients. It’s like a blueprint that anyone can look over. Clients can look over the plans without getting confused and make edits if necessary. Developers can take the blueprint and convert it into actual code. UML diagrams contain an actor that takes the role of a user engaging with the code. The participants represent the rest of the classes. The vertical rectangles represent the duration of a class’s execution. The arrows, not participants as previously mentioned, represent the path the code takes. Think about everything as components of a map.

Overall, this further research deepened my understanding of UML sequence diagrams. I feel like this would help me with the homework assignment but unfortunately it didn’t answer all my questions.

From the blog CS@Worcester – My Journey through Comp Sci by Joanna Presume and used with permission of the author. All other rights reserved by the author.

It’s An AI Problem

AI has grown to become one of the most useful and powerful tools in the world of technology. To the point where even schools and universities are taking advantage of it and implementing AI into their curriculum, with restrictions of course. Although artificial intelligence continues to evolve, it is not what it’s cracked up to be. Reports have shown that generative AI has been having issues in quality production. It is a hurdle that puts great limits on itself according to Harvard Business Review.

According to their article “Addressing Gen AI’s Quality-Control Problem”, AI has had issues with their output. This type of technology has tendencies of creating problems like making things up, leaving certain answers out and producing limitless possibilities, making difficulties of finding efficient solutions. While companies have found different alternatives to address this matter, it has become very expensive to do. 

By bringing this topic to the forefront, we get to see the reality of how AI isn’t always the solution in terms of finding the answers to different situations. This is why I personally chose this to begin with. A vast majority of this current generation uses this tool on a daily basis, but we don’t truly understand the efficiency of it. Especially in the workplace, where problem solving is crucial. 

Amazon, for instance, uses Catalog AI as a better approach to avoid quality issues. It detects and blocks unreliable data, produce ideas for new product pages, run tests and uses feedback as a method to keep improving. The upside of this is while various organizations struggle to recieve positive results from gen AI, specifically a financial investment return, eight percent of Amazon’s suggestions recieved positive impact from sale revenue, considering it “measurable value”. 

Reviewing this information, it didn’t quite surprise me that different groups of people are using alternative methods to get results like this. Even just in using AI myself, if I notice that I’m not getting accurate answers from one AI assistant, then I turn to others like Microsoft Copilot, ChatGPT, Google AI, etc. It’s also useful for when you want to see different outputs and compare them to each other. The point of performing all these tests is to test the effectiveness of this tool.

This especially applies to companies, who use very similar process to see if their methods work. Going back to Amazon, eighty percent of their outputted data was very unreliable. After going back and reviewing the progress and performance, they were able to make vast improvements. Now approaching to hopefully start in the computer science work field very soon, I pretty much know the do’s and don’ts of using gen AI. And having a process to heighten company data.

Article Source: Addressing Gen AI’s Quality-Control Problem

From the blog CS@Worcester – theJCBlog by Jancarlos Ferreira and used with permission of the author. All other rights reserved by the author.