Author Archives: jlee3811

CS-448 Apprenticeship Patterns Chapter 1 Introduction

Chapter 1 of the Apprenticeship Patterns textbook introduces the principles and ideals of software craftsmanship. This is an approach to software development that emphasizes the importance of writing high-quality code and delivering value to customers. Some key aspects of software craftsmanship include quality code, continuous learning, collaboration, focus on customers, and testing/quality assurance. Following these key aspects helps promote professionalism, excellence, and pride in one’s work as a software developer. This textbook draw inspiration from several highly skilled individuals that were interviewed for the book. Their values helped give meaning to what it means to be an apprentice, journeyman, or a master.

Apprentices typically have the attitude that there is always a better/smarter/faster way to do what you just did and what you are currently doing. Apprenticeship is the beginning of the journey as a software craftsman. One of the most important things needed is the ability to learn and grow for yourself, and then attention from your peers and experienced developers will follow. As you progress through the stages of craftsmanship, it is important to retain the knowledge and attributes gained from the previous stages. Journeyman will continue to focus on growth in their craft, but also focus on connections between practitioners, within and outside the team. Traditionally, a journeyman will move from master to master and sharing ideas amongst the various teams. They are focused on building a portfolio of applications that demonstrates the progress in their craft. Their responsibilities are wider than those of an apprentice, which means their failure can do more harm. Mastery still retains the previous knowledge of the other stages but adds the focus of moving the industry forward. It involves taking skill and translating it into a way to enhance the skills of others.

Apprenticeship is the fundamental learning method through practical experience under the guidance of a skilled mentor or master practitioner. It involves a structured training program where individuals work alongside experienced professionals to acquire the knowledge, skills, and competencies to help further their learning. Key characteristics of apprenticeship include hands-on learning, mentorship, structured curriculum, progression, certification, and industry alignment. Overall, apprenticeship offers a valuable pathway for individuals to gain practical experience, develop professional skills, and pursue careers in the desired field.

1. Introduction | Apprenticeship Patterns (oreilly.com)

From the blog CS@Worcester – Jason Lee Computer Science Blog by jlee3811 and used with permission of the author. All other rights reserved by the author.

CS-448 Week 1

This week I learned about one of several apprenticeship patterns from the “Apprenticeship Patterns” book by Dave Hoover and Adewale Oshineye, the White Belt. The purpose of this is to embrace the state of being a beginner, with no pressure of being an expert. It also states that every step should be embraced with an open mind and to set your previous knowledge aside when taking on new situations. The name “White Belt” comes from the prestige rankings of karate belts, with the white belt being for beginners. As a white belt, you do not carry any previous knowledge about the situation and are forced to learn the way, rather than black belts who know the way. As a programmer, learning a language and becoming proficient in that language is a great feeling. This can create a stubbornness in the person to be unwilling to go through the learning process again in hopes of not making a fool of themselves again when making a mistake.

While these principles are referenced in terms of computer science, they can be applied in general situations as well, especially the White Belt pattern. The well-known saying “you learn something new every day” applies to this pattern as it states that everyone still has room to improve/learn and no one knows everything, even if you feel like you do. This is important to remember when attacking new situations so that you do not limit yourself to possibilities you may not know about. It is something that people might not feel comfortable with at first due to the learning curve that comes with it, but there is always something to take away from failing the first time.

I believe this will be an important principle to follow when going into the professional world. As a software developer, there are a lot of different programming languages that can be learned with their own benefits. While some programming languages are similar, others can be harder to learn with syntax that may not align with each other. Knowing more languages allows for more opportunities when looking for a job. However, it is not easy to learn multiple languages especially when they look completely different. This is where, as a leaner, you must unlearn what you already learn.

2. Emptying the Cup | Apprenticeship Patterns (oreilly.com)

From the blog CS@Worcester – Jason Lee Computer Science Blog by jlee3811 and used with permission of the author. All other rights reserved by the author.

CS448 – LibreFoodPantry and Thea’s Pantry

It was cool to navigate the LibreFoodPantry website and get a better understanding of their company ahead of helping with website development. While exploring their page, I came across the agile values and principles and the Twelve Principles of Agile Software. One of the principles I found interesting was the embracement of changing requirements, even late in development. This is to provide continuous change and adaptations to the product for the customer’s competitive advantage. I chose to write about this because the typical thought process is to stay the course and follow the original plan. However, for an ever changing product market, it is more valuable to welcome the change of requirements rather than staying the course of the original plan.

Thea’s Pantry has a lot of valuable information that is organized in a simple manner that makes it easy for users to navigate. The “User Stories” was a helpful page as it gives insight as to how the process works for a specific cause. For example, they list the steps for when a guest visits the pantry and the different possible outcomes that can happen from it. I chose to write about this because I found it very valuable to get a full understanding of the different types of user interactions that will occur with the website. This will help in the development process as there will be more insight with the website and give a better grasp on the best way to fix the problems and enhance the user experience.

https://librefoodpantry.org/

Developer/UserStories.md · spring2024-updates · LibreFoodPantry / Client Solutions / Theas Pantry / Documentation · GitLab

From the blog CS@Worcester – Jason Lee Computer Science Blog by jlee3811 and used with permission of the author. All other rights reserved by the author.

CS343 – Week 12

SOLID is an acronym that stands for the 5 different principles that help write high-quality, maintainable, and scalable code. These include Single Responsibility Principle (SRP), Open-Closed Principle (OCP), Liskov Substitution Principle (LSP), Interface Segregation Principle (ISP) and Dependency Inversion Principle (DIP). Each provides their own benefits and work in tandem together when designing a program.

SRP states that a class should only have one responsibility, meaning only one reason to change. This helps prevent a class from having too many responsibilities that can affect each other when one is changed. Following SRP ensures that the code will be easier to comprehend and prone to fewer errors. However, it is harder than it sounds to fulfill this principle. The quickest solution to adding a new method or functionality would be to add it to existing code, but this could lead to trouble down the road when trying to maintain the code.

OCP states that software classes, modules, functions, etc. should be open for extension but closed for modification. This is essential because it allows entities to be extended without modification so that developers can add new functionality without risking the chance of breaking the code. Adding an additional level of abstraction with the use of interfaces help design the program to provide loose coupling.

LSP states that any instance of a derived class should be substitutable for an instance of its base class without affecting the program in a harmful way. The importance of this principle revolves around the ability to ensure the behavior of the program remains consistent and predictable. Unfortunately, there is no easy way to enforce this principle, so the user must add their own test cases for the objects of each subclass to ensure that the code does not significantly change the functionality.

ISP focuses on designing interfaces that are specific to a user’s needs. Instead of creating a large interface that covers all methods, it is more beneficial to split up the methods across smaller, more focused interfaces that are less coupled. For example, having too many methods in an interface can sometimes cause issues in the code, so separating the methods into individual interfaces that can be implemented by a certain class.

DIP states that high-level modules should not depend on lower-level modules but should depend on abstractions. This approach aims to reduce coupling between modules, increase modularity, and make the code easier to maintain, test, and extend. An important thing to note is that both high-level and low-level modules depend on abstractions. Dependency Inversion utilizes the SOLID principles which in turn leads to a more refined and maintainable code.

This is related to the class subject in many ways because it works as a guideline to write the most convenient code for programmers to maintain. Testing the aforementioned code is a simpler process when abiding to the SOLID principles as well. It also allows for easy scalability, making it essential for large code sets that evolve and become more complex over time.

SOLID Design Principles: The Single Responsibility Explained (stackify.com)

From the blog CS@Worcester – Jason Lee Computer Science Blog by jlee3811 and used with permission of the author. All other rights reserved by the author.

CS-343 Week 10

GRASP (General Responsibility Assignment Software Patterns) assigns responsibilities for different modules of code in object-oriented software development. There are seven types of roles assigned to classes and objects to easily organize the responsibilities. These roles include Controller, Information Expert, Creator, High Cohesion, Low Coupling, Polymorphism, and Protected Classes. It is important to note that GRASP is occasionally paired with SOLID principles, making for the combination SOLID GRASP. Design patterns like this help keep code clean and more organized, making it more comprehensible and reusable.

Controller suggests that the entity responsible for handling a system operation should be its own class to act as an intermediary between the user interface and the logic of the program. This helps separate concerns as well as improve flexibility of the whole system. Information Expert focuses on assigning responsibilities to classes that include the most information required to fulfill them. By following this principle, we can design systems where responsibilities are distributed efficiently amongst classes which in turn reduces dependencies. Creator guides the allocation of responsibility for creating objects. A class should be responsible for creating objects of other classes if the first class aggregates or has a composition relationship with the second class. By following this, there will be less coupling between classes and ensures better maintainability. High cohesion advocates designing classes with a clear and focused purpose. Each class should have a single responsibility and capture related behaviors and data. This provides easier comprehension of the code and simpler test cases to write. Low Coupling relies on designing classes with minimal dependencies on other classes. The less interconnections between classes allows to create a more modular system and improves maintainability since changes to one class are less likely to affect other classes. Polymorphism enables objects of different classes to be treated the same throughout a common interface in object-oriented design. Leveraging this principle allows for the design of systems to be extensible and adaptable to new requirements and promotes loosely coupled systems.

Applying GRASP principles ensures a clear distribution of responsibilities and promotes low coupling and high cohesion among classes. These principles help create an understandable design architecture while also providing the ability to adapt to future changes. This also helps team members collaborate due to better facilitation for communication among developers and it establishes a common understanding of each component’s role and interactions.

What is GRASP (General Responsibility Assignment Software Patterns)? | Definition from TechTarget

GRASP Principles: Object-Oriented Design Patterns | by Patrick Karsh | Medium

From the blog CS@Worcester – Jason Lee Computer Science Blog by jlee3811 and used with permission of the author. All other rights reserved by the author.

CS343 – Week 9

Front-end development is focused on the user experience with the site. They design the elements of the application that the user interacts with and ensures that the interface is fast and easy to use. As technology continues to grow with different devices with varying screen sizes, a challenge that has arisen for front-end development is the accommodation for the different screen sizes that want to access the same site or application. There are different programming languages for front-end development, including HTML, CSS, and JavaScript. HTML (HyperText Markup Language) allows browsers to display text or load elements, rendering webpages for users. CSS (Cascading Style Sheets) is the standard language to identify how HTML content will be displayed, such as fonts, foreground and background colors. JavaScript (JS) extends the functionality of websites beyond HTML and CSS. This gives websites the ability to refresh themselves dynamically and respond to user actions without page reloads. You can also model UI components like pop-ups and interactive sliders.

While the front-end interface draws a lot of attention to the general audience due to the visual interaction with it, the back-end forms the backbone of any online program. It includes the logic, data storage, and security features required to create a fully functional and reliable application. It is also responsible for processing client requests, interacting with databases, and generating responses to be delivered back to the client. There are several different responses that can be generated depending on the quality of the request. Examples of some responses include 200, 201, 400, 404, and 500. 200 OK indicates the request was successful and returns the requested data. 201 Created indicates another successful request but creates a new resource rather than displaying an existing one. 400 Bad Request indicates the server could not understand the request due to malformed syntax. 404 Not Found is a different type of client error response which indicates the requested resource could not be found. 500 Internal Server Error indicates the server encountered an unexpected condition which prevented a successful request.

The use of databases is important when it comes to designing the back end for several reasons. Data persistence is a positive outcome from databases and ensures that information is not lost when an application is closed or is restarting. It also allows for better data management and efficient mechanisms for inserting, updating, deleting, and retrieving information. Concurrency control is allowed through the use of databases, meaning multiple users or applications can access and modify data simultaneously.

Front-End Development: The Complete Guide (cloudinary.com)

Back-End Web Architecture | AppMaster

From the blog CS@Worcester – Jason Lee Computer Science Blog by jlee3811 and used with permission of the author. All other rights reserved by the author.

CS343 – Week 8

API, or application programming interface, is a set of specifications that allow applications to interact with one another. They enable transfer of information and is treated as an intermediary level let companies open their application data to external third-party developers as well as internal departments within the company. An example of how APIs work is third-party payment processing. For instance, when making a payment online and being given an option to “Pay with PayPal”, the connection made between the third-party payment system and the website where the payment is being made is reliant on APIs. When selecting the option, an API calls to retrieve information or request. After processing the request from the application to the web server, the API makes a call to the external program/web server. In this situation, it would be the third-party payment system. The external system then sends the requested information back through the API to transfer to the initial requesting web server.

REST is a set of design principles and stands for “representational state transfer” architectural style. Sometimes referred to as RESTful APIs, they were first defined in 2000 by Dr. Roy Fielding and provides more flexibility and freedom for developers. They can support many different data formats and are required to follow the 6 principles, also known as architectural constraints. The six principles are the following: uniform interface, client-server decoupling, statelessness, cacheability, layered system architecture, and code on demand (optional).

Uniform interface means that all API requests from the same resource should have identical formats to ensure that a piece of data belongs to only one uniform resource identifier (URI). The resource should not be too large while still containing the information the client needs. Client and server applications must be completely independent of each other in REST API design. The client application only needs to know the URI of the requested resource and cannot interact with the server in any other ways. Statelessness means that each request needs to include all the information necessary for processing it, which means REST APIs do not require any server-side sessions. Resources should be cacheable on the client or server side and the server responses should contain the needed information about whether caching is allowed for the delivered resource. The purpose of this is to improve performance on the client side while also increasing scalability on the server side. REST APIs have different layers to them that calls and responses go through. To note, do not always assume the client and server applications connect directly to each other. These APIs need to be designed so that neither the client nor the server can tell whether it communicates with an intermediary or end application. In certain cases, responses can contain executable code when they usually send static resources. In the case that an executable code is added (such as Java applets), the code should only run on-demand.

What is a REST API? | IBM

From the blog CS@Worcester – Jason Lee Computer Science Blog by jlee3811 and used with permission of the author. All other rights reserved by the author.

CS343 – Week 7

SOLID is an acronym that stands for the 5 different principles that help write high-quality, maintainable, and scalable code. These include Single Responsibility Principle (SRP), Open-Closed Principle (OCP), Liskov Substitution Principle (LSP), Interface Segregation Principle (ISP) and Dependency Inversion Principle (DIP). Each provide their own benefits and work in tandem together when designing a program.

SRP states that a class should only have one responsibility, meaning only one reason to change. This helps prevent a class from having too many responsibilities that can affect each other when one is changed. Following SRP ensures that the code will be easier to comprehend and prone to fewer errors. However, it is harder than it sounds to fulfill this principle. The quickest solution to adding a new method or functionality would be to add it to existing code, but this could lead to trouble down the road when trying to maintain the code.

OCP states that software classes, modules, functions, etc. should be open for extension but closed for modification. This is essential because it allows entities to be extended without modification so that developers can add new functionality without risking the chance of breaking the code. Adding an additional level of abstraction with the use of interfaces help design the program to provide loose coupling.

LSP states that any instance of a derived class should be substitutable for an instance of its base class without affecting the program in a harmful way. The importance of this principle revolves around the ability to ensure the behavior of the program remains consistent and predictable. Unfortunately, there is no easy way to enforce this principle, so the user must add their own test cases for the objects of each subclass to ensure that the code does not significantly change the functionality.

ISP focuses on designing interfaces that are specific to a user’s needs. Instead of creating a large interface that covers all methods, it is more beneficial to split up the methods across smaller, more focused interfaces that are less coupled. For example, having too many methods in an interface can sometimes cause issues in the code, so separating the methods into individual interfaces that can be implemented by a certain class.

DIP states that high-level modules should not depend on lower-level modules but should depend on abstractions. This approach aims to reduce coupling between modules, increase modularity, and make the code easier to maintain, test, and extend. An important thing to note is that both high-level and low-level modules depend on abstractions. Dependency Inversion utilizes the SOLID principles which in turn leads to a more refined and maintainable code.

From the blog CS@Worcester – Jason Lee Computer Science Blog by jlee3811 and used with permission of the author. All other rights reserved by the author.

CS-343 Week 6

With the constant updates that software can endure, there have been schemes that help track each update. Software versioning is the process of assigning either unique version names or numbers to unique states of computer software. This allows programmers to know when changes have been made and track them. There are several different types of versioning schemes, including name versioning, basic versioning, and internal and external versioning.

Name based versioning identifies software with words and labels rather than a numerical value. This is usually less structured than some of the numerical versioning systems. A basic versioning scheme uses simple, numeric values to track changes. While it is simple and easy to understand, it may not provide detailed information about the nature of the changes with previous versions. Internal versioning, also known as internal build numbers, is used within an organization or for internal purposes to track and manage different iterations. This is separate from external versioning, which is used to communicate with users. The versioning scheme we have started to learn about in class has been semantic versioning. This is a format that I have seen before, but personally did not know much about how exactly the scheme works.

Semantic versioning, also referred to as SemVer, is a versioning system that has the ability to provide a universal way of versioning software development. It is represented by a 3-component number (X.Y.Z) to represent the three different software releases. The Z value indicates the releases for bug fixes, with no functionality changes coming in these updates. Y shows a minor version update where a new functionality is introduced. When increasing the Y value after an update, you must reset the Z value back to 0. The X value denotes a major version, which breaks the current API. It is helpful to split up the different updates that the software endures in this manner so that the user knows the importance of each change.

There are advantages that SemVer brings to software development. It is a fairly simple scheme which provides the ability to track every transaction and help manage dependencies. This also helps the user to identify the risk of taking on the updated packages. It is a very valuable option for version management, especially when it relates to open-source and collaborative development environments.

Semantic versioning and impact of breaking changes in the Maven repository – ScienceDirect

From the blog CS@Worcester – Jason Lee Computer Science Blog by jlee3811 and used with permission of the author. All other rights reserved by the author.

CS343 – Week 4

Through the duration of this class, we have worked a lot with different types of classes, abstract and concrete, as well as interfaces to better design the code. It was not a new concept to me, as I have learned some of the basics to these in prior classes. However, I never truly understood the benefits and the right time to incorporate each. The articles I found give a simple explanation on the distinctions between concrete classes, abstract classes, and interfaces, as well as the correct situations to use them in.

A concrete class, sometimes just referred to as a class, is used to specify any entity. It also can work as a blueprint for all entities with the same attributes. An abstract class and interfaces are similar and was often confusing for me to distinguish the two of them at first. An abstract class will have methods implemented inside the body, but abstract methods will not have the body of the method inside this class. For example, the duck class I was working with for Homework 2 has the abstract class Duck and the abstract method display(). The body of the method is not present in the abstract class because the different concrete classes implementing Duck uses display() to show different messages. An interface only has the method names included for classes to implement with the interface but does not have any body of the methods. This is what partially distinguishes abstract classes from interfaces, as abstract classes can have concrete methods defined in them while interfaces can only have the method names defined. Interfaces are handy when only needing to enforce a contract. Whoever implements this interface will provide an implementation of all the methods. Abstract classes are helpful when only needing partial implementation, which leaves the responsibility of implementing non-useful methods from the class.

The phrase “program to an interface, not an implementation” is new to me and I am starting to make more sense of it. Concrete classes are the actual implementation, interfaces are the contract, and abstract classes are a trade-off between both. Being able to fully program these three structures into the program helps with maintainability, extensibility, and testability. When programming to an interface, you are forced to split the program into subsystems, with each subsystem responsible for certain tasks and having the ability to communicate with each other to complete the whole task. The key to making the program more flexible is focusing the design on what the code is doing rather than how it does it.

I decided to pick this topic for my blog because I had always had a good idea of how to physically write programs to function correctly. However, something that I never focused on before was the structure of the code which can help when needing to develop the program further after initial creation. Most of our time spent in the class so far has been focusing on this concept and it is proving to be very important the more a program continues to develop.

Program to Interface, Not Implementation – Beginner’s Tutorial for Understanding Interface, Abstract Class and Concrete Class – CodeProject

Programming to an Interface – DZone

From the blog CS@Worcester – Jason Lee Computer Science Blog by jlee3811 and used with permission of the author. All other rights reserved by the author.