Category Archives: CS-343

Golden Rules for APIs

This week I have decided to view a source regarding APIs since that has been our focus in class recently. I had come across an article written by Jordan Ambra, an experienced software engineer from Pennsylvania, describing a few “rules” to keep in mind to create the best API possible and better maintain its health in the long run.

Jordan starts with his first point being proper documentation, he states “ask [a developer] to follow a tutorial or build something really basic in about 15 minutes. If they can’t have a basic integration with your API in 15 minutes, you have more work to do.” It’s important to have proper documentation because without such, having an expansive and robust API is great but what isn’t great is if the implementation of said API is very limited caused by developer confusion due to the lack of documentation.

The next point Jordan describes is the importance of API stability and consistency. This is key in having APIs last in the long run. Jordan uses Facebook as an example to show that while an API’s health won’t make or break a company, most people don’t have the capital or userbase Facebook does so recreating an API is going to be more costly for one person. Keeping track of version numbers by incorporating a change log is a great way to document changes so users know how and why to upgrade.

Another practice is to maintain API flexibility, if an API is or over time becomes too rigid it can cause integration to be difficult. Not all platforms are consistent, Jordan states, “It’s good to have at least some degree of flexibility or tolerance with regard to your input and output constraints.” So by keeping the API flexible, it’ll allow for the widest implementation without a large margin of error.

A very important aspect of APIs to prioritize is security. With malicious actors always looking for new weaknesses and ways to hijack or manipulate things for their gain, it is more important than ever to implement security safeguards to act as a preventive measure to prevent people with the wrong intentions from harming others.

Finally, the last thing Jordan brings up is the importance of an API’s ease of adoption. If things are overly complex or not universal enough it can turn people away from wanting to interact with your API. If you’re not able to efficiently use your API then how is anyone else going to be able to?

After reading this article, I hope to now be better equipped to create healthier and longer-lasting API(s) among a majority of APIs that are not easy to use which can be due to one, a combination, or all of the factors above. Focusing and prioritizing the rules set by Jordan will help in the future to improve my work.

Article Link: https://www.toptal.com/api-developers/5-golden-rules-for-designing-a-great-web-api

From the blog CS@Worcester – Eli's Corner of the Internet by Eli and used with permission of the author. All other rights reserved by the author.

Anti-Patterns

So what even is an anti-pattern? Well, anti-patterns are solutions to ineffective problems that eventually cause more problems than they solve them. They are often used because they seem to work very well but the long-term consequences are not usually thought of. Anti-patterns are just like a regular pattern but instead of a solution, they give a superficial solution but really isn’t one at all. Programming anti-patterns are known for common mistakes, they can lead to problems like maintainability. The spaghetti code is a good example of anti-pattern, it’s a code with no structure. There are random files scattered into random directories, the whole thing is difficult to follow and is tangled together. This usually happens when someone isn’t carefully thinking out their program and how smoothly it should be running before actually coding. It makes it basically impossible to add any new functionality, no matter how many changes you try to make and try to understand those changes you will still end up with countless issues with your code. Another example of anti-patterns is the boat anchor. The boat anchor happens when someone leaves a piece of code in the codebase because they believe that they will need it later but doing this actually can keep your project from moving forward, can cause your coding time to slow down, and mess up your codebase.

Avoid anti-patterns with better system management. You can avoid anti-patterns in your code by being more consistent with your system. By reviewing your code, looking through and making sure you have no typos and grammatical errors. These code reviews help improve the quality of your code and make it easier to find better solutions for any common problems your’re having. Always have someone else take a look at your code in case you did miss something that you didn’t see it’s always helpful to have a set of fresh eyes look at your code so it can help you tighten up your code. The process of engaging in code refactoring can also help make adjustments that will strengthen your code’s structure and framework without impacting the user experience. Refactoring is very helpful in simplifying your code construction.  It will make it easier for someone to take a look at your code and understand how you put the code together and be able to add any new functionality to the code as well. Making the code a visual can help give you as well as others a better understanding of the information presented to them. It can help you show the workflows, and analyze and brainstorm for any new improvements.

https://www.lucidchart.com/blog/what-are-software-anti-patterns

https://www.baeldung.com/cs/anti-patterns

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

Navigating Software Pitfalls: Understanding Anti-Patterns

In the intricate world of software development, as developers strive to create elegant and efficient solutions, they encounter not only best practices but also pitfalls to avoid. These pitfalls, often referred to as anti-patterns, are common design and coding practices that may initially seem like solutions but ultimately lead to more problems than they solve. Understanding and recognizing these anti-patterns is a crucial part of becoming a seasoned software developer.

At its core, an anti-pattern is a recurring design or coding practice that appears to be helpful but is counterproductive in the long run. It’s like a mirage in the desert – promising relief but ultimately leaving you more parched. Anti-patterns often arise from misapplications of well-intentioned ideas or a lack of experience in software development.

One common anti-pattern is known as “Spaghetti Code,” where the codebase becomes entangled and challenging to maintain. While quick fixes and shortcuts may seem like a solution, they often lead to a tangled mess that hampers productivity.

Another notorious anti-pattern is “Cargo Cult Programming,” where developers mimic code without understanding its purpose. This blind imitation can lead to code that lacks context and may introduce errors.

By studying anti-patterns, developers can proactively identify and avoid these pitfalls. It’s akin to recognizing warning signs on the road and taking detours to smoother coding practices. In the ever-evolving landscape of software development, understanding what not to do is as important as knowing what to do. Recognizing anti-patterns empowers developers to make informed decisions and craft robust and maintainable software solutions.

References:

From the blog CS-343 – Hieu Tran Blog by Trung Hiếu and used with permission of the author. All other rights reserved by the author.

rest apis

REST stands for Representational State Transfer. This means that when a client requests a resource using a REST API, the server transfers back the current state of the resource in a standardized representation.

From the blog CS@Worcester – Andres Ovalles by ergonutt and used with permission of the author. All other rights reserved by the author.

Comparing REST and SOAP API

APIs are what allow different applications to communicate with one another, making the intricate web we have access to today possible. Because the present world basically runs on the web, it is important to understand how the API system operates.

REST and SOAP API are the two main standardized types of APIs, and while the two work towards the same goal, that is, application-to-application communication, they operate differently.

Simple Object Access Protocol or SOAP API was developed by Microsoft in the late 90s. It was designed to be highly extensible so that future created functionalities could be added depending on the task for the API would be used.

Because of this extensible design, SOAP needed to be highly standardized, which is both an advantage and disadvantage. On one side, services written using SOAP API are very easy to error handle. SOAP is able to implement a built-in error handling system that even gives code suggestions for automated solutions, making it especially useful for users who do not own the web service.

However, on the other hand, while SOAP is compatible with any programming language, it was designed to rely solely on XML for messaging services. Though much of the process of writing the XML file can be automated or at least heavily simplified by the IDE using the Web Services Description Language (WSDL), this tool can only be used by NET languages (such as C# or F#). Other languages like JavaScript have to write each XML structure separately for each task, something programmers would rather not do.

Because of the more complicated nature of SOAP API, programmers later developed a simpler API system called REST.

Representational State Transfer or REST API operates using URL instead of XML to make requests. These requests are made through four basic methods: PUT, POST, GET, DELETE.

REST API is simpler than SOAP because it has the ability to use smaller messaging formats. It is also easier and often cheaper to use as it does not require the expensive tools to interact with web services that SOAP often utilizes. REST is also often faster than SOAP because it does not require extensive processing and can utilize the cache system.

Overall, the general consensus is that both systems are good at what they do and have their advantages and disadvantages. Programmers select which API to used based on multiple factors such as the language used, the environment, and requirements for the system or project.

In terms of my personal experience with APIs, I partook in an internship last summer which involved using Slack API and Python bolt — which are based on JSON-RPC — to send commands from a Slack channel to a raspberry pi. It was a simple program, but it helped me learn more about how APIs work and their important role in facilitating application-to-application communication.

For the future, I hope to look more into XML files/structures and familiarize myself with HTTP to learn more about using other APIs like REST or SOAP.

Source: https://blog.postman.com/rest-api-examples/

From the blog Stories by Namson Nguyen on Medium by Namson Nguyen and used with permission of the author. All other rights reserved by the author.

law of demeter

During the course of this course (Software Construction, Design, and Architecture), there have been design concepts that are very easy to grasp at first glance, and those that take much more time to digest. I was surprised to see that the Law of Demeter, or Principle of Least Knowledge, is a fairly intuitive rule, but feels almost too restrictive in nature.

Essentially, the Law of Demeter is the concept that methods in an object should not communicate with any element that isn’t ‘adjacent’ to it. According to a blog post by JavaDevGuy (and thinking of a Java application to the rule), the elements that are allowed by the law are the object itself (this), objects in the argument of the method, instance variables of the object, objects created by the method, global variables, and methods that the method calls.

This is most easily explained by a negative example. For example, if a class Car has a method with a Dashboard object as an argument, it can technically call something like dashboard.getVersion(). But if a class Garage method has a Car argument, the method should not call something like car.getDashboard().getVersion(). Maybe this is a silly example, but this applies to more practical code as well.

JavaDevGuy goes further to say that most Getter methods violate this law. This interpretation seems restrictive, as it makes it much more difficult to just get work done (of course, I’m not the most experienced in the design aspect of software engineering so I could be wrong). It seems more practical to use the law to get rid of chaining in your code, as it causes needless complexity. Chaining methods together, regardless of how necessary it is, always ends up looking kind of ugly. I do feel like it is a necessary evil sometimes though.

As it stands, I can understand that this sort of practice can minimize that amount of complexity and reduce code repetition, but it does feel like sometimes you sort of need to put things together in this way to get the desired output. The aforementioned blog post seems to explain when code is violating the law, but unless my eyes and brain are too tired to read properly, the author doesn’t really give any good replacement options for the code. The few alternatives given don’t seem very desirable. This is typically the problem with negative rules, it imposes a restriction without a solution, and so you have to scramble to figure out how to work it.

Perhaps I’ll understand better when we cover this material in class.

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

CS343 – Week 7

SOLID is an acronym that stands for the 5 different principles that help write high-quality, maintainable, and scalable code. These include Single Responsibility Principle (SRP), Open-Closed Principle (OCP), Liskov Substitution Principle (LSP), Interface Segregation Principle (ISP) and Dependency Inversion Principle (DIP). Each provide their own benefits and work in tandem together when designing a program.

SRP states that a class should only have one responsibility, meaning only one reason to change. This helps prevent a class from having too many responsibilities that can affect each other when one is changed. Following SRP ensures that the code will be easier to comprehend and prone to fewer errors. However, it is harder than it sounds to fulfill this principle. The quickest solution to adding a new method or functionality would be to add it to existing code, but this could lead to trouble down the road when trying to maintain the code.

OCP states that software classes, modules, functions, etc. should be open for extension but closed for modification. This is essential because it allows entities to be extended without modification so that developers can add new functionality without risking the chance of breaking the code. Adding an additional level of abstraction with the use of interfaces help design the program to provide loose coupling.

LSP states that any instance of a derived class should be substitutable for an instance of its base class without affecting the program in a harmful way. The importance of this principle revolves around the ability to ensure the behavior of the program remains consistent and predictable. Unfortunately, there is no easy way to enforce this principle, so the user must add their own test cases for the objects of each subclass to ensure that the code does not significantly change the functionality.

ISP focuses on designing interfaces that are specific to a user’s needs. Instead of creating a large interface that covers all methods, it is more beneficial to split up the methods across smaller, more focused interfaces that are less coupled. For example, having too many methods in an interface can sometimes cause issues in the code, so separating the methods into individual interfaces that can be implemented by a certain class.

DIP states that high-level modules should not depend on lower-level modules but should depend on abstractions. This approach aims to reduce coupling between modules, increase modularity, and make the code easier to maintain, test, and extend. An important thing to note is that both high-level and low-level modules depend on abstractions. Dependency Inversion utilizes the SOLID principles which in turn leads to a more refined and maintainable code.

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

Encapsulating What Varies

For this week’s blog post, I chose to discuss the design principle of encapsulating what varies, as described in the article “Encapsulate What Varies (EWV)- Design Principle” by Pankaj. This article discusses the rationale behind encapsulating what varies, its two aspects, its benefits, the strategies of implementing encapsulating what varies, and gives an example of what encapsulating what varies looks like. This article falls in line with the design principle section of the syllabus and its sub-section encapsulating what varies. I also enjoyed the section discussing the benefits of encapsulating what varies. In this blog post, I will review a few of the benefits of encapsulating what varies are mentioned in the article.

The first benefit mentioned in the article that I will be discussing is flexibility. “Flexibility: By encapsulating the parts of the system that are subject to change, we make it easier to modify or replace those parts without affecting the rest of the system. This makes the system more flexible and easier to adapt to changing requirements.” As stated in the article, when encapsulating what varies, your resulting project becomes significantly more straightforward to maintain and update in the future. Instead of having to adjust one extensive method or class, possibly causing conflicts with other parts of the project, if you isolate the factors that are likely to change in the future, you prevent possible issues with updates causing problems with unrelated systems.

The next benefit that I will be discussing that comes with encapsulating what varies is reusability. “Reusability: By creating abstractions that represent the parts of the system that are subject to change, we make it possible to reuse those abstractions in different contexts. This can save time and effort when developing new features or applications.” Being able to reuse aspects of your code in other areas is very useful in reducing time developing and bug testing. Instead of making more methods or classes that could conflict with preexisting ones, you are reusing methods or classes that you already know will not conflict with other areas in your project.

Finally, I will discuss one of the greatest benefits that come with encapsulating what varies: maintainability. “Maintainability: By isolating the impact of changes to a specific part of the system, we make it easier to maintain the system over time. This reduces the risk of introducing unintended side effects or breaking existing functionality.” As I have also mentioned earlier in this blog post, isolating frequently changing parts of the project makes it much easier to diagnose bugs or other issues that may come up as the project is developed or as it is updated as time goes on.

Article: https://www.neatcode.org/encapsulate-what-varies/

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

The Magic Behind Software Frameworks: Understanding Their Role & Importance (Week-7)

In the vast world of software development, there’s a term that’s often tossed around, especially when discussing the foundation of any application or website: Software Frameworks. For those on the periphery of tech, this term might sound intimidating or complex. However, software frameworks are essentially tools that simplify our digital lives, both as developers and users. Let’s delve into what they are, why they matter, and the magic they bring to the table.

What Are Software Frameworks?

At its core, a software framework is a platform or foundation that provides a structured way to build and deploy software. Think of it like a skeletal structure upon which developers can flesh out their applications. It provides a set of guidelines, tools, libraries, and best practices that developers can follow and utilize to streamline the development process.

Why Do Software Frameworks Matter?

  1. Efficiency & Speed: Instead of starting from scratch, developers can leverage pre-written chunks of code, leading to faster development cycles.
  2. Consistency: Frameworks provide standardized practices, ensuring that applications are built consistently and are maintainable in the long run.
  3. Scalability: As a business grows, its software needs might evolve. Frameworks often come with built-in tools and conventions that make scaling up (or down) more manageable.
  4. Security: Many popular frameworks undergo rigorous testing and have built-in security measures to help protect against common vulnerabilities.

Popular Software Frameworks:

  1. Web Development:
  • Django: A high-level Python web framework that encourages rapid development and a clean, pragmatic design.
  • React: A JavaScript library for building user interfaces, particularly single-page applications.
  1. Mobile Development:
  • Flutter: A UI toolkit for crafting natively compiled applications for mobile, web, and desktop from a single codebase.
  • React Native: Enables developers to build native mobile apps using JavaScript and React.
  1. Backend Development:
  • Express.js: A fast, unopinionated, minimalist web framework for Node.js.
  • Ruby on Rails: A server-side web application framework written in Ruby.

In Conclusion:

Software frameworks are the unsung heroes of the tech world, working behind the scenes to ensure that the applications and websites we rely on daily are robust, secure, and efficient. By providing a structured foundation, they enable developers to focus on what truly matters: creating innovative solutions and improving user experiences. Whether you’re an aspiring developer or just a tech enthusiast, understanding the role of software frameworks can offer a deeper appreciation for the digital tools that power our connected world.

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

CS343 Blog Post for Week of October 22

This week, I wanted to continue from my previous entry describing the Single Responsibility Principle. The next concept named in the SOLID design philosophies is the Open-Closed Principle. I first heard the name of this design philosophy in one of my computer science courses. I couldn’t figure out what exactly it meant just going intuitively from the name, however, so I returned to the Stackify website from my previous blog post to continue reading about the SOLID principles.

The Open-Closed Principle was first coined by Bertrand Meyer in his 1988 book “Object-Oriented Software Construction”. Robert C. Martin would later adopt the Open-Closed Principle, calling it “the most important principle of object-oriented design”. He would explain the Open-Closed Principle as “Software entities (classes, modules, functions, etc.) should be open for extension, but closed for modification.” In practice, this means programming such that new functionalities may be added without changing the existing code.

Bertrand Meyer originally proposed inheritance as a means of abiding by the Open-Closed design principle, but this introduces the problem of tight coupling between software classes. If one class is too dependent on a parent class to function, it will be difficult to make changes to one class without modifying the other class to maintain functionality. Instead, Robert C. Martin suggests using interfaces rather than concrete superclasses, redefining this design philosophy as the Polymorphic Open/Closed principle. The abstraction provided by interfaces helps avoid the problem of tight coupling between software classes.

The article goes on to provide a practical example of the application of the Open/Closed principle through creating a software class representing a coffee machine, and an accompanying class representing a simple app that controls the coffee machine. The article presents the situation where the user may have a different kind of coffee machine that they would like to control with the same software app. The process of refactoring the BasicCoffeeMachine code to implement a broader CoffeeMachine interface is detailed, as well as the process of refactoring the CoffeeApp to utilize the new CoffeeMachine interface. This way, the functionality of our software was greatly expanded, without having to remove large portions of our previously written code.

I chose to research more about the Open/Closed Principle this week because I don’t find myself using interfaces in my projects as often as I should. I could save space and make my code more efficient if I took care to design my software classes to an interface. The example in the article seems like it is employing the Strategy method when instantiating the CoffeeMachine objects. Understanding both the Strategy method and the Open/Closed principle will help me to make better use of interfaces when designing software classes in the future.

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