Category Archives: CS-343

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.

Was it really all about frameworks?

What’s a Framework? All About Software Frameworks is an article written by Luke Stahl. I found it on dev.to, but it can also be found on the Contentful Blog. Links to both blogs are available in this post. The reason I chose this article is that I’ve heard a lot about frameworks since I started exploring web application development, and they always confused me. I used to struggle to understand what they were and what they were built for. Luke Stahl’s article answered both of these questions for me, though it also left me with a few more.

The article provides a general overview of frameworks for software development, web development, and working with APIs. However, it then pivots toward web development frameworks, which left me wondering about the differences between them. While it clearly explains the distinctions between backend and frontend frameworks, it misses covering some other differences I initially expected.

The author also includes a fairly extensive list of the benefits that frameworks bring to development, along with a brief list of challenges. For me, it’s always a bit concerning when something presents itself with so many benefits and so few downsides. Still, the benefits outlined are appealing and useful for developers.

Frameworks, as explained by Luke Stahl, are essentially blueprints or templates for a particular final product. They provide the essential building blocks and materials required to create your software or web application. A framework offers a skeleton for your application, allowing you to build functionality on top of it.

Halfway through reading the article, I began to wonder about the difference between a framework and a code library. Thankfully, and to my surprise, it seems Luke anticipated this question. He includes an explanation from two outside sources, David Fateh and Alvin Bryan. Both summarize that frameworks act as templates, while code libraries serve as tools you can use to build on top of that template.

One point that caught my attention—and that I believe is very important—is that most frameworks are FOSS (Free and Open Source Software). Being free and open source brings many advantages. Such products undergo extensive testing by a diverse group of programmers, across various applications, which increases the test sample size. This added testing leads to greater reliability, as it helps ensure that any new functionality works as intended. Another benefit of free and open-source products is the large community that often forms around them. This means that if you encounter questions or difficulties, it’s likely that someone else has already addressed them.

From the blog CS@Worcester – CS Today by Guilherme Salazar Almeida Nazareth and used with permission of the author. All other rights reserved by the author.

Back-end Optimization

Most of my time developing software so far has been with the back-end, I had to learn a decent amount about specific algorithms and because of the languages I worked with especially Java, learning about the Garbage Collection is something that’s been on my mind for a while. Overall, my time spent actually researching the Garbage Collector for Java has been very limited, all I knew was the baselines of the algorithms and the base of the functionality. While searching for some posts and information about the GC I came across a video from Inside Java that went over the Z Garbage Collector. Here is the link to said video, https://inside.java/2023/04/23/levelup-zgc/?utm_source=blog.quastor.org&utm_medium=referral&utm_campaign=scaling-microservices-at-doordash. For a quick summary of what is discussed in the video, there are multiple garbage collector types for Java, most of which are usually used in different scenarios. A quick description is given of these garbage collectors and some of their strengths in terms of throughput, memory footprint, latency and scalability. After discussing these, we learn more about ZGC which first released in a jdk11 development build for testing. Comparatively, ZGC is far better than pretty much every other GC in terms of scalability, heap allocation, latency and just overall performance. ZGC especially in terms of pause times is so much better that most other GC have a pause time in the terms of milliseconds, while ZGC has pause times in terms of microseconds. With accessibility in mind, when doing performance tuning for ZGC it is way easier, after jdk 17, it auto-adjusts itself to handle the amount of threads it will need for garbage collection, aside from that there is only the max heap allocation that the user should worry about tuning as well. The reason I am mostly interested in these types of algorithms and garbage collection systems in general is because many of the projects I’ve developed rely on them to be as efficient as possible, removing the unused data and keeping memory usage down. After listening to this I will most certainly either start using ZGC for my applications or do more research on the topic because for the most part I never paid too much attention to what GC my applications were using, it didn’t matter to me since I was uninformed on what exactly they did. Now that I know more about how specific GC’s function I’m most certainly going to start and try to apply ZGC to most of my projects as it seems it will be the most efficient for me.

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

UML Diagrams

Earlier in this course, I learned about UML diagrams, how to read them, how to make them, and so on. This section of the class stuck with me as I thought it was pretty interesting how we use these diagrams to “visualize” our code. I thought I’d gain some more insight on UML diagrams and possibly more on how they are used in the real world.

For those who aren’t so familiar with UML diagrams, let me give you some background. UML stands for “Unified Modeling Language” and is “a way to visually represent the architecture, design, and implementation of complex software systems” (Lucidchart). These diagrams can be generally divided into two types, structural and behavioral. Both types of UML diagrams are pretty self-explanatory but structural UML diagrams display the various pieces of a system and how they are related while behavioral UML diagrams show how the system “interacts with itself and with users, other systems, and other entities” (Lucidchart).

In this blogpost from Lucidchart, one of the first things that caught my eye was under the section “Why should you use UML diagrams?” Of the four bullet points, three of them had me nodding my head in agreement, these were:

  • Bring new team members or developers switching teams up to speed quickly.
  • Plan out new features before any programming takes place.
  • Communicate with technical and non-technical audiences more easily.

To me, these points make perfect sense. I’m not very familiar with how development teams work in the real world but I assume that there are plenty of developers and others that may come and go in companies, groups, and such. It may sound like a simple switch or change but that new person may have no idea what they will be working on or how it will be worked on. UML diagrams could help them adjust more quickly and help them understand their role, team, and work better. As for planning, simply adding a new piece to the diagram to indicate a new piece of the system could help display the relationships to what they already have. And finally, UML diagrams are much easier to digest than multiple files, classes, blocks of code, and such, especially for those who are not developers. A customer may want some update or insight into what they are spending their money on, and so, teams can simply show them a UML diagram and point out where they are and where they plan to go.

Blogpost: https://www.lucidchart.com/blog/types-of-UML-diagrams

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

SoftwareDiary 2024-11-12 09:00:00

In the realm of software development and design, UML (Unified Modeling Language) class diagrams play a pivotal role. The blog post “UML Class Diagram Explained with Examples” by Algomaster provides a comprehensive overview of class diagrams, illustrating their importance in modeling the structure of a system.

Code, while essential for functionality, is not always the best medium for conveying complex relationships between components. To address this challenge, the Unified Modeling Language (UML) class diagram provides an abstract visual representation of the structure of a system. The blog post by Algomaster, offers a detailed explanation of UML class diagrams, including key concepts such as classes, attributes, methods, and associations. This resource was particularly relevant to our recent assignment on Modeling with UML Class Diagrams, where we were tasked with designing class diagrams to represent a student-course scheduling system.

The blog post breaks down the structure of UML class diagrams, explaining each component in detail with accompanying examples. The tutorial begins by outlining the core elements of a class diagram, including classes, attributes, methods, and associations.

I selected this blog post because it provides a clear, concise explanation of UML class diagrams and their practical application, which directly ties into the Modeling with UML Class Diagrams assignment. This resource helped me better understand how to translate Java code into a UML diagram by identifying key components such as classes, attributes, and methods. Additionally, the visual nature of the tutorial, with its real-life examples, made it easier to grasp abstract concepts and apply them to my assignment.

I feel more confident in my ability to design and interpret UML class diagrams. Visit the original post on Algomaster: UML Class Diagram Explained with Examples.

From the blog SoftwareDiary by Oanh Nguyen and used with permission of the author. All other rights reserved by the author.

Consistent Hashing Algorithm

After spending some time exploring algorithms and blogs, I came across a post on a consistent hashing algorithm. I have had an interest in hashing and have found growing use for hashing algorithms as my classes and programming complexity progresses. This article is found on highscalability.com, and it is focused on providing a tutorial to understand how to use a consistent hashing algorithm for partitioning and load-balancing. The article’s title is Consistent Hashing Algorithm by NK

The blog identifies consistent hashing as an algorithm used to distribute data across multiple nodes in a distributed system, minimizing data movement when nodes are added or removed. It works by placing both nodes and data keys on a virtual hash ring. A virtual hash ring is a technique where each node is assigned a position on the ring based on the hash value of its identifier. The blog explains further that data keys are also hashed to determine their position on the rin as well. When a key needs to be stored or retrieved, the system traverses the ring in a clockwise direction until it finds the first node that is closest to the key’s hash position. This method ensures that only a small portion of the data needs to be redistributed when nodes are added or removed, making the system more easily scalable. The blog identifies these strategies and techniques to be best used in web development to handle caches. Through several figures, NK identifies as a way to improve load balancing and avoid hotspots, consistent hashing can use virtual versions of these nodes, where each physical node is mapped to multiple positions on the ring virtually. This technique can be essential for scaling distributed systems, like caching systems and distributed databases, that need to handle dynamic loads while maintaining high availability.

This is a topic that interested me greatly as I have–in conversations with friends in Computer Science–been consistently recommended to learn more about hashing. Through the CS-343 course, I have been looking for more ideas for algorithms and techniques to learn to improve my understanding as my senior year progresses. I will be prepared to answer questions regarding consistent hashing thanks to this article. This is of great value to me as I will continue to look for more on this topic, as I explore software development. While I did not cover every example or style found in the article, I found it all extremely interesting and comprehensive. This blog has many examples and well-made figures to explain things in a simple manner, and I will continue to use highscalability to learn more.

Source:https://highscalability.com/consistent-hashing-algorithm/

From the blog CS@Worcester – WSU CS Blog: Ben Gelineau by Ben Gelineau and used with permission of the author. All other rights reserved by the author.

6 Common Design Smells and Why They Matter

Ever work with code that feels like it’s about to fall apart? That’s often due to design smells, which are signs of poor design that make code harder to work with. Here’s a quick rundown of six big ones: Rigidity, Fragility, Immobility, Viscosity, Needless Complexity, Needless Repetition, and Opacity

1. Rigidity

Rigidity is when code is hard to change. You try to update a small feature, and suddenly you’re changing ten other things just to make it work. This makes the code stiff, leading to slow updates and frustration.

2. Fragility

Fragility means that the code breaks easily. A small change in one part of the codebase suddenly causes errors all over. Fragile code is typically too tightly coupled, meaning different parts rely too much on each other, making even minor updates risky.

3. Immobility

Immobility happens when you can’t easily reuse code in other projects. Maybe you’ve written a method that could be helpful elsewhere, but it relies on so many project-specific details that you can’t transfer it without dragging a ton of dependencies. Immobile code wastes potential and limits flexibility.

4. Viscosity

Viscosity means the code is easier to “quick-fix” than fix the right way. The messy design makes doing things properly so difficult that developers often take shortcuts, creating even more technical debt. Viscous code tempts us to compromise, resulting in even messier code over time.

5. Needless Complexity

Needless complexity is adding extra, unneeded elements to the code. This could be because someone thought, “We might need this someday,” or because they’re solving non-existent problems. Extra complexity doesn’t just add confusion; it makes the code harder to read, test, and debug. Simple solutions are usually best.

6. Needless Repetition

Needless repetition is when you see similar code blocks everywhere instead of consolidating them. When you repeat code instead of centralizing it, it violates the DRY (Don’t Repeat Yourself) principle. This makes code harder to maintain, as changes need to be made in multiple places instead of just one.

7. Opacity

Opacity is when code is confusing and hard to read. Maybe variable names don’t make sense, logic is overly complex, or comments are missing. Opaque code is like a puzzle, requiring extra time to understand, and slowing down productivity.

Why It Matters

Design smells don’t stop your code from working, but they make it harder to understand, change, and maintain. Ignoring them means the code gets more frustrating to deal with over time. By refactoring to remove these smells, you make the code cleaner, easier to work with, and more enjoyable for everyone on your team. Next time you’re reviewing code, look out for these design smells, your future self will thank you!

From the blog CS@Worcester – Anairdo's WSU Computer Science Blog by anairdoduri and used with permission of the author. All other rights reserved by the author.

GRASP

Source: https://www.youtube.com/watch?v=GcqTrlL_Htw

This video from YouTube is titled “Design Patterns GRASP // Object Oriented Analysis and Design (ICS).” As stated in the title, it goes over the design patterns of GRASP, or General Responsibility Assignment Software Patterns. GRASP is a set of 9 principles that relate to object-oriented design that help developers/engineers assign certain responsibilities to certain variables, classes, objects, etc. in software. The overall purpose of GRASP isn’t to create “fancy” code, but rather to create maintainable and reusable code/software. The 9 principles are information expert, creator, controller, low coupling, high cohesion, polymorphism, pure fabrication, indirection, and protected variations. “Information expert” places responsibility on classes that have the required information to complete it, wanted behaviors and data are put together. “Creator” places responsibility for the creation of instances of classes to classes that would use it. “Controller” places responsibility for handling system events to a class that describes the event, known as the controller. “Low coupling” states that classes should be as independent as they can be from other classes. “High cohesion” states that classes should have clear purposes with responsibilities that relate to it. “Polymorphism” is implemented so new behaviors can be added without changing preexisting code. “Pure fabrication” states that new classes should be created if there isn’t an already existing one that fulfills a desired requirement. “Indirection” states that dependencies among classes should be minimized so changes can be made without having an impact on other parts of the system. Lastly, “protected variations” encourages developers to design the system in a way that variations in behaviors are negated through encapsulation. 

I chose this particular source because we haven’t covered this topic in class yet and it seemed interesting, I found the topic from the syllabus. This video had a low amount of views and I wanted to give it a chance. After watching the video, I appreciated the fact that the information was presented in a straightforward manner and offered visual examples for each of the 9 principles of GRASP. After learning about Agile methodologies, it was interesting to learn about GRASP, because in my opinion it seems as though instead of being a set of principles of workplace improvement, GRASP seems to be a set of principles for actual work improvement. Overall, the material impacted me in a positive way because I appreciate the idea of everything in a system/software having a certain responsibility, and can definitely see how this will benefit me in the future when I work on more projects related to software development. I will certainly keep GRASP in mind for these future projects. 

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.