Event Driven ProgrammingChapter 1
Event Driven ProgrammingChapter 1
--------------------------------------------------------------------------------------------------------------------------------------
Chapter 1: Introduction
Software development requires careful planning and execution to meet the goals. Sometimes a developer must react
quickly and aggressively to meet every changing market demands. Maintaining software quality hinders fast-paced
software development, as many testing cycles are necessary to ensure quality products.
Each software development project has to go through at least the following stages:
In this stage, marketing and sales people or people who have direct contact with the customers do most of the
work. These people talk to these customers and try to understand what they need. A comprehensive
understanding of the customers‘ needs and writing down features of the proposed software product are the keys
to success in this phase. This phase is actually a base for the whole development effort. If the base is not laid
correctly, the product will not find a place in the market. If you develop a very good software product which is
not required in the market, it does not matter how well you build it. You can find many stories about software
products that failed in the market because the customers did not require them. The marketing people usually
create a Marketing Requirement Document or MRD that contains formal data representation of market data
gathered.
Spend some time doing market research and analysis. Consider your competitors‘ products (if any), a process
called competitive analysis. List the features required by the product. You should also think about the
economics of software creation at this point. Is there a market? Can I make money? Will the revenue justify the
cost of development?
Functional specifications may consist of one or more documents. Functional specification documents show the
behavior or functionality of a software product on an abstract level. Assuming the product is a black box, the
functional specifications define its input/output behavior.
Functional specifications are based upon the product requirements documentation put forward by people who
have contact with the end user of the product or the customers.
In larger products, functional specifications may consist of separate documents for each feature of the product.
For example, in a router product, you may have a functional specification document for RIP (Routing
Information Protocol), another for security features, and so on.
Functional specifications are important because developers use them to create design documents. The
documentation people also use them when they create manuals for end users. If different groups are working in
different physical places, functional specifications and architecture documents (discussed next) are also a means
to communicate among them. Keep in mind that sometimes during the product development phase you may
need to amend functional specifications keeping in view new marketing requirements.
When you have all of the requirements collected and arranged, it is the turn of the technical architecture team,
consisting of highly qualified technical specialists, to create the architecture of the product. The architecture
defines different components of the product and how they interact with each other. In many cases the
architecture also defines the technologies used to build the product. While creating the architecture documents
of the project, the team also needs to consider the timelines of the project. This refers to the target date when the
product is required to be on the market. Many excellent products fail because they are either too early or late to
market. The marketing and sales people usually decide a suitable time frame to bring the product to market.
Based on the timeline, the architecture team may drop some features of the product if it is not possible to bring
the full-featured product to market within the required time limits.
Once components of the product have been decided and their functionality defined, interfaces are designed for
these components to work together. In most cases, no component works in isolation; each one has to coordinate
2
with other components of the product. Interfaces are the rules and regulations that define how these components
will interact with each other. There may be major problems down the road if these interfaces are not designed
properly and in a detailed way. Different people will work on different components of any large software
development project and if they don‘t fully understand how a particular component will communicate with
others, integration becomes a major problem.
For some products, new hardware is also required to make use of technology advancements. The architects of
the product also need to consider this aspect of the product. After defining architecture, software components
and their interfaces, the next phase of development is the creation of design documents. At the architecture
level, a component is defined as a black box that provides certain functionality. At the design documents stage,
you have to define what is in that black box. Senior software developers usually create design documents and
these documents define individual software components to the level of functions and procedures. The design
document is the last document completed before development of the software begins. These design documents
are passed on to software developers and they start coding. Architecture documents and MRDs typically need to
stay in sync, as sales and marketing will work from MRDs while engineering works from engineering
documents.
The software developers take the design documents and development tools (editors, compilers, debuggers etc.)
and start writing software. This is usually the longest phase in the product life cycle. Each developer has to
write his/her own code and collaborate with other developers to make sure that different components can
interoperate with each other. A revision control system such as CVS (Concurrent Versions System) is needed in
this phase. There are a few other open source revision control systems as well as commercial options. The
version control system provides a central repository to store individual files. A typical software project may
contain anywhere from hundreds to thousands of files. In large and complex projects, someone also needs to
decide directory hierarchy so that files are stored in appropriate locations. During the development cycle,
multiple persons may modify files. If everyone is not following the rules, this may easily break the whole
compilation and building process. For example, duplicate definitions of the same variables may cause problems.
Similarly, if included files are not written properly, you can easily cause the creation of loops. Other problems
pop up when multiple files are included in a single file with conflicting definitions of variables and functions.
Coding guidelines should also be defined by architects or senior software developers. For example, if software
is intended to be ported to some other platform as well, it should be written on a standard like ANSI.
3
During the implementation process, developers must write enough comments inside the code so that if anybody
starts working on the code later on, he/she is able to understand what has already been written. Writing good
comments is very important as all other documents, no matter how good they are, will be lost eventually. Ten
years after the initial work, you may find only that information which is present inside the code in the form of
comments.
Development tools also play an important role in this phase of the project. Good development tools save a lot of
time for the developers, as well as saving money in terms of improved productivity. The most important
development tools for time saving are editors and debuggers. A good editor helps a developer to write code
quickly. A good debugger helps make the written code operational in a short period of time. Before starting the
coding process, you should spend some time choosing good development tools.
Review meetings during the development phase also prove helpful. Potential problems are caught earlier in the
development. These meeting are also helpful to keep track of whether the product is on time or if more effort is
needed complete it in the required time frame. Sometimes you may also need to make some changes in the
design of some components because of new requirements from the marketing and sales people. Review
meetings are a great tool to convey these new requirements. Again, architecture documents and MRDs are kept
in sync with any changes/problems encountered during development.
Testing is probably the most important phase for long-term support as well as for the reputation of the company.
If you don‘t control the quality of the software, it will not be able to compete with other products on the market.
If software crashes at the customer site, your customer loses productivity as well money and you lose
credibility. Sometimes these losses are huge.
Unhappy customers will not buy your other products and will not refer other customers to you.
You can avoid this situation by doing extensive testing. This testing is referred to as Quality Assurance, or QA,
in most of the software world.
Usually testing starts as soon as the initial parts of the software available. There are multiple types of testing and
these are explained in this section. Each of these has its own importance.
5.1.Unit Testing
Unit testing is testing one part or one component of the product. The developer usually does this when he/she
has completed writing code for that part of the product. This makes sure that the component is doing what it is
4
intended to do. This also saves a lot of time for software testers as well as developers by eliminating many
cycles of software being passed back and forth between the developer and the tester.
When a developer is confident that a particular part of the software is ready, he/she can write test cases to test
functionality of this part of the software. The component is then forwarded to the software testing people who
run test cases to make sure that the unit is working properly.
5.2.Sanity Testing
Sanity testing is a very basic check to see if all software components compile with each other without a
problem. This is just to make sure that developers have not defined conflicting or multiple functions or global
variable definitions.
Regression or stress testing is a process done in some projects to carry out a test for a longer period of time.
This type of testing is used to determine behavior of a product when used continuously over a period of time. It
can reveal some bugs in software related to memory leakage. In some cases developers allocate memory but
forget to release it. This problem is known as memory leakage. When a test is conducted for many days or
weeks, this problem results in allocation of all of the available memory until no memory is left. This is the point
where your software starts showing abnormal behavior. Another potential problem in long-term operation is
counter overflow. This occurs when you increment a counter but forget to decrement, it resulting in an overflow
when the product is used for longer periods.
The regression testing may be started as soon as some components are ready. This testing process requires a
very long period of time by its very nature. The process should be continued as more components of the product
are integrated. The integration process and communication through interfaces may create new bugs in the code.
5.4.Functional Testing
Functional testing is carried out to make sure that the software is doing exactly what it is supposed to do. This
type of testing is a must before any software is released to customers. Functional testing is done by people
whose primary job is software testing, not the developers themselves. In small software projects where a
company can‘t afford dedicated testers, other developers may do functional testing also. The key point to keep
in mind is that the person who wrote a software component should not be the person who tested it. A developer
will tend to test the software the way he/she has written it. He/she may easily miss any problems in the
software.
5
The software testers need to prepare a testing plan for each component of the software. A testing plan consists
of test cases that are run on the software. The software tester can prepare these test cases using functional
specifications documents. The tester may also get help from the developer to create test cases. Each test case
should include methodology used for testing and expected results.
In addition to test cases, the tester may also need to create a certain infrastructure or environment to test the
functionality of a piece of code. For example, you may simulate a network to test routing algorithms that may
be part of a routing product.
The next important job of the tester is to create a service request if an anomaly is found. The tester should
include as much information in the service request as possible. Typical information included in reporting bugs
includes:
The service request should be forwarded to the developer so that the developer may correct the problem.
Many software packages are available in the market to track bugs and fix problems in software. There are
many web-based tools as well. For a list of freely available open source projects, go to http://www.osdn.org
or http://www.sourceforge.net and search for ―bug track‖. OSDN (Open Source Developers Network) hosts
many open source software development projects.
6. Software release
Before you start selling any software product, it is officially released. This means that you create a state of
the software in your repository, make sure that it has been tested for functionality and freeze the code. A
version number is assigned to release software. After releasing the software, development may continue but
it will not make any change in the released software.
The development is usually carried on in a new branch and it may contain new features of the product. The
released software is updated only if a bug fixed version is released.
Usually companies assign incremental version numbers following some scheme when the next release of the
software is sent to market. The change in version number depends on whether the new software contains a
major change to the previous version or it contains bug fixes and enhancement to existing functionality.
Releases are also important because they are typically compiled versions of a particular version of the code,
and thus provide a stable set of binaries for testing.
6
6.1.Branches
In almost all serious software development projects, a revision or version control system is used. This
version control system keeps a record of changes in source code files and is usually built in a tree-like
structure. When software is released, the state of each file that is part of the release should be recorded.
Future developments are made by creating branches to this state.
Sometimes special branches may also be created that are solely used for bug fixing.
6.2.Release Notes
Every software version contains release notes. These release notes are prepared by people releasing the
software version with the help of developers. Release notes show what happened in this software version.
Typically the information includes:
Typically a user should be given enough information to understand the new release enhancements and decide
whether an upgrade is required or not.
7. Documentation
There are three broad categories of documentation related to software development processes:
1. Technical documentation developed during the development process. This includes architecture, functional
and design documents.
2. Technical documentation prepared for technical support staff. This includes technical manuals that support
staff use to provide customer support.
3. End-user manuals and guides. This is the documentation for the end user to assist the user getting started
with the product and using it.
All three types of documents are necessary for different aspects of product support. Technical documents are
necessary for future development, bug fixes, and adding new features. Technical documentation for technical
support staff contains information that is too complicated for the end user to understand and use. The support
staff needs this information in addition to user manuals to better support customers. Finally each product
must contain user manuals.
7
Technical writers usually develop user manuals which are based on functional specifications. In the timelines
of most software development projects, functional specifications are prepared before code development
starts. So the technical writers can start writing user manuals while developers are writing code. By the time
the product is ready, most of the work on user manuals has already been completed.
Support and New Features: Your customers need support when you start selling a product.
This is true regardless of the size of the product, and even for products that are not software related.
Most common support requests from customers are related to one of the following:
o The customer needs help in installation and getting started.
o The customer finds a bug and you need to release a patch or update to the whole product.
o The product does not fulfill customer requirements and a new feature is required by the customer.
In addition to that, you may also want to add new features to the product for the next release because
competitor products have other features. Better support will increase your customer loyalty and will create
referral business for you.
You may adopt two strategies to add new features. You may provide an upgrade to the current release as a
patch, or wait until you have compiled and developed a list of new features and make a new version. Both of
these strategies are useful depending how urgent the requirement for new features is.
Hardware Platform
8
This is the tangible part of the development system. A hardware platform is the choice of
your hardware, PC or workstation, for the development system. You can choose a particular
hardware platform depending upon different factors as listed below:
Usually UNIX workstations have high performance and stability as compared to PC-based
Performance
solutions.
Tools You also need to keep in mind availability of development tools on a particular platform.
If the target system is the same as the host system on which development is done, the
Development
development is relatively easy and native tools are cheap as well, compared to cross platform
Type
development tools.
Development Type If the target system is the same as the host system on which development is done, the
development is relatively easy and native tools are
cheap as well, compared to cross-platform development tools.
Depending upon these factors, you may make a choice from the available hardware platforms for
development.
The Software Development Approaches below show how the various tasks related to software development
can be organized. Typical approaches or paradigms encountered in software development include waterfall,
incremental, and spiral as described below. The incremental development approach typically forms the basis
9
for software development within the larger systems level of Evolutionary Acquisition (EA). There are four
main types of software development approaches which are:
Development activities are performed in order, with possibly minor overlap, but with little or no iteration
between activities. User needs are determined, requirements are defined, and the full system is designed,
built, and tested for ultimate delivery at one point in time. A document-driven approach best suited for highly
precedence systems with stable requirements.
The waterfall model is often also referred to as the linear and sequential model, for the flow of activities in
this model are rather linear and sequential as the name suggests. In this model, the software development
activities move to the next phase only after the activities in the current phase are over. However, as is the
case with a waterfall, one cannot return to the previous stage.
Determines user needs and defines the overall architecture, but then delivers the system in a series of
increments (―software builds‖). The first build incorporates a part of the total planned capabilities; the next
build adds more capabilities, and so on, until the entire system is complete.
10
III. Spiral Approach
A risk-driven controlled prototyping approach that develops prototypes early in the development process to
specifically address risk areas followed by an assessment of prototyping results and further determination of
risk areas to prototype. Areas that are prototyped frequently include user requirements and algorithm
performance. Prototyping continues until high-risk areas are resolved and mitigated to an acceptable level.
During each iteration or loop, the system is explored at greater depth, and more detail is added. Appropriate
for exploratory projects working in an unfamiliar domain or with unproven technical approaches. The
iterative nature allows for knowledge gained during early passes to inform subsequent passes.
Software metrics should be an integral part of the software development processes. Program Management
Offices (PMO) should gain insight into proposed metrics during source selection, and developers should
commit to the consistent use of those metrics, including collecting, analyzing, and reporting. Metrics chosen
for use should be defined in the Software
Software engineers should take into account several variables when choosing a software development
approach for a project to ensure the greatest fit for their unique requirements. Here are some tips for
assessing and choosing the best strategy from among the several possibilities, including waterfall,
incremental, spiral, and agile:
Project Requirements: Recognize the type of requirements for the project. A more sequential
method, like the waterfall model, might be effective if the requirements are clearly specified and
unlikely to change dramatically. Conversely, Agile approaches may be more suited if the
requirements are flexible and likely to change.
Project Size and Complexity: Consider the project‘s size and complexity. A more conventional
strategy like the waterfall model may be adequate for smaller projects with unambiguous goals.
However, methodologies that support iterative development and ongoing feedback, like incremental
or agile approaches, typically perform better for larger and more complicated projects.
Flexibility and Adaptation: Throughout the development process, evaluate the need for flexibility
and adaptability. Agile approaches are excellent when requirements are likely to change because they
12
Prepared By Ayele S. (MSc, BSc in CS), Department of Computer Science Hawassa University – November, 2023
strongly emphasize numerous iterations, ongoing feedback, and adaptability. Iterative cycles for risk
management are incorporated into the spiral model, which also offers flexibility.
Timing Restrictions: Consider the project‘s timing restrictions. A more linear strategy, such as the
waterfall model, may be effective if there is a hard deadline and it is unlikely that the requirements
would change dramatically. However, agile or incremental approaches that emphasize providing
usable software in brief iterations might be helpful if time-to-market is important or if the project
calls for frequent releases.
Stakeholder Involvement: Take into account the degree of collaboration and stakeholder
involvement needed. With frequent communication and feedback loops, agile techniques encourage
active stakeholder involvement throughout development. Agile approaches are suitable if stakeholder
collaboration is essential for the project‘s success.
Risk Management: Assess the project‘s need for risk management. The spiral model, which
combines risk analysis and mitigation at each iteration, is beneficial when working with highrisk
projects. Risk management strategies used by other approaches, such as agile, include constant
feedback and early problem detection.
Team Experience and Skill Set: Evaluate the development team‘s experience and skill set.
Continuing with a methodology could be more effective if the team has past experience and skill with
it. Agile methodologies, which encourage cooperation and continuous improvement, are worth
considering if the team is receptive to adopting new methodologies.
Client or Industry Requirements: Consider any unique demands or tastes of the client or sector.
Some clients or industries may have established preferences for specific development methodologies.
To guarantee client happiness and compliance, aligning with these requirements is crucial.
Remember that these strategies are not mutually exclusive and that hybrid models can be adjusted to meet the
needs of specific projects. The key is to assess the project‘s characteristics, goals, and restrictions while
considering the team‘s capabilities and stakeholder expectations when choosing a strategy.
13
Prepared By Ayele S. (MSc, BSc in CS), Department of Computer Science Hawassa University – November, 2023
Rapid Application Development (RAD) was conceived in the 1980s, so it‘s definitely not something new.
But unlike the waterfall model, it‘s not singular. It‘s a continuous evolution of development philosophies
according to the requirement at that particular time.
The worldwide market for Rapid Application Development is projected to grow at a compound annual
growth rate (CAGR) of 42.8% from 2022 to 2027.
Initially, Barry Boehm, James Martin, and a number of others saw that software was not limited to traditional
methods of engineering. It wasn‘t a singular resource that required a fixed structure. It was malleable to suit
the needs of the user.
RAD is the best approach to develop prototypes swiftly for testing software functionalities without worrying
about any effects on the end product. Businesses option RAD approach as it requires little focus on the
planning phase while enabling the team to design, review, and iterate features and functionalities quickly.
Initially, rapid application development took the shape of the Spiral model, where one or more development
models were used to work on a particular project.
Over time, RAD phases have changed. It molded itself to fit the requirements of the time while retaining
some core development guidelines. The RAD approach is driven by user interface needs and is perfect for
application development requiring quick development and deployment. With visual interface tools and pre-
built modules, RAD helps create software apps quickly and easily. Businesses adopt different types of rapid
app development because of their agility, flexibility, and scalability.
Steps in Rapid Application Development: Here are the four basic steps of RAD:
At the very beginning, rapid application development sets itself apart from traditional software development
models. It doesn‘t require you to sit with end users and get a detailed list of specifications; instead, it asks for
a broad requirement. The broad nature of the requirements helps you take the time to segment specific
requirements at different points of the development cycle.
2. Prototype
This is where the actual development takes place. Instead of following a rigid set of requirements, developers
create prototypes with different features and functions as fast as they can. These prototypes are then shown to
the clients who decide what they like and what they don‘t.
14
Prepared By Ayele S. (MSc, BSc in CS), Department of Computer Science Hawassa University – November, 2023
More often than not, these prototypes are quickly made to work to showcase just the key features. This is
normal, and the final product is only created during the finalization stage where the client and developer are
in alignment with the final product.
3. Construction
The construction stage is a crucial stage of development. Engineers and developers work tirelessly to flesh
out a working system from a working model. Feedback and reviews are crucial at this stage and most bugs,
issues, and alterations are addressed during this stage. This stage can be particularly long, especially in cases
where clients change directions or feedback is intensive.
4. Deployment
The final stage of RAD involves deploying the built system into a live production environment. The
deployment phase involves intensive scale testing, technical documentation, issue tracking, final
customizations, and system simulation. Teams also spend time debugging the app and running final updates
and maintenance tasks before going live.
(RAD) model Rapid Application Development (RAD) is a software development methodology that
prioritizes rapid prototyping and quick feedback over long, drawn-out development and testing cycles. Here's
how RAD's accelerated development cycles contribute to overall value generation for businesses:
Faster Time-to-Market: RAD uses iterative development and prototyping, which means that usable parts of
the software can be delivered quickly. This allows businesses to bring their products to market faster, which
can provide a significant competitive advantage.
Cost Savings: Since RAD involves continuous user feedback, errors and issues are identified and rectified
early in the development process. This reduces the cost and effort required for extensive debugging later on.
Additionally, since the product reaches the market quicker, the revenue stream begins sooner, contributing to
better financial performance.
Increased Value Generation: RAD allows for the frequent release of smaller features, which not only keeps
the end-users engaged but also provides them with immediate value. Moreover, as the end-users are involved
throughout the development process, the final product tends to be more aligned with their needs, thereby
increasing its overall value.
15
Prepared By Ayele S. (MSc, BSc in CS), Department of Computer Science Hawassa University – November, 2023
Reduced Risk: With its focus on incremental development, RAD reduces the risk of project failures. Since
each of small iteration is manageable and can be easily tested, the risk of any major issue affecting the entire
project is significantly reduced.
Enhanced Customer Satisfaction: By involving users throughout the development process, RAD ensures
that the final product meets user expectations and requirements. This leads to increased customer satisfaction,
which can drive customer loyalty and retention.
Self-exercise: Answer the following questions by further referring or reading from any resources;
KISS: Keep It Simple, Short. The main idea is to keep the code as simple as possible so that it is easier
to work with later. Complex or complicated code takes longer to design, write, and test. And it might be
harder to modify or maintain in the future. However, I would still avoid being ―cheap‖ at the design
stage. Simplicity is much better, but missing the essential requirements and not including them in the
process is just as bad as overcomplicating it. If you don‘t understand your code well enough to write it
into its most simple version, how can you look back at the code and get what it was supposed to do in
the future?
DRY (Don‘t Repeat Yourself) is a principle of software development aimed at reducing repetition of
code, replacing it with abstractions or using data normalization to avoid redundancy. Sometimes in Go
you need to write a copy of a function if you need additional parameters. In Go, the lack of function
overloading and default values for arguments requires writing a new function and setting a default value
and calling the same function. In Go, I like the KISS principle the most, keep it simple. Experience with
other languages has taught us that having many methods with the same name but different signatures is
16
Prepared By Ayele S. (MSc, BSc in CS), Department of Computer Science Hawassa University – November, 2023
sometimes useful, but in practice it can also be confusing and unreliable. Matching by name only and
requiring consistency in types has been a major simplification in the Go type system. On the other hand,
Go has packages that allow us to focus on code with DRY principle. That allows us to write concise
code in a structured way.
YAGNI (You Aren‘t Gonna Need It) is simple and obvious principle, but not everyone follows it. If you
write code, then be sure that you will need it, as described in the requirements. Don‘t write code if you
think it will come in handy later.
BDUF (Big Design Up Front): this software engineering principle affirms that a developer should
complete the project‘s design first. After that, they can now implement it. Proponents argue that this
helps discover issues at the requirements stage and solve them quickly. However, changes in the
software requirements may occur during the project‘s life cycle. Such changes may cause difficulties or
even render the design code obsolete. One way to solve this is to have the general architecture first.
Then divide the requirements into several stages according to priorities. The development stage starts
with the highest to the lowest priority stage. At every step, implement the BDUF principle before the
actual coding process. Critics (notably those who practice agile software development) argue that BDUF
is poorly adaptable to changing requirements and that BDUF assumes that designers are able to foresee
problem areas without extensive prototyping and at least some investment into implementation. For
substantial projects, the requirements from users need refinement in light of initial deliverables, and the
needs of the business evolve at a pace faster than large projects are completed in – making the Big
Design outdated by the time the system is completed.
SOLID: The SOLID principles are essentially a set of rules for helping you write clean and maintainable
code, and the most well-known principle of software development. The first principle of SOLID is S –
the principle of single responsibility. Go doesn‘t have classes, but if we replace the word class with
objects (structs, functions, interfaces or packages) must have only one responsibility, a single important
unifying idea, functions serve a single purpose.
Open–closed principle — O Objects must be open for extension but closed for modification. It‘s about
not overriding methods or classes, just adding extra functionality as needed. A good way to solve this
problem is to use inheritance. Go solves this problem with composition.
L – The Liskov Substitution Principle states that a derived class should be substitutable for its base class.
In other words, if a program is using a base class, it should be able to use a derived class without
knowing it. In Go, this can be achieved by defining clear contracts between types using interfaces, and
ensuring that derived types fulfill those contracts.
Interface Segregation Principle – The fourth principle is the interface segregation principle, which reads:
Clients should not be forced to depend on methods they do not use. In Go, the application of the
17
Prepared By Ayele S. (MSc, BSc in CS), Department of Computer Science Hawassa University – November, 2023
interface segregation principle can refer to a process of isolating the behavior required for a function to
do its job. As a concrete example, say I‘ve been given a task to write a function that persists a document
structure to disk.
Dependency Inversion Principle High-level modules should not depend on low-level modules. Both
should depend on abstractions. Abstractions should not depend on details. Details should depend on
abstractions. In the Go context, high-level modules refer to software components that are utilized on top
of the application, such as presentation code. Understanding it as a layer that provides real business
value to our application. On the other hand, the majority of low-level software components are little
code fragments that support the higher-level software. They keep technical information regarding
various infrastructure integrations hidden.
18
Prepared By Ayele S. (MSc, BSc in CS), Department of Computer Science Hawassa University – November, 2023