Monthly Archives: September 2019

Digital Code apparently can smell.

How can code smell? This was my
question last class in my Software Architecture class, and I was surprised to
learn that it can. Not literally of course, but because code can be written in
a manner that somebody may say that there is something going bad in here, as
food would. According to Wikipedia
Code Smell is
: “any characteristic in the source code of a program that
possibly indicates a deeper problem” and “Code smells are usually not bugs;
they are not technically incorrect and do not prevent the program from
functioning. Instead, they indicate weaknesses in design that may slow down
development or increase the risk of bugs or failures in the future.” This is a
very interesting topic in my opinion because it can make me and other alike to
be a better coder and help us avoid common mistakes.

While searching for some more
information about the topic I have stumbled upon blog by Jeff Atwood that gives
and describes different kinds of smells that code can have. This directly related
to my class and helped me to specify different problems that can arise when I create
some software. In the class we have described smell in a little bit broader
scope then in the blog, which describes more detailed cases. For example,
Atwood gives us this: “Long Method – All other things being equal, a shorter
method is easier to read, easier to understand, and easier to troubleshoot.
Refactor long methods into smaller methods if you can.”, and in my opinion
anyone writing code nowadays can agree with that assessment. I know it can be
hard sometimes to write a short method because it would be more functional, and
that is a one of the subjects of one of my classes I took before about writing
clean code.

In my opinion this blog is a great reference
for everybody who wants to keep in mind problems that can arise, or to say avoid
you code from smelling a certain way. I know it will be helping me a lot both
in my school and professional life. Eventually anybody can learn this by heart
and know it  at the drop of a hat, but
for me until it will become almost a reflex I know I will be probably using
this post and other like it as a reference. Anybody who has plans to have a career
in a Computer Science field should learn this.

From the blog #CS@Worcester – Pawel’s CS Experience by Pawel Stypulkowski and used with permission of the author. All other rights reserved by the author.

What is UML?

UML Diagrams – as a CS major at a university
I realize that sooner or later I would have heard something about it and had to
work with it, on that subject even though I am already a little bit familiar I
found myself a little bit lacking in knowledge because I simply didn’t have to
deal with it too much. To help me familiarize myself with them I stared browsing
the net and stumbled upon this blog
by Noel Ceta on Tallyfy website, which helped me to understand the topic a
little bit more.

                This
blog goes into some details about different types of UML diagrams and what are
they best used as well as how they look and present. It gives some examples on
each one of them which helps a lot to help and differentiate between them. It helped
me. Even though I am supposed to use UML at work because it helps with
documentation, I rarely do due to the time constraints of the projects I work on
and honestly nobody makes it a big issue, which is a problem, I think.

Noel in his blog uses one of the descriptions
of UML as follows: “Sketch – UML diagrams, in this case, are used to
communicate different aspects and characteristics of a system. However, this is
only a top-level view of the system and will most probably not include all the
necessary details to execute the project until the very end.

Forward Design – The design of the sketch is done before
coding the application. This is done to get a better view of the system or
workflow that you are trying to create. Many design issues or flaws can be
revealed, thus improving the overall project health and well-being.

Backward Design – After writing the code, the UML diagrams
are drawn as a form of documentation for the different activities, roles,
actors, and workflows.”. This description really fits with what I think UML is
and how it should be used.

                Over all
this blog post is a good way to introduce people to UML and show them what a powerful
tool they can be if, like in my own life’s example, they are used and people
spend time to work with the design of their software starting with UML. I believe
everybody should learn about this because not only CS majors will find it
useful but others as well, for example a business person who can describe the
relationships in their business to better understand it or to describe it to
others.

From the blog #CS@Worcester – Pawel’s CS Experience by Pawel Stypulkowski and used with permission of the author. All other rights reserved by the author.

Before we start….

To kick things off for my blog
about Software Architecture I would like to say a few words about programing
itself. I have recently read a blog
post
by Joseph Gentle called “3 tribes of programming” from May third of
2017.

In his blog he talks about a subtle
but nevertheless existing differences between people who write code. Gentle
says: “… I think there’s fundamentally 3 architypes of programmers, divided by
which ideals we hold in highest esteem: You are a poet and a mathematician.
Programming is your poetry; You are a hacker. You make hardware dance to your
tune; You are a maker. You build things for people to use. We self-select into
communities of our peers based on these ideals. We use coded language to
express these ideals to our peers. I think each group has its own conferences,
and its own subreddits. Its own programming languages, heroes and its own
villains.”, and I could not agree more. Each camp as he says has its own quirks
and they are spelled rather plainly in my opinion.

I have chosen this blog to write about
because it gives me and hopefully other an idea of what kind of a programmer one
wants to be, and how I will possibly design my software in the future. I work
as low-level programmer for a big company, and I work with some very talented people.
Take my boss for example, in accordance with this blog and its descriptions he
will be in the second camp (The Hardware Hacking people) but with a small twist
of camp 1 (Mathematician) since he loves beautiful and easy flowing code. Based
on that I would be in the 3rd camp, I use programming as a tool to
make things, be it a simple app to help me with things or something work
related to help me in that aspect. I like people using my software and having
some feedback about, even if it not too good at least I know somebody took their
time to check it out. I design my programs with the end user in mind most of
the time.

Reading Gentles blog helped me to familiarize myself more with how others might think about programming and how to approach certain aspects of it, but it also helped me see that “Ultimately code is code. Even though we have different reasons for writing software, what we write is (usually) compatible. And even when it’s not (looking at you, Haskell) – there’s always a lot of ideas we can learn from and steal.”. We all have some part to play in this world of Computer Science and we all help each other one way or another, no matter which camp somebody belongs to.

From the blog #CS@Worcester – Pawel’s CS Experience by Pawel Stypulkowski and used with permission of the author. All other rights reserved by the author.

Refactoring: Spring Cleaning for Code

Depending upon the subject, some of us are lucky to finish a functioning project so the thought of improving code after the fact – especially if there’s a new project due soon – is a distant one. However, they may be tricked into refactoring their code if asked when you say the magic words: “Refactoring is not rewriting code”. The definition, as defined by its creator is:


“a change [or changes] made to the
internal structure of software to make it easier to understand and cheaper to
modify without changing observable behavior.”


In
reality, the process may involve:

  • new
    code, but it must not change the behavior of the original code;
  • ensuring
    the system works before and after each refactor, including original unit tests;
  • creating
    unit tests to verify our refactoring has not changed system behavior;
  • changes
    that individually are minute, but combined lead to a healthier program;
  • eliminating
    duplicate code, potentially changing variable names, and more.

It is not
simply cleaning up code, but rather reorganizing it in order to make it easier
to trace and understand, as well as add functionality to in the future.

              For our purposes, this may be a very
important concept to learn but it may be some time before we get to implement
it, unless we’re coding or maintaining an entire program for our capstone; however,
it is important to understand when to do so. According to my sources, the best
time to do so is before you add new features to an existing program, or right
after you’ve already shipped it. For the former, it makes these new features much
easier to add when the program is much more readable and makes the program better
for having made the changes. As for the latter, it makes a lot of sense to
snoop around for ways to reorganize code after you’ve spent so much time on it,
and in a mad dash to finish it towards the end no doubt. Years’ worth of work
is no doubt going to have some inconsistencies that fell through the cracks in
the course of development.

              As for implementing these changes, there are several methods, including Red-Green-Refactor, Abstraction, Simplifying Methods, as well as many others we won’t cover. In R-G-R, red means stop and determine what to develop – usually with a new test that fails, getting this new development to pass tests (green), and finally refactoring to optimize. Abstraction is used to address duplicate code and can be done by restructuring hierarchies using the Pull-Up [pulling up code into a superclass to be shared more effectively] or Push-Down [pushing down code to more subclasses from a superclass] method. Finally, Simplifying Methods is an effort to simplify older code by consolidation and reducing interclass complexity. Hopefully this helps develop an understand of refactoring, in fact, I had to do quite a lot of refactoring to this blog to get it down to size!


Sources:

Refactoring – Martin Fowler
Refactoring – Agile Alliance
Code Refactoring Best Practices: When (and When Not) to Do It

From the blog CS@Worcester – Press Here for Worms by wurmpress and used with permission of the author. All other rights reserved by the author.

Software Construction, Design and Architecture for Design Patterns

The Creational

The object creation and or the class instantiation is
the core center of the design patterns, the design patterns will be divided
into object-creational and Class-creational patterns. The Class-creational use
inheritance during the process, however the object-creation uses the delegation
during the process to finish the task.

The Creational Design patterns:

  • Abstract
    Factory
  • Builder
  • Factory
    Method
  • Object
    Pool
  • Prototype
  • Singleton

To make this clear I found this example on Geeks for
Geeks web site (Abhijit Saha).

When a developer design simple DBConnection class to
use it to connect into a database, he will the access the database at multiple
locations from code. That will be by creating an instance of DBConnection class
and it will be used to do database operations as needed. Which results in creating multiple
connections from the database as each instance of DBConnection class will have
a separate connection to the database. In order to deal with it, we create DBConnection class as a singleton class, so that only
one instance of DBConnection is created and a single connection is

The Structural

What the design patterns do, is forming or more on organizing
the multiple classes and objects which will create the structures which will
provide the new functionality.

Structural design patterns are:

  • Adapter
  • Bridge
  • Composite
  • Decorator
  • Facade
  • Flyweight
  • Private
    Class Data
  • Proxy

Another Example is here to show how the Structural
design patterns are working (Abhijit Saha).

If there are incompatible interfaces and the developers
want to make establish a relationship between them through an adapter it’s
called adapter design pattern. Adapter pattern converts the interface of a
class into another interface or classes.

The Behavioral

all what the Behavioral
patterns are about is recognizing and identifying the common communication
patterns between objects.

Template
pattern defines the skeleton of an algorithm in an operation deferring some
steps to sub-classes, Template method lets subclasses redefine certain steps of
an algorithm without changing the algorithm structure. (Abhijit Saha).

The Behavioral patterns are:

  • Chain of responsibility
  • Command
  • Interpreter
  • Iterator
  • Mediator
  • Memento
  • Null Object
  • Observer

The Concurrency Patterns

The choice of
concurrency architecture has a significant impact on the design and performance
of multi-threaded networking middleware and applications.

The Concurrency Patterns are:

  • Active Object
  • Monitor Object
  • Half-Sync/Half-Async
  • Leader/Followers
  • Thread-Specific Storage
Works
Cited

Abhijit Saha, Tanuja Praharaj. Design Patterns.
2015.
<https://www.geeksforgeeks.org/design-patterns-set-1-introduction/&gt;.

Babu, Dinesh. DESIGN PATTERNS Creational design patterns.
n.d. <https://www.academia.edu/37967381/DESIGN_PATTERNS_Creational_design_patterns&gt;.

Mallawaarachchi, Vijini. 10 Common Software Architectural
Patterns in a nutshell
. 2017.
<https://towardsdatascience.com/10-common-software-architectural-patterns-in-a-nutshell-a0b47a1e9013&gt;.

From the blog CS@Worcester – Shams&#039;s Bits and Bytes by Shsms Al Farees and used with permission of the author. All other rights reserved by the author.

The Factory Design Pattern

There are many design patterns that assist in building software architecture. They fall into four categories: creational; structural; behavioral; and concurrency. Each of these groups has many specific design patterns, but to focus on more than a single pattern in a blog post would be remiss.

The Coding Blocks Podcast has a series on design patterns, the first of which discusses creational patterns, which are described in the “Gang of Four” book, “Design Patterns” [1]. While the hosts find the overuse of these design patterns humorous, they admit that seeing the word “Factory” instantly describes code at a higher level. Furthermore, design patterns assist in adhering to other object-oriented design principles.

[Design Patterns] help make a system independent of how its objects are created, composed, and represented. 

– Design Patterns, Gamma, E., et al

I have come to strongly dislike nested if statements, checking if a subclass is an instance of a superclass, and switch statements. Clean Code by Robert Martin [2] has influenced that a lot, because it made me realize there’s a better way.

Imagine an app that asks the user what kind of Car they would like. This car needs to drive(), brake(), and calculateFuelCost(). Assume there are dozens of types of Car, each implementing the Car interface with these methods. The app will need a bloated switch statement to make all of these concrete classes, depending on user input.

The idea behind the Factory design pattern is that there is a separate class that creates concrete objects, but returns an abstraction (an abstract class or interface). You don’t need to scatter logic across an application that determines which type of “Car” should be created, for example. In fact, you don’t even need or want to know what kind of car it is, once it’s created. A CarFactory class returns an Abstract Car or a Car Interface. In the case of an interface, concrete classes such as ElectricCar or HybridCar implement the Car interface.

The result is an application that can create a CarFactory, tell it what kind of car the user wants, and then manipulate the returned interface as needed. And no matter the concrete object it gets back, it can be treated the same. This separates the application logic from specific implementation of concrete Car classes.

So when your application needs to add a FlyingCar option, a concrete class can be created that implements the same Car interface. The application only needs to tell the CarFactory to create a new FlyingCar object. The rest can be treated identically, because the CarFactory returns an interface with all the required methods.

As stated in the podcast episode, if this is confusing it means you’re learning. These patterns are not trivial to learn, and require many more examples and plenty of UML diagrams to fully understand the idea behind the pattern.

[1] Gamma, E., et al. Design Patterns:Elements of Reusable Object-Oriented Software. Addison-Wesley, 1995.
[2] Martin, Robert C., et al. Clean Code: a Handbook of Agile Software Craftsmanship. Prentice Hall, 2016.

From the blog CS@Worcester – Inquiries and Queries by ausausdauer and used with permission of the author. All other rights reserved by the author.

Thinkin ‘bout KISS‘n you


KISS
(Keep it Simple, Stupid) is potentially one of the most culturally pervasive concepts
used in Computer Science, the other being maybe blockchain – the difference of
course is that people actually understand what KISS is, everyone who says they
understand blockchain is lying. Of course, KISS did not originate in Computer
Science, and instead was popularized at Lockheed Skunk Works by noted
tangential war criminal and engineer Kelly Johnson. While it may be difficult and
seemingly sacrilegious to try to explain something so self-explanatory that is
what I hope to do, flying in the face of the concept of simplicity to stretch
four words into four hundred.

Credit: csiaexchange

              It begins with, put kindly, making
distinctions about the semantics of the scant few words in this phrase; put
more bluntly, being pedantic. This examination is important, and the linked
article does a great job of highlighting first the distinctions between ‘simple’
and ‘easy’, which could be mistaken as synonyms, and contrasts it with ‘complex’.
His conclusion is this, a simple system is defined by what it is not, which is one
with too many parts which are interconnected – with the latter being worse in
software development.

              This all sounds wonderful on paper,
and about the same on a computer screen, but sometimes complexity is
inevitable. So, it is advised that you make things as simple as possible, until
you can’t, at which point you are vigilant in handling that necessary
complexity. For instance, I could try all sorts of methods to navigate a 2D
array in some mock-up code, but I don’t need to introduce recursion or anything
outrageous to shorten a method body if a simple nested loop will do.

              This idea of simplifying through pruning
code is expressed in the next sections of this post, stressing the importance
of cleaning up dead or underutilized code so that no resources are wasted maintaining
or reintegrating useless code. Additionally, YAGNI (yay more acronyms) states
more or less the same thing, encouraging programmers to implement the essentials,
that will actually be presently utilized, and skip the bells, whistles, and
maybes. Code with bunches of maybe methods require time and resources to
maintain and if they aren’t actively being utilized, then they’re a waste of
both.

              From here on, the blog introduces
many more concepts that are possible to cover in just this blog post – although
I do hope to mention Lasagna Architecture in another post sometime later. Instead,
I think it is time to bring this post to a close. What is the take-away then?
Well its exactly what you thought it was from the first line. In conclusion, it
may be appealing to get a jump on features you may want to implement in the future,
but it is best to keep things as simple as possible and/or only as complex as
needed but no more.


Sources

KISS Principle Explained
KISS, A Design Principle

From the blog CS@Worcester – Press Here for Worms by wurmpress and used with permission of the author. All other rights reserved by the author.

Is That Bug Bothering You

Using Black Box Testing To Your Advantage

Blackbox testing is a strategy programmers use to test code at the level of the user. They have no access to the source code and only see what a user would see. The goal is to see that everything functions correctly from the view of the user. This type of testing doesn’t require much knowledge of the structure of the program and could be executed without any access to that information. 

Blackbox testing can be problematic because you  can’t see what part of the code is problematic when running into an error. However, if you have code that is functioning properly, perhaps blackbox testing can be quite beneficial. In a scenario where you have complicated code keep in mind the YAGNI rule (You ain’t gonna need it). Perhaps  all bugs aren’t worth testing for, if the user couldn’t trigger the bug then why go through the testing trouble. Yes it is always better to safeguard code against any error but if fixing this hidden bug would over complicate things then just let it be. Blackbox testing comes into play here, if you are not running into errors as the user then consider whether or not you need to safeguard any code level concerns. An article from qablog.practitest.com states, “When we test, the idea is not to find all the issues, we only need to focus on those issues that will affect our users.

The question of “If a tree falls on an empty forest, does it make a sound?” is simple in the context of testing…  If there is a bug that no one will run into, then we do not care about this bug!. Spending time and resources on patching spots of code that aren’t going to be disrupted by a user is a quality issue. Check out this article for more information on this idea.

https://qablog.practitest.com/you-do-not-need-to-make-the-wrong-assumptions-about-your-users-anymore/

Do not make the wrong assumptions. (2019, September 15). Retrieved from https://qablog.practitest.com/you-do-not-need-to-make-the-wrong-assumptions-about-your-users-anymore/

From the blog cs@worcester – Zac&#039;s Blog by zloureiro and used with permission of the author. All other rights reserved by the author.

Heroku, a Haiku for you

Heroku a haiku: Constant deployment Integration on the fly Heroku for you Let’s talk about the devops cycle. It’s comprised of several different layers. We’re going to focus on Continuous Integration (CI), Continuous Delivery(CD), test automation, and configuration management. More importantly we are going to focus on connecting our Gitlab repository with Heroku. We’ll do this so we can get the CI/CD environment setup for our branch of the LibreFoodBank. So what do we need to accomplish this? We’ll need our repository on Github migrated to Gitlab. This has already been done and we will be working from a specific forked branch for our testing. We’ll need our Heroku account setup. This has already been setup for us. Since we are stepping into this project at this phase we should just need to follow some basic steps to link the two. Once we have confirmation that all the steps work correctly and are repeatable we will create working documentation for other teams to utilize. Here’s the high altitude overview of how we will accomplish this: Setup Gitlab account Generate a pair of SSH keys Setup staging and production environments in Heroku Setup tests Setup the CI environment on Gitlab Install and register Gitlab Runner Configure the pipelines and fire it up Again this is the 20000 foot look at how we are going to get where we need to be and we’ll be taking notes as we go! #CS@Worcester #CS448

From the blog Home | Michael Duquette by Michael Duquette and used with permission of the author. All other rights reserved by the author.

Heroku, a Haiku for you

Heroku a haiku: Constant deployment Integration on the fly Heroku for you Let’s talk about the devops cycle. It’s comprised of several different layers. We’re going to focus on Continuous Integration (CI), Continuous Delivery(CD), test automation, and configuration management. More importantly we are going to focus on connecting our Gitlab repository with Heroku. We’ll do this so we can get the CI/CD environment setup for our branch of the LibreFoodBank. So what do we need to accomplish this? We’ll need our repository on Github migrated to Gitlab. This has already been done and we will be working from a specific forked branch for our testing. We’ll need our Heroku account setup. This has already been setup for us. Since we are stepping into this project at this phase we should just need to follow some basic steps to link the two. Once we have confirmation that all the steps work correctly and are repeatable we will create working documentation for other teams to utilize. Here’s the high altitude overview of how we will accomplish this: Setup Gitlab account Generate a pair of SSH keys Setup staging and production environments in Heroku Setup tests Setup the CI environment on Gitlab Install and register Gitlab Runner Configure the pipelines and fire it up Again this is the 20000 foot look at how we are going to get where we need to be and we’ll be taking notes as we go! #CS@Worcester #CS448

From the blog Michael Duquette by Michael Duquette and used with permission of the author. All other rights reserved by the author.