Category Archives: CS-343

Software Construction Log #2 – Learning about Containerization and Virtualization

            In my experience, the concept of virtualization is currently synonymous with the creation of virtual machines that are used to emulate hardware and operating systems that, for one reason or another, are not readily available during the process of software development. For example, during my studies I have needed to use programs that were not available on Windows operating systems or to study an operating system for which a physical unit may not be readily available. Whatever the case may be, virtualization is not a new concept, and it is widely utilized in software development. It is important to note that virtualization is not exclusive to virtual machines, as it has a broader range that includes any concept related to the abstraction of a system’s physical components into virtual components.

            Among others, one concept of virtualization is containerization, with which most of us are familiar through Docker. Conversely, containerization refers to the containment of applications, their dependencies, and their required operating system into a singular package, also called container (hence, the name) that can be deployed and used on any operating system. By design, containers are meant to be a portable and lightweight way of testing and deploying applications, at least when compared to virtual machines. However, it is important to note that singular instances of containers cannot be modified, whereas it is possible to customize and modify virtual machines. Despite the caveats or benefits of virtual machines and containers, both are equally important during development.

          As I mentioned before, I have used virtual machines during my studies to create and use servers that I had no immediate physical access to, so the concept of virtual machines is not entirely foreign to me. However, I have little experience by comparison when it comes to Docker and using containers for software development, so I believe it is important for me to understand their differences so that I can know how to properly utilize them. As I was researching more regarding the concepts of virtualization and containerization, I came across the post titled What’s the Diff: VMs vs Containers on BackBlaze.Com, in which Roderick Bauer defines what virtual machines and containers are in detail, how they are different based on their structure on a server, as well as listing their benefits and best uses. Though Bauer does not directly state their caveats, by looking at the differences of both virtualization and containerization I can better understand when either approach could be more suitable depending on the needs during development.

            Moreover, what this post also helped me understand better is that neither option is mutually exclusive; it is possible (and sometimes, even preferable) to utilize both virtualization and containerization during development, rather than being limited to either option, so long as doing so does contribute to improving development.

Direct link to the resource referenced in the post: https://www.backblaze.com/blog/vm-vs-containers/

Recommended materials/resources reviewed related to virtualization, virtual machines, and Docker/containerization:
1) https://www.oracle.com/cloud-native/container-registry/what-is-docker/
2) https://www.infoworld.com/article/3204171/what-is-docker-the-spark-for-the-container-revolution.html
3) https://www.docker.com/resources/what-container
4) https://devopscon.io/blog/docker/docker-vs-virtual-machine-where-are-the-differences/
5) https://www.airpair.com/docker/posts/8-proven-real-world-ways-to-use-docker
6) https://opensource.com/resources/virtualization
7) https://en.wikipedia.org/wiki/Virtualization (Definition of Virtualization)
8) https://www.ibm.com/cloud/learn/containerization

From the blog CS@Worcester – CompSci Log by sohoda and used with permission of the author. All other rights reserved by the author.

Junit and Temporary Files

               When working with a Java program, one of the strongest tools to ensure it is functioning is Junit testing. Junit testing makes it easy to take a glance and see if all properties of your code are functioning correctly. Despite this however, at the end of the day, the product must be able to seamlessly accept and output data in a usable form. Therefore it is important to understand how to use temporary test files when using Junit.

              Andrew Binstock’s post fits in with regards to the currently assigned homework which sees us utilizing test classes and modifying them as the code is refactored. These tests allow us to ensure that the written code is working properly. To build upon this idea the post linked below presents the idea of Junit testing with temporary files to read and write to. Within this post is sample code which creates temporary files in and out of Junit testing.

Below we can see a snippet of code from the original blog post which shows temporary files being used in a Junit test. (Andrew Binstock)

import org.junit.jupiter.api.*;
import org.junit.jupiter.api.io.TempDir;

import java.io.*;
import java.nio.file.InvalidPathException;
import java.nio.file.Path;

import static org.junit.jupiter.api.Assertions.*;

public class TempFilesJUnit5Test {

Path path1, path2;
File file1, file2;

/* This directory and the files created in it will be deleted after
* tests are run, even in the event of failures or exceptions.
*/
@TempDir
Path tempDir;

/* executed before every test: create two temporary files */
@BeforeEach
public void setUp() {
try {
path1 = tempDir.resolve( “testfile1.txt” );
path2 = tempDir.resolve( “testfile2.txt” );
}
catch( InvalidPathException ipe ) {
System.err.println(
“error creating temporary test file in ” +
this.getClass().getSimpleName() );
}

file1 = path1.toFile();
file2 = path2.toFile();
}

               Within the second homework assignment we can see that Junit tests are used to ensure that the different classes of ducks and working properly and that the data output is correct. Some of the Junit tests scan the output file and compares it against the expected output. While this is useful to ensure the code works, it is also important to consider that not everyone will want their output confined to the terminal. This program could very easily be modified to output to a text file for data collection purposes. Testing this with Junit would allow the creator to ensure that data is being retained properly before running the program in a real case scenario.

Testing with temporary files was previously an underutilized method of testing due to older hardware being much slower and older drives using spinning magnetic disks rather than modern solid state storage. In the post we see the author discuss this dated policy and encourage the use of test files to create a more thorough testing method. Some might want their output in a text file or as an output to a front end for a website. Junit tests with temporary file allow you to test for this functionality as these temporary files can be created, read from, written to, and are all deleted at the end of testing to keep drive space free from clutter.

Bibliography:

Binstock, A. (n.d.). Working and unit testing with temporary files in Java. Blogs.oracle.com. Retrieved October 11, 2021, from https://blogs.oracle.com/javamagazine/post/working-and-unit-testing-with-temporary-files-in-java.

Working and unit testing with temporary files in Java (oracle.com)

From the blog CS@Worcester – George Chyoghly CS-343 by gchyoghly and used with permission of the author. All other rights reserved by the author.

Factory Method vs Abstract Factory

For this week’s assignment, exercise #2, I had an opportunity to refactor a poor design of Duck Simulator using the factory pattern. It was nice that I could approach this design pattern step by step and learned its definition by understanding why I had to create an abstract method or why I had to create a factory class. Moreover, after skimming through a long chapter, Chapter 4. Baking with OO Goodness: The Factory Pattern, although there are many important definitions in this chapter, I believe that there are two concepts that I shouldn’t miss, the factory method and the abstract factory. Both are new tools that I need to know what they are and how to apply them to a design.

Furthermore, for better understanding, I also wondered what was the difference between factory method and abstract factory. Although, the textbook has a comparison between those two concepts, but for myself, it was long and difficult to follow till the end. So, I did a few searches to see if there were any good resources that I could take a quick look at for my question. I found a good blog, called Factory Method vs Abstract Factory. In this blog, the writer makes some comparisons to show the difference between factory method and abstract factory. Through the blog and the textbook, I know that both concepts are used to encapsulate object creation, and they apply the dependency inversion principle by allowing coders to decouple code from concrete classes . On the other hand, the two concepts differ in many ways. First, the number of products produced is different. The factory method is used to create only one product while the abstract factory is used to create families of related products. Second, for the factory method, the object creation is decided by subclasses (depending on inheritance), whereas the abstract factory has a separate class to creates a family of products, then its object can be passed to client class for using (object composition). Next, it is the level of abstraction. Since the abstract factory are at higher level in abstraction, we can use factory methods to create products in factories.

For myself, this is a resource worth referring to because its concise, well-organized content helps readers easily distinguish the difference between the two concepts. Thanks to this resource, I got a better understanding of the factory pattern, especially the abstract factory and factory method, which is really helpful for my diagram design latter.

From the blog CS@Worcester – T's CSblog by tyahhhh and used with permission of the author. All other rights reserved by the author.

From Warcraft III to My PC: My Inevitable Pairing with Polymorphism

The year was 2005. I was a young child in elementary school, and eventually I was exposed to a little-known strategy game known as Warcraft III. As I championed the human race in my epic quest against the Undead Scourge of Lordaeron, I came across a sorceress ability known as “Polymorphism”. This powerful spell allowed its caster to turn an individual target into a harmless sheep. While entertaining and useful to say the least, little did I know that Polymorphism itself would take on a new form in the years to come…

Fast forward to 2021. I am being exposed once again to Polymorphism, this time as an essential feature of Object-Oriented programming. This would mark the third time that I am working with this concept (the other times being 2016-2017, and 2019 respectively). Polymorphism, in theory, isn’t very difficult: we take one idea (such as a function/method), and give it “many forms” (hence the name) among its various classes that use the function/method.

Listed below is an article about polymorphism from GeeksForGeeks, one of my “personal go-tos” when it comes to learning about programming practices. Specifically, “runtime polymorphism” will be more applicable in my software design class, due to its usage of method overriding. When using the “Strategy Design” of refactoring, we will create various interfaces and have them implemented using respective classes; these classes will then create their own version of the method.

Strategy design refactoring seems to provide an edge over “simple inheritance”, which would involve having a single base class (that all subclasses inherit off of). This “edge” is the removal of inherited methods that serve no purpose in certain subclasses; when the interface is implemented by the class, we can choose exactly what we want and don’t want from polymorphism.

However, having too many interfaces, or not enough data within the interface can cause its own problems. In addition, an interface is just that: a “top-down” view, with nothing beneath it; the methods need to be designed by the class using it. Meanwhile, inheritance may have redundant data, but at least you get all that and a bag of chips. In other words, inheritance provides one portion of functioning methods, plus whatever else is added on in the subclass.

I hope that I can use the idea of polymorphism, alongside interfaces, to reduce the amount of redundancy and complexity in my programs. There is no need to turn a program into a headache with unnecessary amounts of inheritance. In addition, part of this unnecessary material could be redundant – brought along for the ride, but not used during run-time.

Link: https://www.geeksforgeeks.org/polymorphism-in-java/

From the blog CS@Worcester – mpekim.code by Mike Morley (mpekim) and used with permission of the author. All other rights reserved by the author.

Just Another Scripting Saying

Ever since the beginning of my programming career, I have had a plethora of professors provide several sayings that were helpful to becoming a better software engineer. One particular saying was acquired only a few weeks ago, during my Software Construction course. The saying goes: “YAGNI”, or when extended beyond the acronym: “(Y)ou (A)in’t (G)onna (N)eed (I)t”.

YAGNI is a useful term when considering one particular coding smell: Needless Complexity. Novice programmers often believe that they need to somehow squish every keyword, conditional statement and data structure into one massive, impressively diverse program. Yes, it is definitely useful to be knowledgeable in all of these areas. However, an advanced understanding of programming requires that one not only knows the skills, but also when to use them.

The article listed below (created by legendary software engineer Martin Fowler) explains the various reasons why YAGNI is so important. Specifically, it explains different kinds of “costs” related with unnecessary complexity: Costs of building, repairing, delaying and carrying the software. Considering these costs is such a crucial factor due to the fact that software should be designed to be cheap for the producer, yet effective and “easy-to-use” for the customer.

Understanding YAGNI, and its effectiveness against needless complexity, is invaluable to achieving proficiency in software design. The class does not want us to build products “per se”; rather, it already expects that we can build the block from the get-go. Instead, this class focuses on “whittling away” at the back-end block to create something more beautiful and beneficial.

If anything, based on the material that Martin Fowler has presented to us, we need to take a look at our code and ask ourselves: “is this really necessary?” Do we really need this exception case if the chances of achieving the error make the lottery look like a safe bet? Are these security features needed when a simple password check can cut the mustard? Cutting down on needless complexity is a rather easy smell to work on, since the problem is based on our ability to work harder than we really need to. Instead of remembering every last line of code, we should remember the abstract ideas, and learn how to translate/implement them.

In conclusion, I believe that “YAGNI” is an essential saying that every programmer should know by heart. In addition, I strongly believe that the sooner a junior programmer can learn this rule, the better off they’ll be in the world of software design. The best way to avoid certain coding smells (such as viscosity) and technical debt is to instill proficient programming practices that avoid these problems to begin with.

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

From the blog CS@Worcester – mpekim.code by Mike Morley (mpekim) and used with permission of the author. All other rights reserved by the author.

Singleton/Factory

Last week reading took us through one design pattern the singleton pattern and a quasi-design pattern the simple factory technique. I was very impressed by both and took some time to analyze their delivery method –how they presented their arguments. On singleton the author presented the design as a conversation in an almost Zen tone. I was attracted to his way of explaining because I believe that a lot of times when studying we let the stress get the better of us and miss many important points. The step by step really show not just how but why. A lot of times we write a lot of code because we know how but not always know why we write it a certain way, which I believe makes the knowledge untransferable –although why is not always important.

The relaxed Zen mode of explaining is also something I appreciate because I am a strong believer that sometimes, some things should be explained like you would explain a 5-year-old, and I have no shame in listening like a 5-year-old. It is easy to have many years of experience on something and forget some of the things taken for granted are very important to the beginner(me). The Zen approach also reminds me of Buddhist monks drawing complex sand diagrams only to erased them and start over again. It is hard to erase bad habits and acquiring good ones, but by creating the habit of erasing habits the learning cycle can be increased considerably. That’s all I must really say on how the authors carried their message, but the interesting thing was the message itself.

The singleton pattern at first was not impressive if anything I always had a bad view of private or protected variables or methods. I never really understood the need to hide things in code maybe because I never really had to write code of considerable size. Once I started working with the pattern it was like a little light bulb flickered on top of my head and I suddenly started seeing the coolness of obfuscation in this case just preventing object overcrowding. I really thought it was pretty cool and I think that in the way the idea was explained the structure will be in my head for quite some time, and I am a very forgetful person.

The simple factory technique was also well explained in just the right number of words. It was very clear that by consolidating actions or delegating the creation of objects helped to minimize how much one class was doing. Uncle bob always say doing too many things is bad, so I think this applies in this case. I was afraid at first that to implement this was to substitute the singleton pattern that I’ve gotten so fond of, but that was not the case. After implementing it I saw that there were other areas that could be greatly improved by consolidating further. My only fear is to know when to stop –how much is too much consolidation.

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

Why Encapsulation Matters

Summary:

In this article, they don’t show us examples of encapsulation but instead explain to us the importance of it and why we do it as software engineers. Initially, they start off with how encapsulation helps us hide the complexity of our code. The beauty of hiding our code is not having to understand all the details in order to be able to use it, we just need to understand a broader abstract concept and how it works and how we interact with it. They also explain to us what happens when are not able to achieve the proper levels of encapsulation in our design. That article continues as to why we need accessor and mutator methods in Java.

Reason:

The reason why I chose this article was because in class we have done a lot coding in regards to encapsulation and I thought that this would help me fully grasp the purpose and meaning of encapsulation. Encapsulation is the very essence of API’s and how they work and being able to understand this is very important since we may be creating API’s in the future.

What I’ve Learned:

Encapsulation is more than just defining accessor and mutator methods for a class. It is a broader concept of programming, not necessarily object-oriented programming, that consists in minimizing the interdependence between modules and it’s typically implemented through information hiding. Our software designs the visible parts of our modules/classes constitute their public interface, and this is exposed to the outside world, the rest of it should be hidden to the naked eye. With encapsulation us as humans deal with complexity by defining abstractions with public interfaces so that we are able to interact with them and all of the code that lies beneath it is unnecessary in order for use it. It is like an iceberg, only a small portion of it is visible on the surface, but most of its true size is hidden underwater where we cannot see it. Changes can we made in directional systems because internal implementation is encapsulated and because of that, changes can we safely done without affecting it’ public interface. By minimizing the impact of changes and independence of modules, we can achieve proper levels of encapsulation in our software that can handle change without breaking its users. Information hiding is important because it decouples modules that compromise a system and it allows for them to be tested, optimized, used, understood, and modified in isolation. This allows for other modules to be developed in parallel and eases the burden of maintenance without the fear of affecting other modules. Encapsulation is a desirable attribute that allows for the evolution of APIs and as long as we respect public interfaces of our abstractions, we are free to change whatever has been encapsulated. Failing to define proper abstraction with proper levels of encapsulation will end up causing difficulties when change happens. There is no way to change the public interface of an abstraction without breaking its users. Encapsulation is one of the tools we use that help us create good abstractions, but no level of encapsulation is going to make bad abstraction work.

Source: https://dzone.com/articles/why-encapsulation-matters

From the blog CS@Worcester – Life as a CS Student by Dylan Nguyen and used with permission of the author. All other rights reserved by the author.

CS-343 Post #1

After the past few activities in class I was trying to think of what I wanted to look for to do my first blog post on. The one topic that caught my attention and I wanted to look more into was Design Patterns from activity 4. The strategy design pattern that we used in model 8 to improve the DuckSimulator seemed very effective to me, and I wanted to look more into design patterns after reading a bit about them in models 8 and 9. I found a blog post that goes over the strategy design pattern and when reading it, it went more in depth with the pattern than I thought it would based on the title of the post, “Keeping it Simple with the Strategy Design Pattern”, from Bits and Pieces.

The post briefly goes over Object Oriented Programming, then it focuses on the different aspects of the strategy design pattern. The parts of the pattern that the post goes over are its basic idea, structure, examples, authentication strategy, the problems it solves, SOLID principles, how it’s used in JavaScript, and when to use it.

Some of the material was familiar to me from previous courses that I didn’t think would show up, but it made sense that it did, such as the sorting algorithms, such as bubble sort and linear search, being used for the strategies being represented based on the data and objects in the program. Diagrams used for the pattern also were very similar to the ones used in the activity to show the structure of the pattern with the implementation of context, interface, strategy, and concrete strategy.

What was less familiar to me where the authentication schemes and strategies, such as basic and digest, that are brought up later on in the post. I did not know the specific schemes brought up, but I got the idea behind their usage for authenticating data in the program. The schemes were also used in examples for the strategy design pattern by showing an interface being used to have an authentication method that is implemented by the schemes.

The main problem resolved by the pattern is the hardcoding of the program, which can make in run less smooth and more complex/complicated than it needs to be. Using a pattern prevents this by breaking down the program into different tasks and classes that keeps the algorithms more understandable and usable. This is reflected in another example with a given Printer class with multiple classes, but is also shown in the final DuckSimulator version.

In conclusion, the strategy design pattern is effective at improving complex programs, keeping the classes manageable, and keeping the methods and algorithms separated from each other.

Link: https://blog.bitsrc.io/keep-it-simple-with-the-strategy-design-pattern-c36a14c985e9

From the blog Jeffery Neal's Blog by jneal44 and used with permission of the author. All other rights reserved by the author.

          YAGNI

YAGNI has two different meanings: You Ain’t Gonna Need It or in other words, You Aren’t Gonna Need It. YAGNI has appeared differently as the main principle that has been used in the extreme program. This principle stated in a different interpretation is:

“Always implement things when you really need them, never when you just anticipate that you might need them.”

The reasons why this principle exists are various. As a start, it makes it possible to maximize the amount of unnecessary work that remains unfinished. This is a very good way to improve the productivity of the developer, but also the simplicity of the product. One thing to keep in mind, these features are very expensive, both for development and maintenance. It is also important for users, so that they have the opportunity to learn, but also to navigate around. But those features seemingly are not necessary, in fact, they are a very large source of waste.

 Yagni Advantages

Here are some reasons why YAGNI should be used:

-Save time in the same amount of money (saving time and money is equal), and this is the main factor but also the most important

-gives you the opportunity to use a much easier code, good but most importantly “thoughtless”

-makes available the deadlines

-ensures that the client is happy with the very frequent but also obvious changes that are in line with the specifications

-code has better quality, notice this from the fact that many developers focus on just one even smaller task they may be doing (tasks which are more important at the moment)

last but not least, that code has the property to be more extensible.

Yagni design principle

We will not need this program much. Extreme Programming (XP) says that a programmer should not add the functionality he has until it is considered necessary. So YAGNI translates differently – You will not need it. Extreme software is generally used in the Agile software development process. According to this principle, we should not add any functionality until the moment when it is deemed necessary, in other words, to write the code which we need in the current situation.

YAGNI in Agile/XP

Many people may remember that this principle is called “stupid” and that the requirements it has should be prepared even better. But those people who work in the slightly more advanced methodology or, as they say, “agile” should take into account the possible changes that the client’s requirements may have. For this reason, the subsequent tasks in most cases depend on the results of the current status of this project, but that over time this result may change.

If at the same time we develop many features that “maybe needed” as a start, we lose not only the time but also the effort that has been needed to complete it. There are also cases when we waste the time we spend refactoring or fixing them as these interventions may be redundant.

In general, developers should never rely on different assumptions because they are likely to prove that they are not worthy and capable of the effort and time a programmer needs.

Refereces:

https://www.plutora.com/blog/you-aint-gonna-need-it-yagni

https://jasonmccreary.me/articles/practicing-yagni/

From the blog CS@worcester – Xhulja's Blogs by xmurati and used with permission of the author. All other rights reserved by the author.

Improve Your Code with Design Patterns

This week, I wanted to learn more about the design patterns we discussed in class. After completing the homework, I saw how each of the design patterns we had used could be stacked on top of each other to make more efficient programs and find solutions to common programming problems. So naturally, I decided to seek out a comprehensive list of the Gang of Four design patterns to learn more about them. While looking into this, I found a blog post by Madhura Oak entitled Design Patterns – Revisiting Gang of Four that seemed to fit the bill.

In this post, Oak explains how the “Gang of Four” came up with a list of design patterns that solve common issues within programming, and laid out these patterns so they could be used in any language, and could help software designers write maintainable and easily readable code. In this, he explains the SOLID principles by Robert Martin, and uses these 5 design principles to help explain the usefulness of each pattern. The author also breaks down the 23 Gang of Four design patterns into categories depending on how they are used and gives examples of their use, which helps put into context why we would use these patterns in the first place.

After reading about all 23 of the design patterns, and having used both the singleton and factory patterns in the homework, I feel like I have a far deeper understanding of how these patterns can be used to create more efficient and readable code. They provide a framework for so many different types of abstraction, showing ways to structure your class hierarchies to improve your ability to modify, extend, and test code without having to slog through massive classes that are full of specific use-case scenarios. Using encapsulation and inheritance in the way they are used in these design patterns, code can become so much easier to document, test, and build upon. It becomes so much cleaner and more readable.

So far in class, we have only looked at what Oak classified as “creational” design patterns, as they mainly have to do with the creation and encapsulation of objects. However both “behavioral” and “structural” design patterns are also listed here, to help bring the same principles to the structure and behavior of the programs. Mixing these together within the full structure of a project would provide great benefit to the maintainability of code in the future, one of the most important parts of software design.

Overall, this blog post was a good introduction to design patterns and the principles that they help to achieve. In the future, I hope to use these patterns to help design code that is far more abstracted, and hopefully far easier to follow than code I’ve written in the past. I really like how easily followed the patterns are, and the way the post is organized makes it easy to find what you are looking for. If you are interested in further reading about more design patterns, I would highly recommend looking through this post, at least for a general outline of what they do and how they work.


Source:

https://madhuraoakblog.wordpress.com/2017/03/01/design-patterns-revisiting-gang-of-four/

From the blog CS@Worcester – Kurt Maiser's Coding Blog by kmaiser and used with permission of the author. All other rights reserved by the author.