Category Archives: CS-343

What is the difference between a software framework and a software architecture?

Software frameworks are reusable “semi-finished” software for domains (such as ERP, computing, etc.) that implement common parts of the domain and provide well-defined points of variability to ensure flexibility and extensibility. In other words, the software framework is the softwarenation of the results of domain analysis and the template for the final application in the domain.

With the expansion of software scale, wide application and the development of software reuse technology, the software reuse based on subroutine and class has a lot of shortcomings:

(1) The library of the subroutine is becoming more and more huge, which makes it difficult for its users to master

(2) Most classes are too small to do all the useful work by themselves

It is for these reasons that a set of classes (modules) are considered as a whole in reuse, resulting in a software framework. The software framework contains at least the following components:

(1) A series of modules to complete the calculation become components

(2) The relationship between components and the interaction mechanism

(3) A series of variable points (hot spots, or adjustment points)

(4) Behavior adjustment mechanism of variable point

Developers through the software framework behavior adjustment mechanism, peculiar to the general application domain software module bound to the variable point of a software framework, and got the final application system, this process is called software example of a software framework, the existence of software framework allows developers will be the main energy on the development system of the module, so as to improve software productivity and quality.

The behavior adjustment mechanism of the software framework refers to how to adjust the variable part of the framework for the specific application and how to add the method and rules of the specific application module at the variable point.

Ii. Software architecture

Software architecture is a sketch of a system. The objects described by software architecture are abstract components that directly constitute the system. The wires between the components describe the communication between the components explicitly and in relative detail.

Software architecture, by definition, is divided into two camps of ‘constituent’ and ‘decision-maker’, which are described as follows:

The componentized view of software architecture is that the system is described as computing components and their interactions. It has two very obvious characteristics:

Focus on the object of architectural practice — software, with the software itself as the object of description.

This paper analyzes the composition of the software, and shows that the software is not a whole in the sense of “atom”, but a whole composed of different parts connected through a specific interface, which is very important for software development.

Decision-makers believe that software architecture involves a series of decisions, mainly including:

Organization of software systems

Choose the structural elements that make up the system, the interfaces between them, and the behavior that these elements exhibit when they cooperate with each other

How do you combine these elements so that they gradually synthesize into larger subsystems?

The architectural style used to guide the organization of the system: these elements and their interfaces, collaborations, and combinations

Software architecture is concerned not only with the structure and behavior of the software itself, but also with other features: usage, functionality, performance, elasticity, reuse, understandability, economy, and technical constraints and trade-offs.

Personal understanding: When software engineering has a certain scale, software development does not exist in the form of data structure + algorithm, but “divide and conquer” software based on many factors such as technical choices and user needs. The main task of the architect is to divide the software into different modules and define the interfaces between modules.

Sources:

https://softwareengineering.stackexchange.com/questions/229415/difference-between-an-architecture-and-a-framework#:~:text=An%20architecture%20is%20the%20the,that’s%20designed%20to%20be%20extended.&text=Frameworks%20are%20specifically%20designed%20to%20be%20built%20on%20or%20extended.

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

DRY (Don’t Repeat Yourself)

https://thevaluable.dev/dry-principle-cost-benefit-example/

I’ve chosen to talk about a very simple design principle this week called “Don’t Repeat Yourself”, DRY for short. It’s a topic that is covered in this class according to the syllabus and I chose it since its similar to another topic I covered YAGNI in that they’re easy to understand design principles. The meaning is quite self-explanatory, don’t repeat code since if you need to change the behavior of a certain project, you’d have to rewrite numerous lines of code if DRY wasn’t applied. However, applying this principle to everything isn’t efficient either. Trying to apply DRY everywhere causes unnecessary coupling and complexity which also leads to more difficulty changing behavior. According to the link above, using DRY means emphasizes knowledge above all else. What it means by that is that when designing and constructing software, one should have the knowledge of when to apply DRY and when not to for the sake of the readability and efficiency of the code.

In that context, DRY reminds me of the importance of resources in a computer when running something. If you want something run faster, you’ll have to sacrifice more memory. And when you want something to have more memory, you’ll have to sacrifice more speed. Both are valid choices; it really depends on the needs of the software and the user. Say for example, I want to create a program that lists all numbers from one to 100 which I do by writing out a thousand lines of code in which each prints a number. However, if I implement DRY, then I could create an integer variable r and a loop which prints the value of that variable and increments it by one until r equals 100. But the case where I want to alter the behavior to list every odd number between one and 100 is where thing get a bit interesting. In the DRYless scenario, I can simply delete the lines of code that print even numbers. Yet in the scenario with DRY, I’d have to add a condition that skips printing variable r for that iteration of the loop. You have to sacrifice complexity for readability and vice versa. Though the choice is ultimately up to what works best in the current situation. Like in my example, the added complexity from DRY doesn’t really harm the readability, in fact it improves it in some ways, at least in my opinion.

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

It’s Easy to Break Promises

Context

I’m currently writing a Node.js package for a wrapper I’m calling a curfew-promise. It’s simpler than I thought, but it is still worth doing in my opinion. The package exports a single function that returns a promise. The promise has “3” parameters with the function header being: (curfew, func, ...args). The promise then performs func asynchronously (so func itself can be sync or async). It passes ...args to that function when it’s called. Lastly, the key idea here is that if func takes longer than curfew milliseconds to complete, the wrapper will become a rejected promise.

At first, it seemed like a tough task, until I discovered the built in Promise.race() function which creates a promise which we can refer to as the racePromise. That function then also takes in multiple other promises. Whichever passed in promise resolves or rejects first, its value is then passed onto racePromise. I can achieve my curfewPromise then by creating one promise that runs func and one that rejects after curfew has passed. Whichever finishes first becomes the value of the promise the function returned. The only way I’ve found to pause an async operation in JavaScript is via await new Promise((resolve) => { setTimeout(resolve, duration); }); This line, when placed into any async function, will pause operation until duration has passed. You can also remove the redundant brackets and shrink it down to await new Promise(r => setTimeout(r, duration)); , but I prefer to be more consistent.

JavaScript is NOT Multi-Threaded

JavaScript runs in a single thread. The way it pretends to be multi-threaded is by switching back and fourth between tasks to give all of them a little bit of time until they all finish. JavaScript is also an interpreted language. This means while trying to test my package, I had a lot of trouble. I spent a few hours trying to understand what was going on and now that I have, I’m going to write about it to save you trouble.

The Code

I was completely convinced that JavaScript itself was just broken. Here is my package, at least in its current state: (If you’d like to use this or see the modern version, check the GitHub page (soon to also be on npmjs.com))

module.exports = (curfew, func, ...args) => {
    let waitId;

    async function wait() {
        await new Promise((resolve) => { waitId = setTimeout(resolve, curfew); });
        return Promise.reject(new Error("Curfew of " + curfew + "ms have elapsed."));
    }

    async function perform() {
        const value = await func(...args);
        if(waitId) clearTimeout(waitId);
        return Promise.resolve(value);
    }
    
    return Promise.race([wait(), perform()]);
}

wait() creates a promise (using async notation, since from what I’ve read that is more ideal than direct promise notation) which waits until curfew has passed, which then rejects with a useful stack trace message. You’ll notice I’m also storing waitId, which is the ID of the setTimeout call. This way, if func finishes before curfew, I can cancel the timeout and not waste performance. I’ll also be looking into ways to create cancellable promises. I’m aware there are already packages that do this, but I think I’ll benefit from doing it by hand. I could make wait() a synchronous function that simply returns a waiting promise that calls setTimeout for reject, but I chose making it like this because then it matches the form of perform() (two async functions), and it allows me to write two lines that are visibly neat rather than trying to force everything into one line.

perform() creates a promise that waits until func is finished. Once it is, it’ll attempt to stop the waiting promise. If the promise is still waiting, it’ll stop it. If the promise has already rejected, it will do nothing. Then, the function returns a resolved promise with the value from func. I chose to write return Promise.resolve(value) instead of return value, which I understand to be the same thing, for consistency once again, and I think it makes the code more readable overall.

Lastly, I am creating the promises off of these functions and making them race. The function returns a promise that resolves or rejects whenever the first of the two – wait() and perform() – finish.

The Problem

I was able to narrow down the problem to this line:

        const value = await func(...args);

All of my tests had worked until I did something like the following:

const curfewPromise = require("./index");

// Broken Promise 1
console.log(curfewPromise(10000, async () => { 
    for(i = 0; i < 1000000; i += .001);
}));

// Broken Promise 2
console.log(curfewPromise(10000, async () => { while(true); }));

I found that for broken promise 1, despite the fact that curfewPromise returns a promise, it wouldn’t finish until the for loop finished. Even if I set the curfew to 0, it would take until the for loop completed. Broken promise 2 would never even end. I purposefully wanted to test these edge cases, where something would actually take a long time for ever (a good example for why I want the ability to cancel a promise).

The problem that I realized so frustratingly last evening is, and say it with me, JavaScript is NOT multi-threaded. Yes, when you run an asynchronous function, you can do other things in the meantime while it finishes. But as far as I can tell, JavaScript does this on a line by line basis. If you have a single line that is very slow or infinite, JavaScript will start running it, as that’s how asynchronous functions work, and then after some progress, it will move on. The thing is, you can’t make progress until that line ends. In the case of an infinite while loop, it will never end. In the case of a very slow one-line for loop, it can’t move on until the for loop is finished. Promise.race() cannot return a promise, so curfewPromise cannot return a promise. Once the for loop actually ends, it’s a gamble to decide which non-neutral-state promise will be chosen to have won the race. (Also keep in mind when using very small curfews, there is internal delay and it may not behave how you expect).

Conclusion

JavaScript is not multi-threaded. Make sure you keep that in the back of your mind. I was inadvertently testing for a case that shouldn’t ever even happen. While it was frustrating trying to figure out what was wrong, I still think that this kind of struggle is necessary in both life and learning. I always learn the most in coding when I’m trying to find out how to do something and I have 20 tabs open.

While this is a simple package that does something many developers probably can do easily, I still want to spend time making it and even upload it to npm. I think even though it’s simple, the function still helps clean up syntax to improve readability and reduce lines. I also think making it an external package helps to reduce complexity in your projects and helps me use it in multiple projects. Maybe someone can also look at it for help when learning how promises work.

At the end of the day, promises and asynchronous functions are an incredibly valuable tool in JavaScript and the illusion of multiple threads helps in most situations. Just be careful to not break your promises.

From the blog CS@Worcester – The Introspective Thinker by David MacDonald and used with permission of the author. All other rights reserved by the author.

The must knows of Architectural patterns (12/10/2020)

When thinking about going into the job market for a computer scientist there is a common theme. This includes big enterprises needing systems or designed to be produced in order to benefit you and their operations. Although before even starting this we need to understand Software architecture. An architectural pattern, in general, is considered to be a reusable solution to a commonly occurring problem. within the Architectural pattern, we tend to see a total of 10 different patterns that make up the basic framework. One of these simple frameworks is a layered pattern. this pattern can be used to structure programs that will be decomposed into groups of sub-categories. with this particular pattern, we see it being used in desktop applications and E-commerce web applications. the second pattern we see is a client-server pattern which is made up of a server and multiple clients. This will allow server components which will allow assisting multiple clients among a broad range of devices.  you will be able to find this pattern most frequently in Emails, documents, sharing, and banking. The third pattern that mostly relates to a big data analyst would be the master-slave pattern. The master-slave pattern is able to distribute the work among identical slave components, which will ultimately compute the final results from the results which then gets fed to the slaves to return. this is mainly used in datasets and databases in replication. the database is usually considered an authoritative source and usually synchronized between the databases of slaves and masters.  In inorder for this to work correctly we need to have them connected to a bus in a computer system in a sense of branches where we see that the master usually has 3 slave nodes. The 4th design pattern we usually see is the Pipe filter pattern. A pipe filter pattern can be used to structure systems that produce and process a stream of data. Each of the said processes is enclosed within the filter component, which allows the data to be processed through pipes. you can think of these pipes to be as a buffer so the data can be synchronized in the dataset if new data arrives. As well you may think of the architectural pattern as a pattern which recurring a solution to a recurring problem. in most cases, you are able to figure out which classes we have as well as how they will interact with each other to see how they will be implemented in a sequence of systems. usually, an Architectural pattern has the most impact in regard to the code which will then impact the whole application usually horizontally or vertically. 

From the blog Nicholas Dudo by and used with permission of the author. All other rights reserved by the author.

Why are software Frame Works important (12/10/2020)

 As we continue to live out life on earth we as people have to go through trials and tribulations that build from the very basic of things. We also tend to take inventions that have been long in the tooth and retool or re event them. When looking at a software Framework you can consider it to be the same idea or concept. A software framework is considered to be a platform used as a foundation in order to develop different sorts of applications. As well when it comes to software frameworks we are allowed to have a structure or the base program to develop specific programs without having to start from scratch. There two different types of frameworks, opinionated and unopinionated. An opinionated framework is considered to be more of an enforced approach in the sense that the developer is allowed to choose the application structure while the users are able to enforce conventions in regard to the framework itself. while on the other hand, we have an unopinionated framework which is considered to be less strict and considered to be flexible for other less experienced developers to use. Unopinionated is considered to be more simplistic in the sense of not having to have a prescribed method to solve problems while still having flexible tools that could be used to solve problems in a variety of ways. With a framework, you’re allowed a model, view, and controller. A model for a framework is the application for the data. in specific, this focuses on the web application is dealing with a user, video, picture, or comment. The view of a framework on the other hand is considered to be the user interface. You can consider it to be like the computer screen where whenever you make a change the screen will always show the updates or changes that have been made. Then the final piece is the controller where it handles the input such as clicks or different browser inputs. In a sense, you’re allowed to think of a framework as a house where it’s the foundation of the house. frameworks allow you to establish a sense of order to the code when you allow it to give it an application. They can be highly customizable to developers because in the sense it is Skelton code where then you can fill in whatever you want to make the program work for your needs in particular. another piece of the puzzle is that it allows you to integrate libraries which allows having a useful methodology from different sites. 

From the blog Nicholas Dudo by and used with permission of the author. All other rights reserved by the author.

Finding the Pattern in AntiPatterns

For this week, I will be discussing about anti-patterns. I chose to talk about anti-patterns because it relates to one of the topics on our course syllabus, and it seems like it would be good for me to connect and refresh concepts learned in the previous blog posts to anti-patterns; for many of the design patterns and software concepts learned are used to prevent anti-patterns.

To supplement my knowledge on this topic, I watched two youtube videos and read one article on anti-patterns. The first video I watched was a very short video about a developer who introduces the concept, anti-patterns. In the video, he connects anti-patterns to code-smells and basically says that code-smells serve to indicate potential/likely problems in your code, which are the anti-patterns. The second video I chose was lengthier and was by the infamous ‘techlead’, where he satirically talks about his favorite anti-patterns he has seen in his work experience. Although satirical, I was able to decipher why anti-patterns are important to catch and also was able to learn some anti-patterns from his talk. The third source, the article served to list more formal definition and examples of anti-patterns. The article referred anti-patterns as “… a literary form that describes a commonly occurring solution to a problem that generates decidedly negative consequences”. The article also listed examples of anti-patterns that were similar to the ones discussed in the techlead video.

I chose these three sources in that particular order because the intro video helped me better understand the general picture of anti-patterns, whereas the satirical anti-pattern video and the formal anti-pattern article helped to give more depth and understanding of anti-patterns. The satirical anti-pattern video also included real-world examples from an experienced developer which were helpful as well.

From all three sources I was able to consolidate a better understanding of anti-patterns and can see how they connect to previous material learned in my college courses. An important argument that caught me in the techleads videos was the importance of preventing/catching anti-patterns. He explains that antipatterns are dangerous because they are often irreversible and extraordinary hard to refactor once they are embedded into the architecture or code-base, and over time the damage accrues. In addition the anti-pattern article explains that anti-patterns are important to catch early because it may become a bad habit which will repeat itself. Many of the anti-patterns noted both in the anti-pattern video and article, pointed out common code-smells which appeared to be unnecessary-complexity and obscurity; which exemplifies the need for simple and readable code. This is also a common theme noted in the previous blog posts as well. One of the anti-patterns that I can relate to is the over-usage of refactoring, which is explained as bad because it slows-down readability of code during a code-review; yet it is taught extensively in some CS institutions. Overall, this topic made me realize the importance of learning proper usage of software design techniques and concepts in order to prevent anti-patterns in our code.

Sources linked below

https://www.javacodegeeks.com/2011/10/programming-antipatterns.html

From the blog CS@Worcester – Will K Chan by celticcelery and used with permission of the author. All other rights reserved by the author.

REST API Design

Hello everyone and welcome to week 14 of the coding journey blog. In this week’s post I will be talking about REST API and it is an important topic when it comes to the web. REST API stands for representational state transfer and the main purpose of is that is is designed to take advantage of existing protocols. REST has the option to be used on practically any protocol, the main advantage it takes is over HTTP which is used for Web APIs. The main benefit for REST API design is that software developers don’t need to use any additional software or make downloads to take advantage of the protocols. It has a lot of versatility as it allows you to build an API that accustoms your vision and as well as the needs of any clients. There are six key constraints to REST API design that people need to be aware of when deciding to use the API and if it fits your needs. These constraints include client-server, stateless, cache, uniform interface, layered system and code on demand.

The constraint on client server revolves around the idea that the client and the server need to be independent of each other and need to be separate. In essence, developers should be able to make changes to their applications without impacting the data structure or the database design of the server. This goes vice-versa as the developer should also be able to make changes to the data structure or database design server without effecting the application for the client. Next constraint is that REST APIs are stateless and so calls should be independent of one another and that it contains enough data required to complete itself with no errors. It should not rely on data that is stored in the server and should do with the data it is provided in the call. Next constraint is that a REST API should be designed to allow the storage of cacheable data. Essentially, the response needs to indicate that the data can be stored up to certain time limit or in real time it should not be cached by the client.

Uniform interface is the next constraint and it should allow independent upgrades of the application without having the application’s services attached to the API layer itself. This is essential to separate client from sever. A layered system, which is another constraint, is a system composed layers as each layers serves a different purpose or function. This design principle is important in most software as different layers of architecture allows an application that is more scalable. The last constraint is code on demand which allows for code to be transmitted through the API to use within the application. It creates an evolving application that doesn’t only depend on the structure of its own code. Overall, REST APIs are important for web projects and I will certainly use them going forward.

For more information on the topic:

https://www.mulesoft.com/resources/api/what-is-rest-api-design#:~:text=REST%20or%20RESTful%20API%20design,when%20used%20for%20Web%20APIs.&text=REST%20API%20Design%20was%20defined,in%20his%202000%20doctorate%20dissertation.

From the blog CS@Worcester – Roller Coaster Coding Journey by fbaig34 and used with permission of the author. All other rights reserved by the author.

MongoDB in Five Minutes

This week I wanted to look more into MongoDB. I found an introduction video titled “MongoDB in 5 Minutes with Eliot Horowitz” from MongoDB’s YouTube channel to do so. I wanted to learn more about MongoDB because we have been using it a lot in class, but I do not yet have a clear idea of what it is and how it works. I have already taken a relational database course, so I have a clear mental image of what an SQL database is and how it is organized. I know MongoDB is not a relational database but that is the extent of my knowledge.

They start by describing relational databases as excel sheets on steroids, which is a pretty close comparison. They then use an example of a patient record keeping system for a doctor’s office. A patient information table might need multiple phone numbers and addresses, and these columns would end up being mostly empty in a relational database. We might also have the patient’s information spread over many tables, adding complexity. When this database is used in in application it makes the application inefficient and hard to maintain.

MongoDB uses documents and each document can be different. Not all the documents in this case would have to have the same number of phone numbers or addresses. They don’t need the same number of columns like records in a relational database table.

This video is very short and was also created by MongoDB. It is not surprising that they only show one use case where MongoDB is better than relational databases. If relational databases are Excel then MongoDB is kind of like Microsoft Word. It is important to remember that relational databases enforce things like integrity that MongoDB doesn’t, making it better in certain situations. Using multiple tables also isn’t too much of a problem; that is what joins are for. I can definitely see the advantages of using MongoDB now though. The idea of documents is so simple and it is easy to grasp compared to relational databases. This provides a good start to look more into MongoDB. I may have needed this knowledge for the final project, though we won’t have one anymore. I will definitely be using MongoDB in the future though as it is just becoming more and more popular.

From the blog CS@Worcester – Half-Cooked Coding by alexmle1999 and used with permission of the author. All other rights reserved by the author.

Learning JavaScript

As my interest in learning Javascript grows, I have started to try and strategize how I should go about learning it. I have heard of several JavaScript frameworks, so I was wondering if I should start with one like Angular, Vue, Ember, or something, and in my research I found a blog post by Francois-Xavier P. Darveau with a very telling title: Yes, You Should Learn Vanilla JavaScript Before Fancy JS Frameworks. This is a post which details why Darveau believes that learning vanilla JavaScript is so important. He starts with a short story of his time in college in which he started to learn Node.js for a project and rather than quickly find libraries and do some Stack Overflow style copy/pasting to get the project working, he dove in and tried to do everything himself. Although it was time-consuming and arduous and was not exactly optimal, he had learned far more behind the scenes than he would have otherwise. He emphasizes that learning all the shortcuts from frameworks and libraries without knowing the how’s or why’s is more akin to pretending than real knowledge. He then explains the meaning of vanilla JavaScript, if not inferred before, as “plain JS without any additional libraries.” He notes that, of course, frameworks and libraries can be extremely useful and time-saving, a lack of vanilla JS knowledge can leave one helpless if something goes wrong or the field collectively decides to hop over to the next new best framework. Some framework pros and cons are detailed as well. Pros: abstracting hard code, shipping code faster and increasing development velocity, and focusing on an app’s value instead of its implementation. Cons: When work scales up and apps become more complex or multiple teams are working on multiple apps, there will no doubt be times when a deep JS understanding is needed to get everything to go smoothly. If a vanilla JS foundation is strong, the only thing changing when getting into a new framework will be mainly syntax. The speed at which new useful frameworks come out is faster than one can master them on their own, but with a vanilla JS understanding, you can already be a step ahead. He then provides plenty of resources for how to learn JS and where it can be studied. I found this very useful as I hope to learn much more JS soon. I have just done some work with Node.JS in order to implement a new REST API endpoint and I hope to get down JS as it becomes increasingly prominent in the CS world. I am also doing an independent study related to mathematical modeling and linear algebra using MATLAB in the upcoming semester, so maybe there will be an opportunity there to apply my JS knowledge.

From the blog CS@Worcester – Marcos Felipe&#039;s CS Blog by mfelipe98 and used with permission of the author. All other rights reserved by the author.

What is software architecture design?

I. Concept of system architecture

By Edward Crawley, Bruce Cameron, And Daniel Selva co-authored SYSTEM ARCHITECTURE: Strategy and Product Development for Complex Systems. In the book, the word “system” is defined in this way: a system is a set of entities and their relationships, whose functions are greater than the sum of their respective functions.

In other words, the function has to be 1+1>2, which is called emergence. For example, a pile of bricks and wood cannot provide shelter from the wind and rain, but they can form a warm house. The function of the house is greater than the sum of the functions of the pile of materials, so the house is a system.

Now that you know what a system is, let’s look at what a system architecture does:

1) Determine the form and function of the system. To put it bluntly, it’s analyzing requirements.

2) Determine the entities, forms, and functions of the entities in the system. It’s dividing up the system. To accomplish this task, the book proposes some points of attention: identifying potential entities, focusing on important entities, abstracting entities, and defining the boundaries of the system and the environment in which the system resides.

3) Determine the relationship between entities. This includes identifying relationships between internal entities and entities located at boundaries and defining the form and function of those relationships. That is to define internal and external interfaces.

4) Forecast emergence. The prediction of final function realization, performance realization, and also the prediction of system failure, is the emergence of non-expectations.

II. The book also explains the architect’s function from another perspective:

1) Disambiguation. That is, the architecture is designed so that you don’t have a vague understanding of the requirements.

2) Define the system concept. Put forward the overall solution, define the key terms in the system, define the key measurement criteria.

3) Design decomposition. The key to breaking down the system into entities and the relationships between entities is to control the complexity of the system and not overscale it.

It can be seen that the system architecture is a step between the requirements and the implementation, which not only analyzes the requirements but also proposes a feasible implementation scheme.

The system architecture is suitable for a team composed of one or a few people because many people will lead to insufficient integrity of thinking. If multiple people work together, the best form is also to divide up the hierarchy, with a hierarchy of units to be completed by a single person. This requires a high level of knowledge, synthesis, analysis, and imagination on the part of the architect.

Sources:

Click to access Preface.pdf

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