Jerry Yoakum's thoughts on software engineering and architecture from experience working with code, computer science, python, java, APIs, NASA, data mining, math, etc.
Thursday, December 06, 2018
Avoid Global Variables
Global variables make it convenient to write programs; after all, if you need to access or change x, you just do it. Unfortunately, if x is ever accessed and found to have an inappropriate value, it is difficult to determine which software component is at fault. "Global" implies that anybody could have altered its value incorrectly.
As an alternative, encapsulate important data in its own module, so that anybody who wants to change it or access it must do so by means of that routine. Alternatively, explicitly pass parameters to routines that need specific data. If you find an excessive number of parameters, perhaps your design needs to be reworked.
Reference:
Ledgard, H., Programming Practice, Vol II, Reading, MA: Addison-Wesley, 1987.
Labels:
coder,
development,
software-engineering
Location:
Springfield, MO, USA
Wednesday, December 05, 2018
Avoid Tricks
Many programmers love to create programs with tricks. These are constructs that perform a function correctly, but in a particularly obscure manner. Typically, they use a side-effect of a function to implement a primary function. Programmers see these as "clever," but, as Allen Macro points out, they "are often merely the stupid use of high intelligence."
There are many ways to explain why tricks are used so often:
- Programmers are extremely intelligent and want to demonstrate that intelligence.
- Maintainers, when they finally figure out how the trick works, will not only recognize how smart the original programmer was, but also will realize how smart they themselves are.
- Job security.
Bottom line: Show the world how smart you are by avoiding tricky code!
Reference:
Macro, A., Software Engineering: Concepts and Management, Englewood Cliffs, NJ: Prentice-Hall International, 1990.
Labels:
coder,
development,
software-engineering
Location:
Springfield, MO, USA
Tuesday, December 04, 2018
Software Reliability Can Be Achieved Through Redundancy
In hardware systems, high reliability or availability (Specify Reliability Specifically) is often achieved through redundancy. Thus, if a system component is expected to exhibit a mean-time-between-failures of x, we can manufacture two or three such components and run them in either:
- Parallel. For example, they all do all the work and, when their responses differ, one is turned off with no impact on overall system functionality.
- Or cold standby. A backup computer might be powered on only when a hardware failure is detected in the operational computer.
Manufacturing cost is slightly more than doubled. Design cost increases slightly. Reliability increases exponentially.
In software systems, we cannot use the same approach. If we make two copies of the same software, no increase in reliability will be achieved. In one fails, the other will as well. What can be done, however, is to design (using two different design teams) two versions of the software from the same requirements specification, and deploy them in parallel. Development cost doubles. Reliability increases exponentially. Notice that, in the case of hardware, design increases in cost only slightly, whereas software design cost (the primary cost of software) doubles. Ultrahigh reliability in software is very expensive (High Quality Software Is Possible).
Reference:
Musa, J., et al., Software Reliability, New York: McGraw Hill, 1987.
Labels:
architecture,
design,
software-engineering
Location:
Springfield, MO, USA
Monday, December 03, 2018
"Garbage In, Garbage Out" Is Incorrect
Many people quote the expression "garbage in, garbage out" as if it were acceptable for software to behave like this. It is not. If a user provides invalid input data, the program should respond with an intelligent message that describes why the input was invalid. If a software component receives invalid data, it should not process it, but instead should return an error code back to the component that transmitted the invalid data. This mindset helps diminish the domino effect caused by software faults and makes it easier to determine error causes by 1) catching the fault early and 2) preventing subsequent data corruption.
Reference:
McConnell, S., Code Complete, Redmond, WA: Microsoft Press, 1993.
Labels:
design,
software-engineering
Location:
Springfield, MO, USA
Saturday, December 01, 2018
Imposter Syndrome
All fields have some amount of imposter syndrome. It happens in Software Engineering a lot. Constantly changing technologies and changing projects can catch a person off-guard and overwhelm them. Often the problem is only in your head. You actually are doing fine, or would be if you gave yourself a chance. Peter J. Denning wrote an excellent article about this called The Beginner's Creed. The creed is all about learning to be expert beginners so new technologies and projects don't overwhelm us.
Thursday, November 29, 2018
You Can Reuse Without A Big Investment
When salvaging you got to be the tug that pulls what you need to the surface. |
The most effective way to reuse software components is from a repository of crafted, handpicked libraries that were tailored specifically for reuse. However, this requires considerable investment in both time and money. It is possible to reuse in the short term through a technique called salvaging.
Salvaging is asking others in your organization if they have built a software component that does X. You find it, you adapt it, you employ it. This may not be efficient in the long term, but it certainly works now; and then you have no more excuses not to reuse.
To my experience, few organizations are willing to allocate time for the proper care and upkeep of a repository of reusable software components. Salvaging might be your only option. And it gets you talking to your peers on different teams. This communication is like grease that will make future interactions smoother.
Labels:
design,
software-engineering
Location:
Springfield, MO, USA
Wednesday, November 28, 2018
Know Your Application
No matter how well the requirements have been written, the selection of optimal architectures and algorithms is very much a function of knowing the unique characteristics of an application. Expected behavior under stress situations, expected frequency of inputs, life-critical nature of response times, likelihood of new hardware, impact of weather on expected system performance, and so on are all application-specific and often demand a specific subset of possible alternative architectures and algorithms.
Reference:
Curtis, B., et al, "A Field Study of the Software Design Process for Large Systems," CACM, November 1988.
Labels:
design,
Seattle,
software-engineering
Location:
Seattle, WA, USA
Tuesday, November 27, 2018
Store Requirements in a Database
Keep in mind that the follow quote is from 1995. It is still completely relevant.
Requirements are complex and highly volatile. For these reasons, storing them in electronic media, preferably a database, is a good idea. This will facilitate making changes, finding implications of changes, recording attributes of specific requirements, and so on.I have used JIRA. There are many tools like it. They can do all of the above, but it is up to the person creating a ticket in JIRA to ensure those things are done. I think they are really important so I'm going to list them again.
Some of the things you want to store in the database are unique identifier (Separately Number Every Requirement), the text of the requirement, its relationship to other requirements (such as more abstract or more detailed descriptions of the requirement), importance (Prioritize Requirements), expected volatility, pointers to its sources (Record Why Requirements Were Included), applicable product versions (Identify Subsets and Give Every Intermediate Product a Name and Version*), and so on. Ideally, the requirements specification itself is nothing but an organized "dump" of the entire database.
- Create the ticket in a backlog or project that is unique. Do not lump unrelated tickets together. This will result in a "fatlog" - a fat backlog that is difficult to groom and manage.
- The text of the requirement goes in the "description". The "summary" is not where the requirement should be detailed. Personally, I think systems like JIRA should not allow tickets that have no description to be saved. Engineers should refuse to estimate such tickets and Product Owners who create them should be ashamed.
- JIRA has a feature to link tickets. Use it. If there is a dependency then utilize the sub-task feature. Make a story that encapsulates both tickets and make them linked sub-tasks. Use the system to track if everything for that requirement is actually done.
- Order the tickets by importance. There can only be one highest priority and it at the top.
- Use comments to document the sources/stakeholders for a ticket. Do not use comments to have a discussion about a ticket. Email, call, instance message, etc with the people involved. If you absolutely must use the comments section of a ticket to have a discussion then clean it up later. Delete anything that will mislead people reading the ticket. If you want to save the history then move that stuff into a document and attach it to the ticket with a title that makes it clear that it is for history and it is not the requirement. The actual requirement is in the description.
- Ensure that you put what product the ticket applies to either in the summary or the description. You might be inclined to think that it is clear by where the ticket sits. For example, the ticket is in the product A backlog. Invariability, someone is going to get confused and try to work that ticket for product C which is really similar to product A. I've also seen people accidentally move a ticket to a different backlog then not be able to figure out where it belonged.
- If you can't take the issues in a JIRA backlog and print them out in order and call that your software requirements specification (SRS) then your backlog is a mess and you have some work todo.
6 Tips to Make Your Backlog Lean
Labels:
coder,
development,
requirements,
software-engineering
Location:
Springfield, MO, USA
Monday, November 26, 2018
Self-Destruct TBDs
A software requirements specification (SRS) with a TODO or TBD (To Be Determined) note is obviously not complete. There may be good reasons for approving and starting work on a project with a TBDs in the specification. This is particularly true for requirements whose precision are not critical to fundamental design decisions.
When you create a TBD, be sure to footnote it with a "self-destruction note," that is, specify who will resolve the TBD and by when.
Reference:
IEEE, ANSI/IEEE Guide to Software Requirements Specifications, IEEE Computer Society Press, Washington, DC, 1994.
Labels:
coder,
development,
requirements,
software-engineering
Location:
Springfield, MO, USA
Saturday, November 24, 2018
Specify When Environment Violates "Acceptable" Behavior
Requirements specifications often define characteristics of the system's environment. This information is used in making intelligent design decisions. It also often implies that the developer is contractually obligated to accommodate such characteristics. What happens after deployment when the environment exceeds the specified limits?
Suppose the requirements for an air traffic controller system specify that the system shall handle up to 100 aircraft in a sector simultaneously. They system is built and correctly satisfies this requirement. Three years later 101 aircraft accidentally enter a sector. What should the software do? The possibilities are:
- Print an error message.
- Crash.
- Ignore the 101st aircraft.
- Process all 101 aircraft but perhaps not satisfy some other timing constraint (such as how often the screen is updated).
Reference:
Davis, A., Software Requirements: Objects, Functions, and States, Prentice Hall, Englewood Cliffs, 1993.
Labels:
requirements,
Seattle,
software-engineering
Location:
Seattle, WA, USA
Subscribe to:
Posts (Atom)