<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[Evans' Blog]]></title><description><![CDATA[I am a Software Developer, currently living in Nairobi,Kenya. I am self-motivated, constantly experimenting with new technologies and techniques.]]></description><link>https://evansopilo.hashnode.dev</link><generator>RSS for Node</generator><lastBuildDate>Tue, 06 Oct 2026 13:45:01 GMT</lastBuildDate><atom:link href="https://evansopilo.hashnode.dev/rss.xml" rel="self" type="application/rss+xml"/><language><![CDATA[en]]></language><ttl>60</ttl><item><title><![CDATA[Top killer software design patterns you should know 🚀]]></title><description><![CDATA[In software engineering Design patterns refers to the typical solution to commonly occurring problems. These patterns can be customised to solve a different design problem in software design. These patterns are broadly categorised into three:- creati...]]></description><link>https://evansopilo.hashnode.dev/top-killer-software-design-patterns-you-should-know</link><guid isPermaLink="true">https://evansopilo.hashnode.dev/top-killer-software-design-patterns-you-should-know</guid><category><![CDATA[software development]]></category><category><![CDATA[Software Engineering]]></category><category><![CDATA[design patterns]]></category><category><![CDATA[Beginner Developers]]></category><category><![CDATA[4articles4weeks]]></category><dc:creator><![CDATA[Evans Opilo]]></dc:creator><pubDate>Thu, 18 Aug 2022 20:38:53 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/unsplash/ZSPBhokqDMc/upload/v1659559637205/JpuQGLkMnA.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>In software engineering Design patterns refers to the typical solution to commonly occurring problems. These patterns can be customised to solve a different design problem in software design. These patterns are broadly categorised into three:- creational, structural, and behavioural design patterns. This article aims to brief the common design patterns that every developer should know.</p>
<h3 id="heading-1-singleton">1. Singleton</h3>
<p>At the top of our list is the singleton pattern. This is a creational pattern that ensures that only one instance of the class is created and shared throughout the program code. The most common reason for the pattern is the control of shared resources. for example, in your application, you may only need to create a single database connections pool or instance of logger or cache and share it throughout your application code.</p>
<p>This can be achieved by tracking whether an instance of a class has been created before creating a new one. If the object has been created before, the initially created object is returned instead of creating a new one.</p>
<h3 id="heading-2-observer">2. Observer</h3>
<p>This design pattern defines a one-to-many relationship between objects. It eases the propagation of state changes of one object(subject) to the other objects(observers) interested in the changes. The observer will often create a subscription on the subject, and the subject will intern update all the subscribers of that subject in case of a state change. This pattern is also known as publisher/subscriber.</p>
<p>for example, If you subscribe to a newspaper or magazine, you no longer need to go to the store to check if the next issue is available. Instead, the publisher sends new issues directly to your mailbox right after publication or even in advance.</p>
<p>The publisher maintains a list of subscribers and knows which magazines they’re interested in. Subscribers can leave the list whenever they wish to stop the publisher from sending new magazine issues to them.</p>
<h3 id="heading-3-chain-of-responsibility">3. Chain of Responsibility</h3>
<p>A chain of Responsibility is a behavioural design pattern that lets you pass requests along a chain of handlers. Upon receiving a request, each handler decides either to process the request or to pass it to the next handler in the chain.</p>
<p>Imagine you're building a school management system, whenever a request is received from the client you may need to perform a set of operations ie. validation, authentication, authorization checks, and serve the request response from the cache if it exists, before processing the request.</p>
<p>Chain of responsibility patterns relies on transforming these operations into stand-alone objects referred to as handlers. These methods are chained together, the request object is passed to the fast handler in the chain process and if it is successfully processed this handler decides whether to pass it to the next handler in the chain or not.</p>
<h3 id="heading-4-factory-method">4. Factory Method</h3>
<p>This design pattern provides an interface for creating objects by providing some information about the object such as its type without providing its underlying implementation logic.</p>
<p>Imagine that you start a motor production factory and the first release of your motors are say trucks, but due to the high quality of your motors your customers start to request for busses too. This is good for the business, right? but there is a problem, and that is your production line was only engineered to produce trucks this means the entire production line will have to be re-engineered to support the production of busses too, easy right? what if your customer request for more different motors says motorbikes, cars. </p>
<p>This cycle may become expensive and tiresome for your company. Maybe it would be easy if we have a single production line that can easily be switched to different production modes, say switching to different programs without having to redesign it again.</p>
<p>This is the type of design problem that the factory method solves in your code, that is defining a creation interface that every object must meet. Thus making it possible to create objects of different types by simply providing information such as object type without providing the creation logic.</p>
<h3 id="heading-5-constructorbuilder">5. Constructor/Builder</h3>
<p>Builder is a design pattern that lets you construct complex objects step by step. The pattern allows you to produce different types and representations of an object using the same construction code. This design pattern may be suitable, when the process involved in creating an object is extremely complex with lots of mandatory and optional parameters, an increase in the number of constructor parameters leads to a large list of constructors or when the client expects different representations for the object that's constructed.</p>
<h3 id="heading-conclusion">Conclusion</h3>
<p>In this article, we have briefed the top 5 important design patterns that you should know as a developer. This includes the singleton pattern that ensures that only one instance of the class is created and shared throughout the program code, observer patterns that define a one-to-many relationship between objects, a chain of responsibility that lets you pass requests along a chain of handlers,  factory method that provides an interface for creating objects by providing some information about the object such as its type without providing its underlying implementation logic and constructor pattern that lets you construct complex objects step by step.</p>
]]></content:encoded></item><item><title><![CDATA[Pagination as an ingredient for API scalability]]></title><description><![CDATA[Scaling your API might require fundamental changes to your application architecture and code. First, you need to determine what your scaling bottlenecks are; otherwise, you’re just making guesses.
One of the best ways to gain insights into bottleneck...]]></description><link>https://evansopilo.hashnode.dev/pagination-as-an-ingredient-for-api-scalability</link><guid isPermaLink="true">https://evansopilo.hashnode.dev/pagination-as-an-ingredient-for-api-scalability</guid><category><![CDATA[APIs]]></category><category><![CDATA[scalability]]></category><category><![CDATA[performance]]></category><category><![CDATA[software development]]></category><category><![CDATA[Web Development]]></category><dc:creator><![CDATA[Evans Opilo]]></dc:creator><pubDate>Wed, 27 Apr 2022 18:23:11 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/unsplash/1bNQVGzuy0U/upload/v1651083483414/TwXKTL9uW.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Scaling your API might require fundamental changes to your application architecture and code. First, you need to determine what your scaling bottlenecks are; otherwise, you’re just making guesses.</p>
<p>One of the best ways to gain insights into bottlenecks is through instrumentation. By collecting data on usage and monitoring for capacity bottlenecks, you can take advantage of data-driven insights into optimizations that will help you scale.</p>
<p>APIs serve large datasets, and when the client requests this data, serving it all at once can overwhelm the application's backend and the client application. 
If you love analogies, think of it this way: <a target="_blank" href="https://www.amazon.com/">Amazon</a> sells  12+ million products, and when a client sends a Get request to the product API loading this data to the server's memory, then transmits it to the client becomes resource inefficient.</p>
<p>For these reasons, it's important to chunk the response data and transmit each chunk when needed, which can at least minimize response time for requests, and make responses easier to handle. And this is where pagination, which is one of the best API scaling techniques comes in.</p>
<h3 id="heading-pagination-techniques">Pagination Techniques</h3>
<p>We are going to explore some of the techniques that you can use to paginate an API.</p>
<h4 id="heading-1-offset-based-pagination">1. Offset based pagination.</h4>
<p>Limiting your response dataset by use of limits and offsets is generally the easiest and the most widely used pagination technique. To paginate this way, clients provide a page size that defines the maximum number of items to return and a page number that indicates the starting position in the list of items. </p>
<p>Based on these values, servers storing data in a SQL database can easily construct a query to fetch results. For instance, to fetch the fifth page of items with each page’s size being 10, we should load 10 items, starting after 40 items (skipping the first 4 pages of size 10). The corresponding SQL query would look like the following:</p>
<pre><code><span class="hljs-keyword">SELECT</span> * <span class="hljs-keyword">FROM</span> <span class="hljs-string">`items`</span>
<span class="hljs-keyword">ORDER</span> <span class="hljs-keyword">BY</span> <span class="hljs-string">`id`</span> <span class="hljs-keyword">ASC</span>
<span class="hljs-keyword">LIMIT</span> <span class="hljs-number">10</span> <span class="hljs-keyword">OFFSET</span> <span class="hljs-number">40</span>;
</code></pre><p>APIs, such as GitHub, support this kind of pagination. Clients can simply request with page and per_page parameters specified in the URL.</p>
<h4 id="heading-advantages-and-disadvantages">Advantages and disadvantages</h4>
<p>Offset-based pagination is extremely simple to implement, both for
clients and the server. It also has user experience advantages. It
allows users to jump into any arbitrary page instead of forcing them
to scroll through the entire content.</p>
<p>However, this technique has a few disadvantages:</p>
<p>i)  It’s inefficient for large datasets. SQL queries with large offsets
are pretty expensive. The database has to count and skip rows
up to the offset value before it gets to returning the desired set
of items.</p>
<p>ii) It can be unreliable when the list of items changes frequently.
The addition of an item while a client is paginating through
results could cause the client to display the same item twice.
Similarly, on the removal of an item, a client might end up skipping
it at the boundary.</p>
<p>iii) Offset-based pagination can be tricky in a distributed system.
For large offsets, you might need to scan several shards
before you get to the desired set of items.
That said, offset paginations can be great when pagination depth is
limited and clients can tolerate duplicates or missed items.</p>
<h4 id="heading-2-cursor-based-pagination">2. Cursor-Based Pagination</h4>
<p>To address the problems of offset-based pagination, various APIs have adopted a technique called cursor-based pagination. To use this technique, clients first send a request while passing only the desired number of items. The server then responds with the requested number of items (or the maximum number of items supported and avail‐
able), in addition to a text cursor. </p>
<p>In the subsequent request, along with the number of items, clients pass this cursor indicating the starting position for the next set of items. Implementing cursor-based pagination is not very different from offset-based pagination. However, it’s much more efficient. Systems
that store data in a SQL database can create queries based on the cursor values and retrieve results.</p>
<p>Suppose that a server returns a Unix timestamp of the last record as
the cursor. To fetch a page of results that are older than that given
cursor, the server can construct a SQL query like the following:</p>
<pre><code><span class="hljs-keyword">SELECT</span> * <span class="hljs-keyword">FROM</span> items
<span class="hljs-keyword">WHERE</span> created_at &lt; <span class="hljs-number">1507876861</span>
<span class="hljs-keyword">ORDER</span> <span class="hljs-keyword">BY</span> created_at
<span class="hljs-keyword">LIMIT</span> <span class="hljs-number">10</span>;
</code></pre><p>Having an index on the column created_at in the preceding example makes the query fast.
Several modern APIs, including those of Slack, Stripe, Twitter, and Facebook, offer cursor-based pagination.</p>
<p>Having an index on the column created_at in the preceding example makes the query fast.
Several modern APIs, including those of Slack, Stripe, Twitter, and Facebook, offer cursor-based pagination. </p>
<h4 id="heading-advantages-and-disadvantages">Advantages and disadvantages</h4>
<p>Cursor-based pagination addresses both the issues are seen with offset based pagination:</p>
<p>i) One of the key benefits of cursor-based pagination is performance. With an index on the column used in the cursor for pagination, even queries requiring scanning large tables are fast.</p>
<p>ii) The addition or removal of items does not affect the result set of a page. While paginating across results, the server returns every item exactly once. Cursor-based pagination is great for large and dynamic datasets.</p>
<p>However, it has a few drawbacks:</p>
<p>i)  Clients cannot jump to a given page. They need to traverse
through the entire result set page by page.</p>
<p>ii) The results must be sorted on a unique and sequential database
column, used for the cursor value. It should not be possible to
add records at a random position in the list.</p>
<p>iii) Implementing cursor-based pagination is a bit more complex than offset-based pagination, particularly for clients. Clients often need to store the cursor value to use it in subsequent requests.</p>
<h3 id="heading-the-end">The End!</h3>
<p>Thanks for reading this article to this end. Hope it has been helpful and informative.</p>
]]></content:encoded></item><item><title><![CDATA[Software Testing ⚙ in a nutshell]]></title><description><![CDATA[Testing can simply mean putting something under strain, and challenge to reveal its capabilities or behaviours. This can be through a simulated or an actual environment. This applies everywhere including in the software industry which is referred to ...]]></description><link>https://evansopilo.hashnode.dev/software-testing-in-a-nutshell</link><guid isPermaLink="true">https://evansopilo.hashnode.dev/software-testing-in-a-nutshell</guid><category><![CDATA[Testing]]></category><category><![CDATA[unit testing]]></category><category><![CDATA[Software Testing]]></category><category><![CDATA[software development]]></category><category><![CDATA[Software Engineering]]></category><dc:creator><![CDATA[Evans Opilo]]></dc:creator><pubDate>Sat, 23 Apr 2022 20:54:52 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/unsplash/vc3iVL_znJ8/upload/v1650746837540/mPEtZ2muO.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Testing can simply mean putting something under strain, and challenge to reveal its capabilities or behaviours. This can be through a simulated or an actual environment. This applies everywhere including in the software industry which is referred to as software testing.</p>
<p>This article aims to explain what software testing is at a basic level. covers the importance of testing and some of the important testing strategies that every developer should know.</p>
<p>Software Testing refers to the set of activities that are carried out to examine the correctness, accuracy and completeness of software, before pushing it to the production environment.</p>
<h2 id="heading-why-software-testing">Why Software Testing?</h2>
<p>Software testing is important since it helps in the discovery of bugs which can cause social or economical damage to the end-users. For example, would you take the risk of boarding a plane or a ship that has not to been tested? I guess your answer is no, the same case applies to software.</p>
<p>When software is not tested it can cause economic or social damage to the end-users for example:</p>
<p>One of the biggest American market makers for stocks struggled to stay afloat after a software bug triggered a $440 million loss in just 30 minutes. The firm’s shares lost 75 per cent in two days after the faulty software flooded the market with unintended trades. </p>
<h2 id="heading-types-of-software-testing">Types Of Software Testing</h2>
<p>Though there are more than 100 software testing techniques, only a few are selected during SDLC depending on the type of development model and the application under development.</p>
<p>In this section, we intend to uncover some of the most widely used testing techniques that at least every developer should know.</p>
<h3 id="heading-unit-testing">Unit Testing</h3>
<p>Usually, the software is broken down into units/modules/components that serve a specific functionality in the software. for example in an eCommerce application, we can have an authentication module that handles all authentication operations in the application. </p>
<p>This module integrates with other modules to provide a fully functional application. But before integration, it would be necessary to test this module to ensure that it's bug-free, functional and meets all the requirements and integrating it with other components will not result in the failure of the software.</p>
<p>This is the stage where unit testing takes part, the components are tested independently and if there are dependencies required for the module to work, these dependencies are replaced with stubs/mocks. for example, replacing a database integration with an interface that is not an actual database but mocks the database behaviour.</p>
<p>Note: for a test to be referred to as a unit test the tested component should not interact with any dependencies ie. database, network, files etc.</p>
<h3 id="heading-integration-testing">Integration Testing</h3>
<p>After the software modules are tested to satisfaction, the modules are integrated and tested using the integration testing technique.  The goal of integration testing is to detect any irregularity between the units that are integrated together. </p>
<p>From our earlier example assuming the authentication module and the rest of the modules have been tested to satisfaction. It's time to integrate these components together. </p>
<p>This test can take two-approach:</p>
<ol>
<li>Big-bang, where all the modules are required to run integration tests.</li>
<li>Incremental,  where tests can be run on existing modules and stubs/mocks can be used to provide the functionality of non-existing modules.</li>
</ol>
<h3 id="heading-system-testing">System Testing</h3>
<p>Once all the units/modules/components that make up the application are integrated and tested, System testing also referred to as end-end testing is carried out. System testing detects defects within both the integrated units and the whole system.</p>
<p>In this type of test, the application is treated as a black box. The goal is to ensure the application meets the expected system behaviour without having to worry about how it works internally.</p>
<h3 id="heading-acceptance-testing">Acceptance Testing</h3>
<p>At this stage, the software is tested for compliance with specified requirements. This ensures users' satisfaction is met before deployment.</p>
<p>This test involves:</p>
<ol>
<li>Alpha testing, the system is tested in the development testing environment these testers are referred to as alpha testers.</li>
<li>Beta testing, the system is tested by end-users, and feedback is collected for improving the system's user experience or fixing defects. These users are referred to as better testers.</li>
<li>User Acceptance testing, this test determines whether the software meets the user's expectations.</li>
<li>Business acceptance testing, this test determines whether the software meets the business goals.</li>
<li>Contract Acceptance Testing, this is a contract that once the product goes live, within a predetermined period, the acceptance test must be performed and it should pass all the acceptance use cases.</li>
<li>Regulations Acceptance Testing, is used to determine whether the product violates the rules and regulations that are defined by the government of the country where it is being released. </li>
<li>Operational Acceptance Testing, is used to determine the operational readiness of the product and is non-functional testing.</li>
</ol>
<h2 id="heading-the-end">The End!</h2>
<p>Thanks for reading this article to this end. Hope the article was helpful and informative. </p>
]]></content:encoded></item></channel></rss>