Author Archives: rainiery

Code Smells

https://blog.codinghorror.com/code-smells/

This blog post will center on code smells which was a topic covered in class fairly early on. The reason why I’m going back to it is mainly to refamiliarize myself with the subject since it wasn’t a major topic in class. Code smells are defined by the blog post linked above as general warning signs in code, hence the name. There are different types of code smells that signify different coding problems. For example, long comments, long methods, overly large classes, duplicate code, dead code, inconsistent naming, uncommunicative naming, et cetera. Keep in mind that these issues won’t necessarily stop a program from running, rather they negatively effect on the performance and design levels. Also, all of these different types of code smells share the common trait of not quite looking right when looking at a larger scale. So at first glance the code might seem fine, but given a closer look the flaws whether it be dead code, inconsistent naming, or whatever become readily apparent.

A code smell isn’t something concrete like a detailed recipe, it’s more abstract than that. It similar to a suggestion or a tip and can lead to improving code both on a functional level and a design level. Take for example, noticing the code smells of long comments and dead code which suggest removing the useless code and either simplifying or outright deleting the comments. This will make the code more readable which also improves it on a design level. On the other hand, noticing the code smells of duplicate code and long methods and correcting each issue accordingly will improve the code on a performance level top of the possible design improvements. All of the types of code smells that I listed earlier still hold true but they act as more of a general guideline. There are some scenarios in which some smell types blend together such as long methods and overly large classes to name one. Detecting code smells isn’t going to always be the same in that what someone is looking for will differ every time and the outcome will also differ every time. This process is kind of like trying to find freshly spoiled food; sometimes it looks fine and sometimes you won’t know what exactly you’re looking for. But what you do know is that something smells off and you probably don’t want to risk the chance of getting sick.

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

DRY (Don’t Repeat Yourself)

https://thevaluable.dev/dry-principle-cost-benefit-example/

I’ve chosen to talk about a very simple design principle this week called “Don’t Repeat Yourself”, DRY for short. It’s a topic that is covered in this class according to the syllabus and I chose it since its similar to another topic I covered YAGNI in that they’re easy to understand design principles. The meaning is quite self-explanatory, don’t repeat code since if you need to change the behavior of a certain project, you’d have to rewrite numerous lines of code if DRY wasn’t applied. However, applying this principle to everything isn’t efficient either. Trying to apply DRY everywhere causes unnecessary coupling and complexity which also leads to more difficulty changing behavior. According to the link above, using DRY means emphasizes knowledge above all else. What it means by that is that when designing and constructing software, one should have the knowledge of when to apply DRY and when not to for the sake of the readability and efficiency of the code.

In that context, DRY reminds me of the importance of resources in a computer when running something. If you want something run faster, you’ll have to sacrifice more memory. And when you want something to have more memory, you’ll have to sacrifice more speed. Both are valid choices; it really depends on the needs of the software and the user. Say for example, I want to create a program that lists all numbers from one to 100 which I do by writing out a thousand lines of code in which each prints a number. However, if I implement DRY, then I could create an integer variable r and a loop which prints the value of that variable and increments it by one until r equals 100. But the case where I want to alter the behavior to list every odd number between one and 100 is where thing get a bit interesting. In the DRYless scenario, I can simply delete the lines of code that print even numbers. Yet in the scenario with DRY, I’d have to add a condition that skips printing variable r for that iteration of the loop. You have to sacrifice complexity for readability and vice versa. Though the choice is ultimately up to what works best in the current situation. Like in my example, the added complexity from DRY doesn’t really harm the readability, in fact it improves it in some ways, at least in my opinion.

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

Refactoring

https://www.agilealliance.org/glossary/refactoring/#q=~(infinite~false~filters~(postType~(~’page~’post~’aa_book~’aa_event_session~’aa_experience_report~’aa_glossary~’aa_research_paper~’aa_video)~tags~(~’refactoring))~searchTerm~’~sort~false~sortDirection~’asc~page~1)

This week we’ll be covering refactoring which is a very simple but also very important concept to software design similar to models, the topic I covered last week. The reason why I’ve chosen to talk about refactoring is because while it’s a topic that hasn’t been specifically covered in class; I have had experience learning about a form of refactoring in this software process management class I’ve been taking. According to the link above, refactoring is the process of improving the overall structure of a program’s source code. However, this does not mean that the functions of the program are altered in any way. For example, the interface is not improved on, bugs are not fixed, and code isn’t outright rewritten to change the behavior of the program. Refactoring instead cleans up and organizes the source code in order to be more easily readable and understood. An example of this would be simplifying the two lines “answer = 2 * 5;” and “answer = answer * 8;” into the line “answer = 2 * 5 *8”. This change simplifies the code and makes it easier to understand at a brief glance. On a smaller scale, refactoring can be used to remedy code smells and remove duplication. But on a larger scale, refactoring can alter large bodies of code towards different design styles such as object oriented or functional.

The benefits to refactoring do not end at organization and raising code readability. Refactoring also encourages the use of reusable design elements and code modules. These reusable elements and modules highlight the structural similarities and differences in each code module. Refactoring also improves attributes of code that cause easier maintenance like length, duplication, coupling, cohesion, and cyclomatic complexity. Since refactoring often simplifies source code, the length and complexity are also often times lowered which again makes code easier to read. In order to efficiently refactor code, the dependencies (cohesion) and independencies (coupling) of each module will have to be highlighted in the overall structure of the code. And in the case of duplication, it has already been stated that refactoring can remove it from source code. All of these benefits return back to the intended purpose of refactoring, improving the overall structure of a program’s source code by cleaning and organizing it. It’s a form of proofreading and revising code but also comes at the risk of accidentally changing the behavior of a program. So individuals using refactoring should have a good grasp on which part of their code does what in order to avoid that issue.

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

Models

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

https://c4model.com/

For this week we’ll be covering modeling which is an important aspect in not only software design, but also design in general. Modeling is a very simple concept; it is when one creates a visual representation of a project, program, or whatever someone is working on. It is a visual tool used to streamline and simplify the process of development. In software design, there are two specific types of models which are called UML and C4 diagrams. UML, which stands for Unified Modeling Language, is used to give a visual representation to the architecture, design, and implementation of a software system. For example, a software system by a group of interconnected boxes which symbolize each class in that system. A class is represented in UML as a box which is separated into three sections which hold the name of the class, its attributes, and its operations. C4 meanwhile is used to give a visual representation to the architecture at different levels of detail. For example, a software system is represented by an interconnected group of boxes symbolizing each element of that system. As one zooms closer, each element breaks down into smaller parts that make up of that component. This process spans four levels from the system context level, to the container level, to the component, to the code or UML level. The key difference between C4 and UML diagrams is that C4 uses the general framework of UML to visualize a software system at greater scales.

The general importance of these models is that before creating software, you have to form a plan. If one were to skip this step, they would likely run into multiple problems like forgetting to implement a part of the software, making a mistake that isn’t noticed until much later, or having no clear direction in development. Often times when these mistakes are made, developers would have to devote time to correct them when they could have created a model allowing them to develop more of the software in a shorter amount of time. Models can also be useful with how they can make peer review easier. If a developer wants a peer’s feedback on the general structure of their work, they can give them an easy to understand model rather than the code for the classes that make up an entire software system. Models are a very simple but also very important aspect to software development which is also the main reason why I chose to write about this topic.

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

Rest API Design

https://www.mulesoft.com/resources/api/what-is-rest-api-design

https://restfulapi.net/

The topic I’ll be writing about this week is Rest API design which is one of the topics listed to be covered in the class syllabus, though we haven’t covered it yet if at all. It’s also worth noting that the following information is taken from the websites linked above. Rest API design or simply Rest stands for REpresentational State Transfer and is an architectural style for distributed hypermedia systems. The purpose of Rest is to create web services that have reliability, fast performance, and the ability to grow by reusing components that are managed and updated without affecting the larger system. There are six guiding restraints that an API must follow to implement Rest. The first is “client-server” which states that the client and server should be completely separate in order to improve scalability and portability. The second is “stateless” which means that each call should contain all the data needed to complete itself. The third is “cacheable” which means that the storage of cacheable data should be encouraged. The fourth is “uniform interface” which means the interface should follow four constraints: identification of resources; manipulation of resources through representations; self-descriptive messages; and, hypermedia as the engine of application state. The fifth is “layered system” which means ordering components in a layered system. The sixth and optional constraint is “code on demand” which means REST allows code or applets to be transmitted via API for use within the application.

            Rest API design is generally used to increase performance and make web services that implement is easier to use. For example, the first constraint “client-server” as I already mentioned earlier increases scalability and portability. The second constraint “stateless” reduces the amount of work a server or a client needs to do depending on which is calling. The same applies to the other constraints; they all improve on a web service in some way or another. Of the sources I’ve looked at, I could only find one major drawback which is that you can lose the ability to maintain state in REST, such as in between session. But even then, it’s not that big of a drawback since one of the constraints of REST is refraining to use states so it’s an intentional design choice. So overall, Rest API design is an architectural style that sets out to accomplish a specific goal and does it well with minimal drawbacks. And from what I’ve read, there is really no reason to not use it if states aren’t required and the goal of the designer is to save resources.

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

Software Frameworks

https://techterms.com/definition/framework

            The link above leads to a website article that explains what a software framework is while giving some examples. The two main reasons I chose to write about this topic is because of one, it’s listed as one of the topics to be covered in class and two, I’m not too familiar with the definition of a software framework. According to the article, a software framework is essentially a set of tools that act as a foundation for software developers. These may include preset classes, APIs, compilers, code libraries, and predefined functions among other things. Examples of software frameworks include Microsoft’s .NET framework, Android Application Framework for Android, Cocoa Touch for iOS, and Cocoa for Mac OS X.

            From the definition given, the practicality of a software framework seems pretty apparent to me. Rather than creating classes and functions from scratch that will most likely see reuse, set them together in a ready to use package in order to save time and effort. It’s similar to how someone would buy ingredients at the supermarket rather than making each one from scratch. I’d imagine that software frameworks also have the added benefit of increasing portability for software that uses a specific framework. Take for example my computer which has .NET framework on it. If I were to create a piece of software using .NET, then another machine which has a similar version of same framework would be able to run my software with no additional setup needed. To be fair this is only speculation on my part; I haven’t checked whether or not this is true yet. But then again, I remember having to install a newer version of .NET framework in order for my computer to run software correctly so I might be on the right line of thinking.

In the case of porting software to machines with different operating systems, I’m not sure what role frameworks would take. I am pretty confident that software frameworks aren’t limited by operating systems. One example being Java Collections Framework or JCF for short which, as far as I know, isn’t limited to an operating system like .NET is. When a difference of frameworks is a factor, I assume that a software developer would have to make up for a lack of a framework’s components in a machine in some way. And that’s on top of the usual changes needed for porting software between operating systems.

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

Thoughts on YAGNI

The link at the very bottom is an article focusing on a design philosophy YAGNI which is one of the topics we’re supposed to cover in class, though we haven’t gotten to it yet as of my writing this. The name is an acronym of “You Ain’t Gonna Need It” which is basically means if the situation doesn’t immediately call for something to be done, then don’t bother with it. The acronym’s meaning is also the main reason why I chose to write about this topic; it sounded funny to me. The article goes on to describe four “costs” that YAGNI mitigates. The first is the cost of build which is the time and effort spent on analyzing, programming, and testing something. The second is cost of delay which is the cost of pushing back other priorities in order to work on what is deemed more important. The third is cost of carry, the complexity that something brings to software and how that modifying and debugging more difficult. And the last is cost of repair which is self-explanatory. By only working on what is immediately important, the chances of wasting time or changing the program are reduced significantly.

What I find interesting about YAGNI is that in a way, it’s telling people to wing it. The biggest reason for that is because in everyday life, sometimes plans change because of unforeseen circumstances. Let’s take for example someone meticulously planning out a program while taking multiple scenarios into consideration and designing different components to compensate. But it later turns out that many of these scenarios are either unlikely or are taken care of by other things outside of the program that this person didn’t even know about. That in turn causes cost of carry because of all the components complicating the core program, cost of build from the time and effort wasted on designing and implementing these components. These are a lot of headaches that are solved by just being lazy and that’s kind of funny to me.

Something else I noticed is that YAGNI is a really simple design philosophy, to the point where it isn’t strictly constrained to software design. Another example I’ll bring up is how when I was younger, I would waste time writing essays by agonizing over small minute details. And a piece of advice I would often get is to write out my first draft no matter how horrible and worry about fixing the details when the time comes. That isn’t to say that drafting out an outline isn’t important; this applies both to essay writing and software design. The truth is that there should be a balance between YAGNI and other design principles which the article does acknowledge even though it does downplay it.

Link: https://martinfowler.com/bliki/Yagni.html

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

Introduction

Hello, my name is Rainiery and I’ve started this blog for the class “Software Construction, Design & Architecture” as well as for my career down the line.

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