CSCI-462 SOFTWARE ENGINEERING BLOG
1.13.21 - Introduction
Hello World! Thank you for visiting my blog. I will use this space to discuss my experiences in Dr. Jim Bowring's
sofware engineering course. This is my final semester at the College of Charleston. I am studying Computer Information Systems and hope to
work in either the software industry or in renewable energy in some facet. This semester I am going to complete a project with several other
classmates working with open source software. My teamates are Bradley Odac, Patrick McCabe, and Cormac Conahan. Our group is using the name of
"The Open Source Mafia."
1.20.21 - Reflections on FOSS
In “The Cathedral and the Bazaar” Eric Raymond reflects on Linux, open source software design, and his own projects. Raymond walks us through
his lessons for creating good open source software. The essay is an interesting read with insights into software development. It really gets
you thinking about the benefits of inclusivity with product design and development. People seeking out bugs to fix and features to add produce
better code than those doing it for work.
Raymond lists 19 lessons throughout the essay all of which could have their own summary but I’m just going to touch on a few(in non particular order)
1) "Every good work of software starts by scratching a developer's personal itch."
A motivated developer is a good developer. If the problem is something personal and interferes with the way a developer can use the software
it is much more motivating. Imagine if your favorite game, sport statistic page, or tinder didn’t work properly. People will work hard to personally
benefit from bug fixing.
2) "Good programmers know what to write. Great ones know what to rewrite."
This is an example of the old expression “if it aint broke, don’t fix it.” When writing open source code you are provided
with a foundation to build upon. There is no need to go in and destroy someone elses product to build yours over. Take what
they have and use it to develop what you envision. Waste as little as possible.
3)"Treating your users as co-developers is your least-hassle route to rapid code improvement and effective debugging."/"Given a large enough beta-tester
and co-developer base, almost every problem will be characterized quickly and the fix obvious to someone."
I grouped these ones together because its really the essence of the essay in my opinion. When people use your software they are going to explore areas
you could never have thought of. They are going to find bugs. Lucky for you they are developers! Rapid code improvements will happen which will lead to
less deep structural bugs. Your code is constantly exposed and getting improved. Embrace your users and especially your beta testers!
The Bazaar approach to open source software design seems radical and chaotic but in reality the incessant updates and iterations allow it to be more
streamlined in development. The code is more efficient and of higher quality because the people writing it are building on the work of others. A communal
herd of developers proves more effective than the specialized Cathedral builder. While the team of Cathedral builders may be the most highly skilled they
can not do the work the herd can.
“...given enough eyeballs, all bugs are shallow.”
1.27.21 - Reflections On Open Source In Today's World
Open Source in devOpsOne key way to keep devOps teams fully functional during this unprecedented time is by applying open source principles. This is not a new or novel concept but rather something that needs to be stressed during the pandemic. Some team members may be working from home for the first time while others have done it plenty of times. The key is to remain a cohesive unit. There are two types of devOps teams, those that are hybrid and those that are fully remote. Each type has their own unique problems and advantages. A fully remote team can be more agile because they may be working in different time zones allowing them to take advantage of different delivery cycles. This could also pose a problem because they may not be able to meet as easily. A hybrid team may still have to attend useless meetings and struggle with deciding who works from home and who does not.
DevOps vs AgileAgile and devOps are distinct, even though people think they are one in the same because of their many similarities. The two software development models are not adversaires, they are just different schools of thought. Agile was officially started 20 years ago, after the release of the agile manifesto. Previously, most software development was some form of the waterfall model. The waterfall model was a linear track to development that worked well in manufacturing and engineering but was not the most effective method for software development.
2.4.21 - This bugs me
GitHubs issues is the bug tracker for sugar labs Sugarlabs, like many other current FOSS use the “issues” function of Github to track their bugs.
Developers and users alike are free to report issues as well as feature suggestions and work on them. It seems that most bugs get attention relatively
quickly, especially on the more active modules. While looking through the bug reports I was able to spot a few developers who were actively reporting
bugs and responding to others reports. The most notable is a developer named “quozi”, but there are others who contribute consistently as well.
The oldest bug I was able to find was from late 2016. It seems that their was a real effort to find bugs by one developer in April 2017. In 3 days they opened
~7 new bug reports on various
modules.
For the sake of this exercise I tried to focus on bugs that were in modules we had considered working on such as pippy, calculate, paint etc.
The bugs I chose include:
An svg rendering different colors on different systems
Error with bouncing objects in the pysics activiy
A feature request for stats at the end of memorize activity
Pressing up arrow in chat
Sound button not working
2.11.21 - What's Happening
This article was written by a collective of 6 computer scientists. This article is focused on the disconnect between modern
computer science research and modern mobile computing. The article also poses several challenges to mobile software
engineers and up and coming students.
Mobile apps are being created daily and some are extremely creative and complex. With the rise of Iot and edge computing it
is more important than ever to think about the mobile environment. By taking steps now, we can ensure the best growth for
the mobile environment in the future.
Modern apps interact with physical entities inside and outside the phone, as well as integrating diverse services in the cloud.
Apps have to navigate through poor connectivity, sensor inaccuracies, low battery levels and much more. This creates a huge
challenge as users expect apps to always be functional and operating.
End users want a seamless experience in their home, at work, and out and about. This “Always On” mentality is difficult for software
engineers to deal with. We must practice defensive programming and expect that the worst will always happen when designing applications.
Cyber foraging is the concept of mobile devices offloading computing to other “surrogate” machines in the vicinity. With the amount of data
that modern apps are using it is increasingly important to find ways to divy up work. Instead of your smartphone using all of its
processing power other devices can pick up the slack. It is important that we figure out how to properly place data and computation
closer to mobile devices and tablets. Cloud based systems will need to push work to their surrogates and devices should automatically
locate these proxies.
Android has been the focus of the majority of mobile software research. Largely because 88% of all smartphones run on it and largely
because it is an open source project. This makes it easy for them to customize their own solutions and research. Because Android
has been an open source project from the beginning there are many data analysis tools available which makes conducting research
easier as well. However, this has made research stagnant and researchers have not dug into other cross platforms like Kotlin and
React Native. The majority of research has also been higher level and needs to focus more on specific problems and challenges.
Iot, wearables, and smartphones are going to be some of the most important areas of software development for years to come. Devices are
going to get more and more complex and connected until computing is a seamless process between all connected devices. To achieve
this there needs to be a concerted effort by software developers to bring this about. Research needs to be introduced into industry.
Specific challenges need to be addressed and those solutions must be implemented
2.17.21 - STUPID or SOLID
Software development is a generally fluid concept without solid rules or rights and wrongs. In most cases if it works, it works
. As long as the desired outcome is achieved all is well. However, this article presents the idea of going from STUPID code to SOLID code.
S - (Singleton Pattern) - using a global variable in your code is a dangeround process that requires special attention at all times.
These patterns should only be used when there are no other options.
T - (Tight Coupling) - This can be a symptom of using Singleton patterns. If making a change in a specific module requires changing
in another this is coupling. This creates redundancy that will lead to re-writing code.
U - (Untestability) - Testing is absolutely mandatory and when writing code you should be thinking of how you are going to test while
you write it. If you having a tough time writing unit tests for your code that is a sign of bad code and often happens from tight coupling mentioned above.
P - (Premature Optimization) - Think twice when attempting to optimize code. You may be tempted to try and tweak an algorithm here and
there to run more efficiently. Though this may save you tiny bits of time it may require adjusting much more than you think. Its
often unnecessary to try and optimize working code.
I - (Indescreptive Naming) - Pretty descriptive title. Make your variable names, methods and classes have descriptive names that
relate to what they do. This helps others understand your code better.
D - (Duplication) - Don’t repeat yourself. Write methods and classes that work across applications that way you don’t have to
write and rewrite code.
As you can see these are not strict rules that a developer can follow. Rather, it is a set of instructions to keep in mind while working.
Many of these problems are interrelated and lead to other issues. These issues are evidenced even more when trying to scale. Code smart to save yourself down the line.
S - (Single Responsibility Issue) - Classes should only have one responsibility. Just because you can make a single class do numerous different
things doesnt mean it's a good idea. There should never be more than one reason for a class to change.
O - (Open/Closed Principle) - Variable types should be made variable by default. Getters and setters can be written where needed.
L - (Liskov Substitution Principle) - Subtypes of objects should be able to replace objects. It should not require a change of code to make a
sub type an object.
I - (Interface Segregation Principle) - Interfaces should serve direct client needs. You should not try and create an all encompassing interface.
Tailor these interfaces to specific needs.
D - (Dependency Inversion Principle) - Abstractions should not depend upon details rather details should depend upon abstractions. Refrain from adding
concrete classes to method signatures of an interface.
Although application of some of these concepts is currently beyond the scope of my knowledge, it was still interesting and helpful to lean these
principles. If I can remember to use these as a guideline it will help my development abilities in the future.
3.10.21 - RELEASE EARLY and RELEASE OFTEN
During all of these readings it became clear that there are well established guidelines on how to support software through documentation.
Documentation is a vital lifeline of software development, not only to users but developers as well. Documentation generally falls into
one of two categories, user or developer. It doesn't matter who you are writing the documentation for there are some key structural characteristics:
Oranization, Illustration, Style, and Tone
“Help”
tab is hosted on the application. With regard to
FOSS products I
assume most have documentation in .pdf and hosted on their github. Bigger projects may have hard copies of documentation for their users.
This is found more in proprietary software however. Make sure your user manuals and especially tutorials have illustrations. Keep your text to a
minimum where possible. Huge blocks of text can give users anxiety. Use literal language that won't confuse users. Avoid humor and metaphors.
Also, keep in mind that some users may not be native english speakers. Avoid adding unnecessary words and phrases.
Simplify the process to the point of redundancy and then simplify it more.
Good documentation will onboard new users to your product and give experienced users the tools to maximize the software.
3.18.21 - Chapter 5 - Domain Classes
A fundamental part of software development is testing. Without appropriate testing software will not be able to fulfill its capabilities
and will cause problems for users and developers. There are many components to software testing including unit testing, integration testing,
and using software metric guidelines.
Oftentimes when developing software you work with an existing codebase known as legacy code. These legacy codebases are usually divided
into large classes known as domain classes. Domain classes generally evolve through numerous iterations during their lifetime. However,
there are usually similarities between all the domain classes. It is standard practice to have testing that is specifically focused on each
domain class. These tests are known as unit tests.
Unit tests allow for a software to be tested via a test suite that tests each individual domain class as part of a larger whole. A unit test
can not succeed in two different ways, an assertion in the code that is not confirmed is called a “failure”, or if the code itself experience
s a runtime error this is a “bug.” When unit testing it’s important to test the all instance variables, getter methods, and their different
functionality.
After unit testing each domain class of the software it is important to test how the different domain classes interact with each other,
this is known as integration testing. Before integration testing, make sure the respective classes and modules have been tested separately,
all tests have been merged into the codebase, and that the new code has been pulled into the developers own copies of the code base.
No matter who writes code and how well it is written, you will run into bugs in the software. Luckily with open source projects you have users
that oftentimes are capable of helping with the workload. Whether that be through debugging, refactoring code, or even writing documentation.
Users are the first line of defense because just by using the product they will subert the software to situations that you did not test. It is
nearly impossible to test all use cases and edge cases specifically. Without knowing it users will be stress testing the software all the time.
Even if your software is performing as expected and does not seem to have any existing bugs there could still be work to do. Refactoring is
the process of changing how existing software is written to make it more concise or functional. These changes are not designed to affect the
external processes of the software being refactored. Some reasons for refactoring include poorly named variables and functions, duplicate code,
functions or classes that are too long, and poorly commented code.
While this may seem like a very strenuous process there are some tools to help you. Generally whatever language you are coding in has tools to
build unit and integration tests. GitHub is a great resource for exposing your project to a wide array of users as well as providing excellent
version control. There are also several metrics you can use to judge your software. These include count metrics, clarity metrics, cohesion metrics,
and coupling metrics. All of these are pretty standardized and give you an idea of how well written your code is.
3.25.21 - Chapter 6 - Database Modules
When most people think of software engineering they think of linked lists, arrays, for loops, and if/else statements. Databases often get ignored
because they may be seen as less exciting to a lot of developers. Databases are essential systems to the storage and retrieval of information.
Databases are the backbone of most software applications and differ from a domain class or object because its data remains in permanent memory
, separate from the memory where the program runs. Oftentimes data will be stored as part of a server. Databases are unique because their lifetime
often lasts longer than the program its associated with, this is known as persistence.
Databases can be broken into several different models such as the “relational model” and the “non relational model.” Relational models of
databases store data as a collection of two-dimensional tables. This is convenient because they can be accessed easily and efficiently by SQL.
The Structured Query Language(SQL) is a widely used almost exclusive database modeling language. SQL is generally based on relational algebra and
matrices.
Manipulating data in SQL is generally accomplished through queries. Although this seems like an obvious term for retrieving data, it is also
the term used to insert, update, or delete data. Some common queries include CREATE TABLE - to create a table in a database, DROP TABLE - to remove
a database, SELECT * FROM - to return data based on certain conditions stated, INSERT INTO - to insert new data into a table, DELETE FROM - to delete
rows from a table, and UPDATE - to change data values in the table.
A main strategy in database design is normalization. This strategy is in place so that tables can support queries and ensure data integrity but
eliminating data redundancy. A relational database can be considered “normatlized” if it meets all of the following:
1) The rows can be rearranged without changing the meaning of the table (i.e., there’s no implicit ordering or functional interdependency
among the rows).
2) The columns (attributes) can be rearranged without changing the mean- ing of the table (i.e., there’s no implicit ordering or functional
interde- pendency among the columns).
3) No two rows of a table are identical. This is often accomplished by defining one column whose values are mutually unique. This
column is known as the table’s primary key.
4) No row has any hidden components, such as an object id or a timestamp.
5) Every entry in the table has exactly one value of the appropriate type.
6) No attribute in the table is redundant with (i.e., appears as an explicit substring of) the primary key.
Security plays a huge role in database design. To ensure security, tables should be limited to who can access and perform different queries.
This is called designating privilege. Many developers also implement encryption to secure their data. Overall, databases are an extremely
important part of software engineering and is often the heart of any application.
3.30.21 - Chapter 7 - User Interface Dev
The user interface of a software application is where the code meets the client. UI represents the glue holding all other components
together. This isnt just true for code but the whole development process hinges on the UI. When speaking with a client they are going
to want to know about the functionality, bugs, and new features relating to the user interface.
The book outlines several principles to facilitate a “good user interface.”
1. Task-Oriented There is a clear mapping between the steps of each use case in the design document and a page or group of related
pages in the user interface.
2. Language The language of the interface must be consistent with the lan- guage of the domain and the user. All labels
and user options that appear on individual pages must be consistent with their counterparts in the design document and the domain classes.
3. Simplicity No page should contain too much information or too little. Each page should be pleasant to view, yet its functionality
should not be buried by elaborate stylistics.
4. Navigability Navigation within a page and between related pages should be simple, explicit, and intuitive.
5. Visual consistency All pages in the user interface should have a similar look and navigation style.
6. Discoverability Each page should provide the user with clear feedback on what has just been done, what can be done next, how to do
it, and how to undo it.
7. Data integrity The types and valid values for individual user data entries must be clearly indicated. The software should
validity-check all data at the time of entry and the user should be required to correct errors before the entries are saved in the database.
8. Client-server integrity The activities of several different users who hap- pen to be using the system at the same time must be kept separate
and independent.
9. Security An individual user should have access to the system’s function- ality, but only that functionality for which he/she is authorized.
10. Documentation Every page or group of pages in the user interface should be linked to a step-by-step instruction that teaches a user how
that page can be used to accomplish a task.
Because the user interface has a multitude of different elements there has been a widely used strategy called the “model-view-controller” pattern.
The MVC pattern separates code into three different pieces: The model - code that underlies the application’s logic and underlying data, The view
- code that presents the components of the interface to the user, and The controller - code that controls the user’s input, output, and
navigational functionality for that component.
The MVC pattern encourages independent coding, testing, and maintenance of each component. This layered architecture encapsulates the
database and domain layers, while the code in the view and controller is encapsulated within the user interface layer.
4.1.21 - Meeting Charleston
The alumni symposium was very informative and interesting. It’s always nice hearing from people who have been in the situation us
students are. Graduating is an exciting, nerve wracking, and confusing time. A lot of people may be searching for jobs, figuring out where
they want to live, and the next step in their life.
It’s especially nice hearing about the day in day out life of some of our alumni. Its great for perspective and knowing what to expect.
Some of the knowledge passed on I will remember for a long time. I really appreciate these alumni taking time out of their daily lives
to speak with us.