Author Archives: gizmo10203

Apprenticeship Patterns

The first chapter of Apprenticeship Patterns: Guidance for the Aspiring Software Craftsman by Dave Hoover and Adewale Oshineye made me think differently about what it means to be a software developer. Instead of just being a job, the authors describe it as a craft that requires continuous learning and improvement. I liked how they compared software development to traditional craftsmanship, where a person gets better over time through practice and experience. This made me realize that becoming a great developer isn’t just about getting a job, it’s about always growing and learning.

One of the ideas that stood out to me was the importance of having a growth mindset. The authors encourage developers to recognize their weaknesses and work on them instead of ignoring or hiding them. This made me think about times times when I felt uncomfortable admitting that I didn’t know something. I sometimes hesitate to ask for help because I don’t want to seem inexperienced, but this chapter made me realize that learning from mistakes and seeking knowledge is the only way to improve.

I also liked the idea of patterns, useful strategies that help developers overcome challenges in their careers. While the chapter doesn’t go into details about specific patterns yet, I think this concept is helpful. Instead of struggling alone, developers can follow advice from others who have already faced similar challenges. I usually try to solve problems on my own, but this reading made me realize that asking for guidance from more experienced developers could help me grow faster.

However, one thing I questioned was the idea that every developer should think of their work as a craft. While I agree that learning and improving are important, not everyone may want to dedicate their career to mastery. Some people may prefer to focus on specific tasks without aiming to be the best in their field. The book assumes that all developers should take the path of craftsmanship, but I think it depends on personal goals.

Overall, this chapter made me reflect on my learning process and how I approach my career. It reminded me to stay curious, be open to feedback, and actively work on my skills. It also encouraged me to look for mentors and learn from others instead of always figuring things out on my own. Moving forward, I want to take a more active approach to improving my skills rather than just learning through experience.

Link: https://www.oreilly.com/library/view/apprenticeship-patterns/9780596806842/ch01.html?_gl=1*15ilzcb*_ga*MTY4NzMxMDczMC4xNzM5MjQyNTI0*_ga_092EL089CH*MTczOTI0MjUyNC4xLjEuMTczOTI0MjgyOC4yOS4wLjA.#introduction

From the blog CS@Worcester – One pixel at a time by gizmo10203 and used with permission of the author. All other rights reserved by the author.

LibreFoodPantry and Thea’s Pantry

During this semester I’m taking my capstone in which we are working on a project for Thea’s Pantry. Before starting this project however, we had to take a look at what we would be doing a project on. This blog post is about some of the things that I found interesting and useful about the two pantries mentioned in the title.

The first thing I’m going to talk about is LibreFoodPantry. LibreFoodPantry is a community building free and open source software for food pantries. The website for this community contains six main sections that I read. These include their mission, values (such as Agile principles), code of conduct, licensing, acknowledgements, and coordinating committee. The section I found to be most interesting was the mission. They state “Our mission is to expand a community of students and faculty across multiple institutions who believe software can be used to help society. We strive to support local food pantries with quality, adaptable, free and open source software (FOSS) to help them serve their guests. Through learning opportunities within FOSS food pantry projects, we provide students with the perspective that computing can be used for social good.” I chose to talk about this because I think its really kind that an entire community has been developed and continues to work on projects for social good and to help others.

The second thing I’m going to talk about is Thea’s Pantry. Thea’s Pantry is Worcester State’s own personal food pantry. Within the README file of the Documentation repository, there are five main sections. These sections are User Stories, Architecture, Technology, Workflow, and Release Process. The section that I found to be most useful is the Architecture section. I found this section to be most useful because it describes the ReportingSystem and what the different subsections use for components and queues. On top of that, it shows the diagram for the ReportingSystem Standalone Integration Test which I think is helpful for anyone who wants to understand the architecture.

Overall, I’m really excited to start working on a project with Thea’s Pantry and I hope that I’m able to help make a difference.

From the blog CS@Worcester – One pixel at a time by gizmo10203 and used with permission of the author. All other rights reserved by the author.

Design Patterns – Creational, Structural, and Behavioral

Design patterns are extremely useful within software design. Essentially they are like established solutions to common problems within various contexts. We have learned a lot about design patterns this semester, especially creational, structural, and behavioral. Since we have talked about them and worked with them a lot, I thought it would be a good idea to write a post about what each is. A blog I found while researching more into the topic is called “Intro to Design Patterns” by Saverio Mazza. I think this blog does a great job at giving a brief overview of each of the three different design patterns and how they work. They are extremely helpful for anyone working in software design, and I feel like they will be used in any career I choose. I’m very grateful that I was able to learn more about these design patterns, and I hope my blog post will help you learn more too.

Creational Patterns: As it mentions in the name, creational patterns have to do with the way that objects are created. According to Mazza “They aim to abstract the instantiation process, making a system independent of how its objects are created, composed, and represented. Some examples of creational patterns include the singleton pattern, the factory method pattern, the abstract factory pattern, the builder pattern, and the prototype pattern.

Structural Patterns: These types of patterns deal with how classes and objects are composed in order to form larger structures. They make sure that when one part of a system changes, the rest of it doesn’t need to. Similarly, they make sure that parts of the system are decoupled and can improve the system’s flexibility and reusability. Some examples of structural patterns include the adapter pattern, the composite pattern, the proxy pattern, the flyweight pattern, the bridge pattern, and the decorator pattern.

Behavioral Patterns: Behavioral patterns deal with algorithms and the assignment of responsibilities between objects. They describe the patterns of communication between objects and classes as well as the patterns between them. They let you concentrate just on the way that the objects are interconnected. Some examples of behavioral patterns are the observer pattern, the strategy pattern, the command pattern, the state pattern, the visitor pattern, the mediator pattern, the memento pattern, and the template method pattern.

If you want to learn more about the specific patterns mentioned, I highly recommend checking out the linked blog for more information!

Link: https://medium.com/@saverio3107/intro-to-design-patterns-66f1aebe5be5

From the blog CS@Worcester – One pixel at a time by gizmo10203 and used with permission of the author. All other rights reserved by the author.

Object Oriented Programming – Abstraction, Encapsulation, Polymorphism, and Inheritance

Within object oriented programming, there are four main pillars. These are known as abstraction, encapsulation, polymorphism, and inheritance. These four are essential in understanding object oriented programming and why it is important. While researching, I found a blog called “Encapsulation, Abstraction, Inheritance, and Polymorphism” by Cole Davis which I believe does a great job at explaining all four of the pillars as well as why they are important. I chose to write about this topic as I use object oriented programming all the time, and I plan to do it in the future. Because of this, I wanted to help share some information that I find to be very useful in understanding how it works in case anyone else wants to do the same.

Abstraction: One of the first major pillars you’ll learn about is known as abstraction. Cole Davis does a great job at explaining this pillar, as shown in a quote from his blog: “Abstraction is the process of combining many functions into one. Think of a thermostat. Typically, a thermostat allows the user to change the target temperature, select different modes such as heating, cooling, or fan, and turn the unit on or off. When we use a thermostat, we are unaware of the intricacies that create these functionalities under the hood. By exposing only the necessary abstracted functions to the user, we make it easier for the user to use our programs.” I really enjoyed reading this example as it relates abstraction to real-life terms instead of just using coding terms, making it a lot easier to understand. Essentially, abstraction does the same thing. It makes our code easier to understand, allowing others to get a high-level understanding of our program.

Encapsulation: The second main pillar is known as encapsulation. Encapsulation is the idea of hiding and restricting access to the implementation details of our objects. Basically, this protects the data and functions of our code from being improperly accessed by things other than our objects. It makes our code more robust and predictable, allowing others to see its purpose more clearly. Another major benefit of encapsulation is it allows us to see precisely where we can change implementation details, allowing us to safely change our program.

Inheritance: The third main pillar is known as inheritance. According to the blog “Inheritance is a technique that involves a child class “inheriting” functionality from a parent or super class.” This increases usability in our code as well as stops it from being redundant.

Polymorphism: The four main pillar is known as polymorphism. Polymorphism is a hard one to explain, but its very easy to show. Essentially, it is when child classes run the same inherited method that returns different values. They use the same method, but can return different values based on what they do. Polymorphism allows us to have a more dynamic inheritance, which enables us to use inheritance more for its values that it provides.

Link: https://medium.com/@colebuildanddevelop/encapsulation-abstraction-inheritance-and-polymorphism-26aa98042d41

From the blog CS@Worcester – One pixel at a time by gizmo10203 and used with permission of the author. All other rights reserved by the author.

GRASP

Similar to SOLID, GRASP is an acronym for a set of design principles used in object-oriented programming to clearly define responsibilities within a software system. GRASP stands for General Responsibility Assignment Software Patterns, and focuses on 9 different patterns or principles. A blog on kamilgrzybek.com called “Grasp – General Responsibility Assignment Software Patterns Explained” does a really good job at explaining all nine of the different patterns, as well as gives helpful examples of each. According to the article, “GRASP is a set of exactly 9 General Responsibility Assignment Software Patterns. As I wrote above assignment of object responsibilities is one of the key skill of OOD. Every programmer and designer should be familiar with these patterns and what is more important – know how to apply them in every day work (by the way – the same assumptions should apply to SOLID principles.” This quote shows that the GRASP principles are just as important to know as the SOLID principles. I think that everyone should learn the GRASP principles alongside the SOLID principles, and I plan on trying to use them in the future.

The nine principles consist of the following:

Controller
Creator
High Cohesion
Indirection
Information Expert
Low Coupling
Polymorphism
Protected Variations
Pure Fabrication

Controller tends to represent the device that the software is running within, such as the overall system. It also represents a use case scenario within the system operation occurs. Controller depends on high level design of the system being used, but generally we need to define the object which orchestrates the business transaction before it is processed.

Creator is a hard principle to explain. I think the example that the article gave is helpful. “Problem: Who creates object A? Solution: Assign class B the responsibility to create object A if one of these is true (more is better): B contains or compositely aggregates A, B records A, B closely uses A, B has the initializing data for A.”

High cohesion is how well the elements in a class work together. If a class has low cohesion, then it has a lot of unrelated data or behaviors inside of it. Classes with high cohesion, meaning it has data and behaviors that are all related to each other, are a lot more efficient.

Indirection avoids direct coupling between two or more things and allows an intermediate object to mediate other components.

Information expert assigns a class the responsibility of holding all of the information needed to fulfill the object and its needs.

Low coupling is when objects are more independent and isolated, rather than being completely dependent on other parts of the system. This helps reduce the risk of breaking the system.

Polymorphism is an essential principle of OOD. It allows different types of objects to be treated as a single type.

Protected variations identify points of predicted instability and assign responsibilities in order to create a stable interface around them.

Pure fabrication assigns a highly cohesive set of responsibilities to an artificial class that doesn’t represent a problem domain concept when you don’t want to violate high cohesion and low coupling.

Link: https://www.kamilgrzybek.com/blog/posts/grasp-explained

From the blog CS@Worcester – One pixel at a time by gizmo10203 and used with permission of the author. All other rights reserved by the author.

SOLID

SOLID is an acronym for a set of design principles for object-oriented programming that is used to help developers create flexible, efficient, and easily maintainable software. I think the article “SOLID: The First 5 Principles of Object Oriented Design” by Samuel Oloruntoba and Anish Singh Walia does a great job explaining the SOLID principles. I plan on using these principles in the future to further develop my code and to make sure it is easy to read and understand.

Here is what each of the letters in SOLID stand for:

S: Single Responsibility Principle (SRP)
O: Open-Closed Principle (OCP)
L: Liskov Substitution Principle (LSP)
I: Interface Segregation Principle (ISP)
D: Dependency Inversion Principle (DIP)

SRP states “A class should have one and only one reason to change, meaning that a class should have only one job.” Essentially this means that any object or class should be made for one specific function in order to better understand the code.

OCP states “Objects or entities should be open for extension but closed for modification.” The article states that “This means that a class should be extendable without modifying the class itself.” I think this article does a great job explaining what all of the different principles mean as well as giving examples for each of them. I strongly recommend using this website if you’re trying to learn about SOLID.

LSP states “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.” At first, this really confused me. After doing some research and coming across this website, I began to understand this principle more. In simpler terms, it means that every subclass should be a substitute for their parent class. If you need examples to see how this would work, I highly recommend looking at the linked article.

ISP states “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 states that software should be broken down into smaller, more specific parts. This is so it doesn’t depend on code it doesn’t use.

DIP states “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.” In simple terms, both high-level and low-level modules should depend on abstractions, and abstractions should not depend on details.

Link to article: https://www.digitalocean.com/community/conceptual-articles/s-o-l-i-d-the-first-five-principles-of-object-oriented-design#dependency-inversion-principle

From the blog CS@Worcester – One pixel at a time by gizmo10203 and used with permission of the author. All other rights reserved by the author.

CS-343

As I’m starting my final year here at WSU, I only have a few classes left to take until I officially have my bachelor’s degree! One of the few remaining classes is CS-343, otherwise known as Software Construction, Design, and Architecture. This class is going to be similar to my last class, but it is going to go more in depth with design principles, frameworks, modeling, etc. I hope this class is as fun as the other ones have been!

From the blog CS@Worcester – One pixel at a time by gizmo10203 and used with permission of the author. All other rights reserved by the author.

Combinatorial Testing

One of the last types of testing techniques that we learned about this semester is known is Combinatorial Testing. Combinatorial testing is a testing technique that is used for software applications with a lot of different input possibilities and a high complexity. Even if you create a large number of different test cases, you will most likely still miss a test scenario. I’m not the best at explaining what something is, so I did some research in order to find an article that helps describe the aspects of combinatorial testing as well as how to use it and what its benefits are. This website is called testsigma.com

I think that this website does a great job at explaining what combinatorial testing is as well as all of its different benefits. In the article by Shanika Wickramasinghe, it states “Combinatorial testing is a testing method that uses multiple combinations of input parameters to perform testing for a software application. The main goal of combinatorial testing is to make sure that the software product can handle different combinations of test data as input parameters and configuration options.” This means that combinatorial testing takes a bunch of different input parameters, similar to pairwise testing, and uses it to test a bunch of different cases for the program. This can be extremely useful because some of the errors with a program can only be found with specific inputs. I’ve actually had this happen to me before in one of my classes. I wrote a program and testing a bunch of different inputs and they all worked, but when my teacher tried an input I never used, it failed. I think combinational testing is going to be extremely useful for me in the future. I know it seems like combinatorial testing can only be used in certain scenarios so it might be better to not learn it, but it actually has a lot of benefits according to Wickramasinghe:

  • Covers a broad range of input combinations using a minimum number of test cases.
  • Increases test coverage compared to normal component testing since it always considers multiple input combinations.
  • Helps to detect bugs, defects, vulnerabilities, and unexpected outputs that might not be detected during the usual component and regression testing phases.
  • Reduces testing effort, cost, and time. (Since combinatorial tests use fewer test cases to cover a wide scope of testing.)
  • Identifies issues at the earliest while allowing the team to address and fix those earlier in the software development life cycle.
  • Optimizes the testing process by removing unwanted test cases while ensuring that the cost and effort are not wasted on repeating the same test scenarios again and again.
  • Helps to test complex software applications with a large number of parameters, settings, and options.
  • Reduces the risk of critical defects going unnoticed, which can occur only when handling specific input combinations.

I recommend that everyone tries to use combinatorial testing at least once so they know how it works in case they ever need to use it again in the future to make sure all of their different input possibilities work.

Link: https://testsigma.com/blog/combinatorial-testing/

From the blog CS@Worcester – One pixel at a time by gizmo10203 and used with permission of the author. All other rights reserved by the author.

Stochastic and Property Based Testing

During this semester we have learned about many different testing techniques, some being a lot easier than others. One of the testing techniques that we have learned is called Stochastic Testing. Stochastic testing is a type of black box testing method in which random tests are conducted over time. These tests are performed by automated testing tools in order to see if the software can pass a large number of individual tests.

Another type of testing technique that we have talked about is Property-based Testing. Property-based Testing is very similar to Stochastic testing. In this testing technique, the testing is also automated. However, it isn’t just executing the tests that is automated, it is also generating the tests. While researching the topic, I came across an article called “What is Property-based Testing?” by Alex Robert. In this article, Robert states “Property-based testing automates that work for us. Test automation allows us to generate better tests with less work and less code, so that we can focus our effort on the less mechanical work developers excel at. Instead of writing tests with manually created examples, a property-based test defines the types of inputs it needs. In the example above with CommonPrefix, the input would be two strings. The property-based test framework will generate hundreds if not thousands of examples and feed them to your test function.” He talks about how property-based testing can create a ton of different examples for your test function in order to help you test your program.

In this article, Robert also talks about input generators and what they do. A generator is a function that returns an instance of a given type from a source of randomness. These generators are great for randomly creating new inputs for the test function. However, they are only efficient if the generators have a good framework in order to help uncover more issues with the code. Robert gives a list of qualities that he thinks would make a good generator. His qualities include: a generator should be fast, a generator should be deterministic, a generator should not waste randomness, and a generator should cover the code under test. Most of these property-based testing frameworks come with a built-in generator which can be extremely helpful for testers, depending on the type input parameter. I really enjoyed reading this article as looking at all of the examples given by Robert helped my understanding of the topic. I know that if I ever need to use this type of testing technique, I will definitely use this article as a reference.

Link: https://www.mayhem.security/blog/what-is-property-based-testing

From the blog CS@Worcester – One pixel at a time by gizmo10203 and used with permission of the author. All other rights reserved by the author.

Pairwise Testing

Another important topic that we have discussed in CS-443, or Software Quality Assurance and Testing, is known as Pairwise Testing. Pairwise Testing is yet another form of testing, but this type is a little bit different than the rest. Pairwise Testing, sometimes known as all-pairs testing, tests each pair of input parameters in order to make sure that the functions in the system run correctly no matter what the input is, guaranteeing that it will run for every combination. Pairwise Testing is known as a Permutations and Combinations (P&C) based software testing technique. A blog that I found to be really helpful in explaining Pairwise Testing is known as Pairwise Testing | What It Is, When & How to Perform by Kiruthika D. In the blog, she gives an example that helped me understand more. She states “Let’s say you have an application that allows users to enter two numbers, and the application will output the sum of the two numbers. You can use pairwise testing to test all possible combinations of two numbers, such as (1, 2), (2, 3), (3, 4), (4, 5), etc. By testing all the combinations of two numbers, you can be sure that the application is working correctly and will not fail when given different numbers.” This shows that you don’t actually test every single combination, but you test every single input with another input. This way, it makes sure that all of the inputs work instead of testing a potentially infinite amount of combinations.

The actual purpose/use of Pairwise Testing is exactly what I previously stated. It is used to make sure that all combinations of inputs are possible, but you don’t need to test every single combination. It can be extremely helpful as it reduces the amount of time it takes to test the program as well as the amount of effort. While Pairwise testing is a great testing technique, you obviously can’t use it all the time as it involves pairs. As for when to use it, Kiruthika states “Pairwise testing is helpful when testing complex systems that have multiple input parameters and multiple possible values for each parameter. It can significantly reduce the number of test cases that need to be created while ensuring that all possible discrete combinations of parameters are tested. This can help reduce test case creation time and cost and improve the software’s overall quality. Pairwise testing is not appropriate for all types of software testing. As we discussed, it is most effective for systems with multiple parameters and multiple possible values for each parameter. If a system has only a few parameters and a small number of possible values for each parameter, pairwise testing may be unnecessary. Pairwise testing, also, will not be useful if the values of inputs are inappropriate.” Essentially she is saying that Pairwise testing is used for functions that have multiple parameters with multiple values, and the order of parameters doesn’t matter. On top of that, depending on the type of parameter, the technique might not work either. While I personally don’t see myself using this technique in the future, I think that it has the opportunity to be very useful in certain situations, so I’m glad that I was able to understand it more in case I ever need to use it.

Link: https://testsigma.com/blog/pairwise-testing

From the blog CS@Worcester – One pixel at a time by gizmo10203 and used with permission of the author. All other rights reserved by the author.