Author Archives: ztram1

Week 14: CS-343

Design Patterns

A design pattern is a general solution that can be used to solve commonly occurring problems in software design. A design pattern cannot be put directly into code, rather it is a template of how to solve a problem that can be used various situations.

Design patterns are helpful as they speed up the development process by providing proven examples to be used as a reference for common problems. When designing software, small subtle issues can build up leading to major problems that can only be seen during implementation. Using design patterns can help prevent these subtle issues from occurring which reduces the likelihood of major issues occurring.

Because design patterns are tested, proven, and commonly used, patterns also allows for better communication among developers by using well known and understood names for software interactions.

Types of Design Patterns

Creational

Creational design patterns cover class instantiation. These patterns can be further divided into two classifications, class-creation and object-creational patterns. Class creation uses inheritance in the instantiation process, while object creation uses delegation to create objects. Some creational design patterns are:

  • Singleton
    • A class where only a single instance can exist
  • Factory Method
    • Creates an instance of several derived classes
  • Object Pool
    • Avoids expensive acquisition and release of resources by recycling objects that are no longer in use

Structural

Structural design patterns are about class and object composition. Like creational patterns, structural patterns can also be broken down into class creation and structural object patterns. Class creation patterns use inheritance to compose interfaces, while object patterns define ways to compose objects to obtain new functionality. Some structural patterns are:

  • Adapter
    • Matches interfaces of different classes
  • Private Class Data
    • Restricts accessor/mutator method access
  • Decorator
    • Adds responsibility to objects dynamically

Behavior

Behavior design patterns are about how objects communicate with each other. Some examples of behavior design patterns are:

  • Null Object
    • Used to act as a default value of an object
  • Chain of Responsibility
    • A way of passing a request between a chain of objects
  • State
    • Alter an object’s behavior when its state changes

Conclusion

This article was chosen because it clearly described what design patterns are, what they are used for, and gave examples of the different types of design patterns. As stated before, not only does the usage of design patterns help with preventing major issues, they also allow for better communication among developers which is essential to a team’s success which is why I chose to write about design patterns. As I continue to design software, effectively using design patterns will become more and more prevalent, so learning about them now will only be beneficial.

Resources:

https://sourcemaking.com/design_patterns

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

Week 13: CS-343

Anti-Patterns

Anti-Patterns are “imperfect” fixes that may seem like they solve a problem, but over time, can lead to more problems where using anti-patterns are more inconvenient than not. Because anti-patterns cause problems over time, teams are forced to go back and fix them which lead to higher costs and delayed release schedule.

Types of Anti-Patterns

Spaghetti Code

Spaghetti code refers to the logical structure of the code resembling a plate of spaghetti, meaning it is unorganized and confusing. Spaghetti code usually occurs when a developer starts a project without putting much thought into the organization of the code. Although the end product may work, adding functionality may increase fragility. Using the spaghetti analogy, adding more code would be like adding more spaghetti leading to an even larger tangled mess.

Golden Hammer

Golden Hammer refers to one tool being the solution to all problems. A developer may have used a well designed piece of code to solve previous problems, but relies too heavily on it by trying to use the code for problems that do not necessarily belong. Forcing code where it may not belong can lead to spaghetti code. The Golden Hammer concept can be thought of as trying to cut a piece of wood with a hammer.

Boat Anchor

The Boat Anchor anti-pattern occurs when a piece of code is left in the code base, so it can be saved for later use. Although the code may not make sense for the program, the thought process of saving the code is if the code is needed later it can be turned on and off with comments. Some may think because a piece of code is commented out, there is no harm in leaving it. However leaving unnecessary code can lead other developers confused about what the code is intended for and over time may slow down build times. Turning the code back on may also break the code if changes were made to the point where the saved code may no longer be compatible.

God Object

A God Object is an object or a class that has too much responsibility for the program. This violates the single responsibility principle, as every object and class should only be responsible for one single part of the program. For example, there is a customer ID class responsible for the customer’s first and last name, transactions, and more. Rather than the customer ID class manage all those details, better practice would be to have customer ID be responsible for the customer’s name while a separate class is created for transactions.

Reflection

This resource was chosen because it explains what anti-patterns are, why they are bad, and listed common types of anti patterns. The article was informative as I realized I am guilty of utilizing many of these anti patterns such as spaghetti code and god object. After reading this article I am now aware of these anti patterns, and will be more mindful to not use them in the future.

Resources:

https://www.lucidchart.com/blog/what-are-software-anti-patterns

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

Week 13: CS-348

Software Process Model

A software process model is an abstract framework that gives steps on ways to plan software development processes and how they can be organized and executed. There are different types of software process models but all include some form of:

  • Specification – Defining what the system should do
  • Design – Defining the structure of the system
  • Implementation – Implementing the system
  • Validation – Ensuring the system works as intended and that the system is what the customer wants
  • Maintenance – Changing, modifying, updating to keep up with the customer needs/fixing bugs

Types of software process models

There are many different types of models that are available to be used by organizations. Some allow organizations to use the model directly while others are more flexible, allowing organizations to create custom steps that are more specific towards their needs.

Software processes are typically specified using Software Development Life Cycle (SDLC) models. These models specify the different steps of the software development process and the order they are executed. 

Waterfall Model

The waterfall model breaks down software process activities into sequential phases. Each phase depends on the outcomes of the phases before and cannot be started until all phases prior have been completed. Each phase corresponds to a software process. For example, the first phase would be specification/requirements analysis because developers cannot create a system without knowing its intended function. Once that step is completed, then the next phase can be started and so on.

V Model

The V model is similar to the waterfall model where steps are followed in a sequential order. Initially after each step, the model progresses downwards to move onto the next step. Once the the coding/developing stage is complete, the model then bends upwards to create a V shape. This model highlights the relationships between each phase of the development life cycle and its corresponding phase of testing. The downward process is called the Verification Phase, while the upward process of the model is called the Validation Phase which are completed by developers and testers, respectively.

Agile

Unlike the two previous models, Agile is not a model with specific steps to follow. Rather Agile is a broader term for a set of methods and practices that encompasses values from the Agile Manifesto. These values helps teams to react quickly to any unforeseen changes, while reducing risk. The software development approach to Agile is usually rapid and small cycles. Doing this results in more frequent releases with each building upon the previous releases. Agile can be implemented by using frameworks such as Scrum and Kanban.

Reflection

I chose this resource because before simply listing different types of models, it clearly defined what the software processes are. This ensures a foundation is established. Although only three of the models in the article are listed above, there are several more models which I found interesting as I was unfamiliar with some of them. Because organizations use different models, being aware of the more popular ones will be beneficial in the future.

Resources:

https://www.visual-paradigm.com/guide/software-development-process/what-is-a-software-process-model/

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

Week 12: CS-343

Refactoring Code

Refactoring is an important process when maintaining code bases. The goal of refactoring is to change the implementation, definition, and/or the structure of the code without changing pre-existing functionality of the application. Refactoring allows for better extensibility, maintainability, and readability. Refactoring usually results in smaller and simpler code bases, allowing new functionality easier to implement.

When to refactor?

Because refactoring results in simpler code bases, refactoring should be done before adding new features. Working with clean code after refactoring makes the process of adding new functionality easier. For example, if the code base is not extensible, then adding new functionality might break the code leading to more work to fix the problem. Refactoring should also be done before code reviews or before addressing bugs.

What code needs refactoring?

Code smells can be defined as structures in the code that indicate violations of fundamental design principles and negatively impact design quality. Code smells can be used to identify what needs to be refactored. There are over 70 refactoring techniques that help identify problems and provide a known solution. Some techniques are the Extract Method, Replacing Temp with Query, and Encapsulation of a Field.

Refactoring techniques

Extract Method

The Extract Method can be used when code can be grouped together. For example, there is a class called ‘Student’ that has two print statements that prints student details such as name and year. Refactoring would include grouping the two print statements together into its own function. This is helpful because if you wanted to add more details to be printed, you only have to add one line to the function.

Replace Temp with Query

Temp refers to a temporary variable that holds a value of an expression to be used later in the code. This technique replaces the temp variable with a query method that returns the result of an expression. For example, there is a variable where ‘basePrice = quantity * costPerItem’. The variable can be represented as a new method called ‘basePrice()’ that returns the expression, ‘quantity * costPerItem’. If the temp variable is used among multiple classes, having a common method would more manageable.

Encapsulate Field

Encapsulating a field involves using methods that read and write data rather than accessing data directly. When accessing variables directly, they are often set to public which allows the data to be modified without a way to validate the change. Getter and Setter methods should be used to access class variables instead because the access level for the variables can be set to private, meaning the data itself cannot be accessed unless using the access methods. Using access methods provides a way to validate changes.

Reflection

This resource was used because it was clear and concise, making the content easy to understand. The article also included code examples of the techniques which improved comprehension. Before reading, I was unaware of some of the techniques listed which will be helpful when refactoring in the future.

Resources:

https://www.geeksforgeeks.org/refactoring-introduction-and-its-techniques/#

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

Week 11: CS-343

Software Frameworks

What is a framework?

A framework is a platform providing a foundation for creating software development projects. Frameworks can be thought of as a template of a working program where developers can modify the program by adding code. Because frameworks are essentially templates, there are shared resources that are bundled into one package. Some of these resources include libraries, image files, and reference documents. The package can be customized to match the needs of the project.

Different types of frameworks

Backend Web Frameworks

Backend Web, or also known as simply Web Frameworks, are the most commonly used. These frameworks help developers create web applications and dynamic websites. The use of web frameworks has streamlined the process of web development by automating common tasks of web developers such as database access and session management. Rather than using HTML, JavaScript and CSS, backend frameworks use programming languages to access a database, hosted on a server. A common backend framework is Django.

Frontend

Unlike backend where frameworks are loaded server-side, frontend frameworks are executed in the user’s browser. Frontend frameworks allow developers to customize and design the way the web application looks to the user. Popular frontend frameworks are Angular JS and React.

Mobile Development

Nowadays mobile applications are extremely common resulting in mobile development frameworks. Similarly to desktop frameworks, these give developers a foundation to build their mobile applications while allowing full customizability. There are two types of mobile frameworks, native and cross-platform. Native frameworks are for applications that are built specifically for a particular operating system (iOS or Android). Alternatively cross-platform frameworks are for apps that are built to be compatible with any phone. A commonly used mobile framework is Flutter.

What makes a good framework?

A good framework should be simple to understand and easy to implement. It should also follow design principles such as:

  • Being extendable, adding new functionality by adding code rather than modifying
    • Framework cannot be modified at all, but only extended
  • Allows developers to create components that can be reused
  • Should have a default behavior and be useful. No redundant code that is unnecessary

Why use a framework?

Frameworks greatly reduces the time spent on developing. When starting a new project, there are steps that need to be done regardless the project. Using frameworks helps streamline that process by already providing those details. This allows developers to focus their time on extending the functionality specific to their application’s needs.

Reflection

This article was chosen because it broke down the different parts of a framework such as what it is, the different types, and why one might use a framework. Prior to reading this blog, I had a somewhat unclear understanding of what frameworks are. Now I understand that they are useful tools that speeds up the development process by providing essentially a template of a working program. What was learned will be applied to future, larger projects that could benefit from a framework.

Resources:

https://codeinstitute.net/global/blog/what-is-a-framework/

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

Week 10: CS-348

Software Testing

Software testing is an important process that evaluates and verifies a software application works as intended.

Types of Software Testing

There are many different types of software testing, some are:

  • Acceptance – The entire system as a whole is tested and verified
  • Integration – Ensuring that individual parts of a software system properly work together
  • Unit – A unit is the smallest testable component of a software system. This type tests each unit and verifies correctness.
  • Functional – Tests functions by emulating business scenarios
  • Performance – Tests the performance of the software under different system workloads
  • Regression – Tests rigidity of the software by adding new features and seeing if those new features break or impede on fucntionality
  • Stress – Testing the software under maximum workload to see how much the system can handle until it fails
  • Usability – Testing how well a customer can complete tasks using the system

Software Testing Best Practices

The software testing process is typically done with a common methodology. Steps to this methodology can include configuring test environments, writing test cases, analyzing test results, and submitting bug reports. Testing tasks are typically automated using tools. Automating tests is beneficial because it allows teams to quickly implement different test cases, test frequently, and get feedback on what did/didn’t work.

Some best practices include:

  • Continuous testing – Testing builds as soon as they are ready. This relies heavily on automated testing, allowing software to be validated earlier in the development process. Testing often allows for bugs and errors to be found earlier; therefore, reducing the amount of time spent having to go back and redesigning.
  • Configuration Management – Organizations keep test assets (code, test scripts, requirements, etc) in a central location and track what builds need to be tested. These assets allows teams to follow the organization’s testing requirements.
  • Bug Tracking – Keeping track of defects is important

Why Test Software?

Testing software regularly can help teams reduce costs and time spent on developing the software. Before releasing a project, testing the software for any errors or bugs is important to give users the best possible experience. If users find that the software does not work as intended, they may stop using it and find an alternative that does work. Although testing has a cost, the cost of releasing defective software outweighs that of continuous testing.

Reflection

The resource used was chosen because it clearly breaks down the different parts to software testing such as the different types of testing, best practices, and why testing is important. Prior to reading this article, I had heard of a few types of testing like Unit Testing, but only became aware of the other types of testing such as Regression Testing. I now understand when designing software, code should be tested regularly and often as overall it will save time and headache.

Resources:

https://www.ibm.com/topics/software-testing#:~:text=Software%20testing%20is%20the%20process,Test%20management%20plan

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

Week 8: CS-343

SOLID Design Principles

SOLID is a subcategory of five principles, the first being:

Single Responsibility Principle (SRP)

SRP states that a class, module, or function should only have a singular function.

For example, having a class ‘Animal’ with methods ‘displayAnimalName()’, ‘animalSound()’, ‘feedAnimal()’ would be a violation of SRP because each method has a different function. Creating three separate classes that would each represent a functionality resolves the violation. This entails new classes are created for DisplayName, Sound, and Feeding. Although this may lead to more code overall, having separate classes allows for better maintainability. Without SRP, making changes to one functionality may break another.

Open-Closed Principle (OCP)

OCP states that code should be open for extension, but closed for modification. Therefore the code’s behavior should be extended by adding more code rather than modifying the existing code.

Function ‘getArea()’ calculates the area of a shape using a switch statement where there are cases for a square and circle. To add another shape, the switch statement must be modified to add a case for the new shape, violating OCP. To satisfy OCP, one would create separate classes for each shape that implements the Area interface. Now to add a new shape, one would add a new class and implement the Area interface rather than modify the original switch statement.

Liskov Substitution Principle (LSP)

LSP states that child class objects must be substitutable with objects of the parent class without affecting the correctness of the code.

Imagine a parent class ‘Bird’ with method ‘fly()’, and child classes ‘Penguin’ and ‘Eagle’. Both inherit ‘fly()’ because ‘Penguin’ and ‘Eagle’ are child classes of ‘Bird’. Because penguins cannot fly, the ‘fly()’ method in ‘Penguin’ has been overridden to do nothing. Doing this would violate LSP because objects of ‘Penguin’ would not be substitutable for objects of ‘Bird’.

Interface Segregation Principle (ISP)

ISP states that users should not be forced to implement interfaces they will not use.

Imagine an interface ‘Worker’ that has methods ‘work()’ and ‘eatOfficeLunch()’. Classes ‘FieldWorker’ and ‘OfficeWorker’ both implement the ‘Worker’ interface. Because ‘FieldWorker’ does not eat in office, the method ‘eatOfficeLunch()’ is unnecessary. This violates ISP because ‘FieldWorker’ is forced to implement ‘eatOfficeLunch()’ although the method will not be used.

Dependency Inversion Principle (DIP)

DIP states that high-level modules should not depend on low-level modules, keeping that as separate as possible.

For example, there’s a project with high-level systems (backend logic), that relies on low-level modules (database access). However the project’s team wants to change the database from one type to a different. Because the high-level systems are specifically written and depend on the database type, they would no longer work once the database type changes. Having high-level systems be more abstract and able to be implemented in different ways is ideal.

Conclusion

The article used was chosen because it gave examples with code, making understanding easy. As someone who wishes to have a career in software development, knowing the best practices for designing maintainable code is crucial. I expect to apply these principles to all future projects.

Resources:

https://www.freecodecamp.org/news/solid-design-principles-in-software-development/

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

Week 7: CS-348

Version Control

Version control is a software development process that tracks and manages every change made to a code base. Tracking changes allows developers to be able to see what changes were made, who made them, and when they were made. The history of these changes enables developers to revert changes back to previous versions in case of any irreparable damage.

Version control allows for multiple developers to work on a project concurrently. When multiple changes are made at once, conflicts can occur. Version control can identify those conflicts to allow development teams to quickly compare the changes and decide how to handle the conflict. Version control streamlines coordination, sharing, and collaboration.

Types of Version Control Systems

A version control system (VCS) is the system that tracks changes made to files. Common types of VCSs are distributed and centralized, the latter being most common.

Centralized VCS (CVCS)

In a centralized VCS, all files are stored in one central repository where developers work in. The central repository can be hosted on a server or on a local machine. CVCS is most commonly used in projects where teams need to share code and track changes.

Distributed VCS (DVCS)

Distributed VCS store files across multiple repositories, allowing developers access to files from multiple locations. DVCS is often used when developers need to work on projects from multiple machines or who collaborate with others remotely.

Lock-Based

Less commonly used, Lock-Based uses file locking to manage concurrent access to files and resources. File locking prevents more than one user to make changes to a file or resource at a time, eliminating conflict changes.

Optimistic

Optimistic VCS gives every developer their own private workspace. Once changes are made and are ready to be shared, a request is made to the server. Then the server looks at the changes and determines which can be safely merged together.

Popular Version Control Systems

Git

The most popular of version control systems. Git is an open-source distributed version control system that can be used with software projects of any size. This makes Git a popular choice for most, no matter the project.

Subversion (SVN)

Subversion is a centralized VCS; therefore, all project files are kept in one main repository. This makes branching impossible, allowing for easier scalability for large projects. A form of file locking is in place, allowing users to restrict access to subfolders.

Mercurial

Mercurial is another distributed version control system. Mercurial offers an intuitive command line interface that allows developers to use this system immediately.

Conclusion

I chose this resource because it clearly explains what version control is and why it’s important. Before reading this article, I was unaware of the different types of version control systems, and the popular choices that implement them such as Subversion. I also learned when each type of VCS might be more useful than another. This is only the beginning of my knowledge of version control systems. As my journey into software development continues, my understanding of VCSs will only broaden.

Resources:

https://about.gitlab.com/topics/version-control/

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

Week 7: CS-343

Object Oriented Programming Principles

In object oriented programming there are four basic principles: Encapsulation, Abstraction, Inheritance, and Polymorphism. These principles are fundamental such that they are referred to as the four pillars of object oriented programming.

Encapsulation

Encapsulation is hiding or protecting data about a class. This can be achieved by restricting access to public methods. Variables within a class are kept private, while accessor methods are kept public in order to access the private variables.

Encapsulating data helps prevents unauthorized modifications of data by only allowing access to the data using the defined accessor methods. For example, when adding variables to a class rather than accessing/modifying them directly, one would create “getter” and “setter” methods that would still be able to access the data. These methods would allow users the same functionality, but without the risk of undesired changes.

Abstraction

Abstraction is showing only relevant data of classes. Abstraction enables working with high level mechanisms of a class rather than the specific details of implementation, thus reducing complexity.

Picture a system storing different types of vehicles. Rather than creating different concrete classes for each type of vehicle, abstraction can be applied to create one class, ‘Vehicle’, that has the frameworks of basic behaviors and attributes that all vehicles have. These could include methods and attributes such as ‘start()’ and ‘stop()’, and ‘make’ and ‘model’. Then classes for each type of vehicle can be made to extend the ‘Vehicle’ class. Classes that extend ‘Vehicle’ can add specific implementations to the methods and attributes, depending on the vehicle.

Inheritance

Inheritance can be defined as having a “is-a”/”has-a” relationship between a parent class and it’s child classes. The child class derives all methods and attributes from the parent class, enabling reuse of code, but also allowing the addition of unique attributes and methods.

Imagine a system for a college representing faculty and students. A parent class, ‘Person’, is created for common data among all people at the college such as ‘name’ and ’email’. Child classes of ‘Person’ can be created such as ‘Faculty’ and ‘Student’. Both child classes would inherit ‘name’ and ’email’ from the ‘Person’ class, while unique information can be added to each of the child classes. Unique attributes could include ‘gpa’ for ‘Student’ and ‘salary’ for ‘Faculty’.

Polymorphism

Polymorphism can be simply put as reusing code with different types of objects, reducing code redundancy.

Using an interface called ‘Shape’ with method ‘calculateArea()’, different types of shapes can implement ‘calculateArea()’ and change how the specific shape uses the method. For example a square would calculate the area differently than a circle. However, both can still use ‘calculateArea()’ due to polymorphism.

Conclusion

As we learned earlier in the semester, many of us did not have a complete understanding of the four principles above, which is why I chose to learn more about them. After reading the blog, I now better understand the differences and why each of the principles are important. I will be implementing these principles into all future projects.

Resources:

View at Medium.com

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

CS@Worcester – Zack's CS Blog 2023-10-04 12:20:04

Week 4: Understanding Software Licenses

This week I will be writing about software licensing and why I chose this topic. I chose to write about software licensing because I personally do not have much prior knowledge about the topic, so I thought that this would be an interesting (and useful) topic to learn about.

To start off, what is a software license? A software license is a legally binding contract between the software creators and the people who are using the software. The license specifies the conditions of using the software including how the user can use, modify, and distribute the technology and its source code.

Upon initial software usage, the end user usually signs an end-user licensing agreement, or EULA, to contractually agree to the terms stated by the license. Abiding by the EULA is important for both the end user and the developer.

Benefits for the developer:

Benefits for the user:

  • Protects the developer’s rights
  • Allows full control of the usage of the software
  • Prevents users from performing undesired actions that may infringe on the terms of the license
  • Clarifies how the software provider uses your private information
  • Prevents the user from paying for unnecessary tools
  • Keeps the user up-to-date on how the technology can be used

Different Types of Software Licenses (5)

  • Public Domain – Allows anyone to use, modify, and distribute the software. The developers are essentially surrendering all rights they would have under copyright laws.
  • Copyleft (Restrictive) – A type of open-source license stating that any future versions of the software must be open-source, or following the same copyright stipulations, like the source code.
  • GNU Lesser General Public License (LGPL) – A weaker type of Copyleft where the user can modify the software, implement it into their own unique software, and license their software how they see fit.
  • Permissive – Another type of open-source license, minimal amount of restrictions on what users can do with the software. However developers can protect their intellectual property by specifying some restrictions.
  • Propriety – The most strict type for users, and the most protective towards developers. Users are not allowed to modify, copy, or distribute the software. Most used for commercial software.

The resource used was chosen because it was relatively short, yet concise by clearly explaining the basics to understanding software licensing. After reading this blog, I learned a lot as I did not know much about the major types of software licenses and that there are specific licenses that fall under each major type. Therefore the article had a positive impact on me. Because my career goal is to become a software developer, understanding what and how software licenses work will be crucial throughout my entire developer journey. I expect to apply the concepts learned in not only my professional career, but also in my personal life as an end user.

Resources:

Galano, Fernando. “Understanding Software Licensing.” BairesDev Blog: Insights on Software Development & Tech Talent, 22 Mar. 2022, http://www.bairesdev.com/blog/understanding-software-licensing/. 

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