Author Archives: Fadi Akram

Blog Post 5 – SOLID Principles

When developing software, creating understandable, readable, and testable code is not just a nice thing to do, but it is a necessity. This is because having clean code that could be reviewed and worked on by other developers is an essential part of the development process. When it comes to object oriented programming languages, there are a few design principles that help you avoid design smells and messy code. These principles are known as the SOLID principles. These principles were originally introduced by Robert J. Martin back in 2000. SOLID is an acronym for five object oriented design principles. These principles are:

  1. Single Responsibility Principle – A class should have one and only one reason to change, meaning that a class should have only one job. This principle helps keep code consistent and it makes version control easier.
  2. Open Closed Principle – Objects or entities should be open for extension but closed for modification. This means that we should only add new functionality to the code, but not modify existing code. This is usually done through abstraction. This principle helps avoid creating bugs in the code.
  3. Liskov Substitution Principle – 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. This means that subclasses can substitute their base class. This is expected because subclasses should inherit everything from their parent class. They just extend the parent class, they never narrow it down. This principle also helps us avoid bugs.
  4. Interface Segregation Principle – 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 helps keeps the code flexible and extendable.
  5. Dependency Inversion Principle – 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. This means that dependencies should be reorganized to depend on abstract classes rather than concrete classes. Doing so would help keep our class open for extension. This principle helps us stay organized as well as help implement the Open Closed Principle.

These design principles act as a framework that helps developers write cleaner, more legible code that allows for easier maintenance and easier collaboration. The SOLID principles should always be followed because they are best practices, and they help developers avoid design smells in their code, which will in turn help avoid technical debt.

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

Blog post 4 – Semantic Versioning

One of the more interesting topics that we covered in class was semantic versioning. I found it interesting because it is something that I see all the time but had no idea what it meant. After reading over the documentation, I’ve learned that semantic versioning is a set of rules that dictate how version numbers are assigned and incremented. Semantic versioning was proposed as a solution to dependency hell, which occurs when you version lock or when version promiscuity prevents you from easily and safely moving your project forward.

Semantic versioning works in three parts, X, Y, and Z. They are usually written as X.Y.Z, as that is the form semantic versioning must take. Each component says a different thing about the version. The X states what the current major release is, the Y states what the current minor release is after the last major release, and the Z states what the current patch release is after the last minor release. What do a major release, minor release, and patch release mean?

A major release is the first part of the semantic versioning framework. It goes at beginning of the version number. A major release occurs when you make incompatible API changes. The changes must be backward incompatible in order to be considered major. A major version zero is for initial development, and anything may change at any time. When a new major update is released, the minor, and patch version numbers must be reset back to zero.

A minor release is the second part of the semantic versioning framework. It goes in the middle of version number.  A minor release occurs when you add functionality in a backward compatible manner. A minor release needs to be incremented every time any public API functionality is marked as deprecated. Minor releases could also be incremented if substantial new functionality or improvements are introduced within the private code, and it could include patch level changes. When a minor update is released, the patch version number must be reset to zero.

A patch release is the third and final part of the semantic versioning framework. It goes at the end of the version number, and it refers to an update that focuses either exclusively or primarily on bug fixes. A bug fix is a change made to the code to correct incorrect behavior. A patch release does not add any new features, it just modifies existing code to fix errors or make the code run the way it was intended. All the bug fixes must be backward compatible.

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

Blog post 3 – REST API

After spending some time in class working with the REST API, I found myself still having questions regarding what it is and how it works. I decided that I should do some further reading on my own, and I thought that I should make a blog post explaining my findings. I read several articles, but one article in particular by IBM I think describes REST API the best.

Before we delve into REST itself, we first have to understand what an API is. API stands for application programming interface; it is a set of rules that define how applications or devices can communicate with each other. It’s a mechanism that allows applications to access resources within other applications. The application that is utilized to access the other application is called the client, while the application that contains the resources being accessed is called the server.

REST API is an API that uses REST principles. Unlike other APIs which have pretty strict frameworks, REST is pretty flexible. The only necessary requirement is that the REST design principles, or architectural constraints, are followed. These are:

  1. Uniform interface – All API requests for the same resources should be the same regardless of where the request came from.
  2. Client-server decoupling – The client and the server need to completely independent of each other. The client should only know about the URI, or the Uniform Resource Identifier, and the server should only pass the client to the requested data via HTTP.
  3. Statelessness – All requests need to include all the information necessary to process them.
  4. Cacheability – Resources should be cacheable on both the client and the server. The server should also know whether or not caching is allowed for a delivered resource.
  5. Layered system architecture – The calls and responses go through different intermediary layers.
  6. Code on demand – Usually, REST APIs send static resources, but in some cases, they can also contain executable code. In such cases the code should on run on-demand

I didn’t know that REST API had design principles, so this was new information to me. However, so far, I only discussed what REST API is, we still need to understand how it works. REST APIs communicate using HTTP, Hypertext Transfer Protocol, requests to perform basic functions in databases like creating, reading, updating, and deleting data inside a resource. For example, a GET request would retrieve data, a DELETE request would remove data, a PUT request would update data, and so on. All HTTP methods are able to be utilized in API calls. Another thing to note is that the resource representation can be delivered to the client in virtually any form including JSON, HTML, Python, and even normal text files. Finally, it’s important to note the request headers, response headers, and parameters in calls. They’re important because they contain vital identifier information such as URIs, cookies, caching, etc.

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

Blog post 2 – Design Smells

In programming, we often make a lot of mistakes, some break the code, and some do not. The ones that do not tend to bring down the efficiency of our code and make it very difficult to work with. Some of these mistakes have to do with the way we write the code, and they tend to hint at a bigger problem in the code design. These mistakes are called design smells. I think Martin Fowler defines coding smells the best, he defines them as a “surface indication that usually corresponds to a deeper problem in the system.” Design smells come in all different ways, but they usually stem from developers not following best practices. The end result is that the code either becomes too bloated, too inefficient or breaks easily. Luckily, design smells are rather easy to spot once you know what they are. Some of the more common smells are:

Rigidity – Program breaks in many places when a single change is made to the code.

Immobility – The code contains parts that could be useful in other systems, but the effort and risk involved in separating those parts from the original system are too great.

Opacity – This smell occurs when the code is difficult to understand and follow.

Fragility – The code becomes pretty difficult to change. A simple change could cause a cascade of subsequent changes in dependent modules.

Viscosity –  When making changes to the code, it is easy to do the wrong thing, but hard to do the right thing.

Needless complexity –  There are elements in the code that are not useful. Having them in the code is simply not necessary and it makes the code more complex than it needs to be.

Needless repetitiveness –  There are too many repeating elements in the code that could be removed by using abstracted or refactoring the program.

These are things that we do not want in the code. In fact, they are considered technical debt. Technical debt is a term that describes the effects of mistakes or bad practices in code. As we program, we are going to make mistakes, errors, and sometimes not follow best practices. These shortcomings are things that we will have to revisit later today and spend time, resources, and effort spent on trying to fix and modify the code to make it work better. In this sense, it is similar to normal debt.  Once you know the smells, it’ll become a lot easier to find them in your code. If you do spot design smells, then it is best to try to remove and solve the underlying problem.

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

Blog post 1 – UML Class Diagrams

For my first blog, I wanted to discuss UML Class Diagrams, a topic we covered in class. They help put programs in perspective by showing their structure. UML class diagrams have a very simple set up. Each class is represented by a box, and in each box, there are 3. All classes have these boxes, and all these boxes are divided in the same exact way. They look like this:

When writing class names, they must be in bold, and they must start with a capital letter. The font is also used to show other details like what kind of class it is. If it is in bold then it is a concrete class, if it is in bold and italics then it is an abstract class. If you want to denote a specific type of abstract class, like an interface, then it will use the same markdown setup as an abstract class, however, it will have the classifier «interface» on top of the class name. So, it should look like this:

Attributes are listed in a specific way, and this is something that I had a tough time getting used to. Generally, in programming languages we write the data type followed by the variable name, however in UML Class Diagrams, it’s the other way around. Attributes are listed first by name then by data type, and the two are separated by a colon. There is one more thing to touch on, and that is the visibility of the attribute. To denote a public attribute, there should be a (+) sign in front of it. To denote a private attribute, there should be a minus (-) sign in front. Finally static operations are distinguished by an underline font.

Finally, we get to operations. They work similar to attributes; the only difference is that operations are denoted with parentheses. The return type of the operation, its visibility, and so on works the same way as attributes. If a class a has a parameter, then it listed as an attribute but inside the parentheses. It should look something like this:

Note that the class name in this example should have been bolded.

Finally, we get to the last element that I will discuss, and that is relationships. Since these diagrams are meant to be a blueprint to show how programs are structured, we need to show how the classes interact with each other. Tis done with arrows. There are three different types of arrows that show different types of relations.

Solid Arrow: The class utilizes the attributes of the class it points to.

Hollow Arrow: The class extends the class it points to.

Dotted Arrow: The class implements the class it points to.

This is how they look like in use:

This is a very basic overview explaining my understanding of how UML Class Diagrams work. There are many other elements that left out such as multiplicities and composition. I recommend using the sourced I used for further reading:

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


Hello everyone, welcome to my blog! I’m a senior computer science major at Worcester State University. I will be using this blog to document my journey in CS-343.

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