<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Bemigho Awala</title>
    <description>The latest articles on DEV Community by Bemigho Awala (@bemigho_awala_959f07d23df).</description>
    <link>https://dev.to/bemigho_awala_959f07d23df</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3278746%2F6d67dc21-dc2b-44af-ae41-8a2560586eee.png</url>
      <title>DEV Community: Bemigho Awala</title>
      <link>https://dev.to/bemigho_awala_959f07d23df</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/bemigho_awala_959f07d23df"/>
    <language>en</language>
    <item>
      <title>Engineering Empathy: Why Developers Should Think Like Users</title>
      <dc:creator>Bemigho Awala</dc:creator>
      <pubDate>Thu, 15 Jan 2026 09:08:16 +0000</pubDate>
      <link>https://dev.to/bemigho_awala_959f07d23df/engineering-empathy-why-developers-should-think-like-users-2e4o</link>
      <guid>https://dev.to/bemigho_awala_959f07d23df/engineering-empathy-why-developers-should-think-like-users-2e4o</guid>
      <description>&lt;p&gt;BY Oluwaferanmi Adeniji&lt;/p&gt;

&lt;p&gt;There's a moment every engineer experiences but we seldom talk about: the moment you realize your feature works perfectly but is completely unusable by the actual user.&lt;br&gt;
The tests pass. The code review gets approved. Deployment goes smoothly. Logs show no errors. Metrics indicate successful transactions. By every technical measure, the feature is complete and functioning exactly as designed.&lt;br&gt;
And then someone tries to use it.&lt;/p&gt;

&lt;p&gt;Not "someone" in the abstract sense, the way we casually reference "the user" in planning meetings or architecture discussions. An actual person, with actual constraints, trying to accomplish a task in the middle of their workday. That's when the gap appears.&lt;br&gt;
This gap between what works technically and what works practically is what separates functional code from functional products. It's where most engineering effort quietly fails, not with dramatic crashes or security breaches, but with silent abandonment. Features that get built, shipped, measured as "successful" by internal metrics, and then avoided. Worked around. Complained about in Slack channels you're not in.&lt;/p&gt;

&lt;p&gt;I’d call this the “product-engineering empathy gap”, though the term itself is misleading. This isn't about feelings or compassion in the conventional sense. It's not about being nicer to users or caring more deeply about their experience, though those things have their place. The empathy gap is a technical problem with technical consequences.&lt;/p&gt;

&lt;p&gt;It's the distance between your mental model and theirs. Between your development environment and their reality. Between the logic you spent weeks building and the two seconds they have to understand it. Between the interface you see after staring at it for forty hours and the interface they see for the first time while distracted, stressed, or rushed or going about their daily business.&lt;/p&gt;

&lt;p&gt;Familiarity bias plays an important role in blinding us from being able to spot this gaps sometimes, we build a mental model around the features we’re building and know how it works end to end, we know what happens when you click the button “Terminate”, but an average user might see that and think, what am I terminating? My account? My loan? Or transfer?&lt;/p&gt;

&lt;p&gt;Most engineers approach this gap from the wrong direction. We think: "How do I make users understand my system?" We write better documentation. Add more tooltips. Create onboarding flows. Build help centers. All of these treat the gap as a communication problem. As though, if we just explained it better, users would get it.&lt;/p&gt;

&lt;p&gt;But the gap isn't communication. It's assumption.&lt;br&gt;
When you build a feature, you're not starting from zero. You're starting from months or years of context: technical decisions made in previous sprints, architectural patterns chosen by your team, domain knowledge accumulated through countless meetings, mental shortcuts developed through repetition. You know why the button is positioned there. You understand what happens when you click it. You can distinguish between a loading state and a broken state because you've seen both a hundred times.&lt;br&gt;
Your user has none of this context. They're not trying to understand your system. They're trying to complete a task, and your interface is either helping or hindering that goal. Every moment of confusion is friction. Every unclear label is a decision point. Every unexpected behavior is a crisis of trust.&lt;/p&gt;

&lt;p&gt;For the longest time, engineering empathy has been treated as a skill that designers handle while engineers focus on "real" technical problems. That’s wrong. Engineering empathy is a technical discipline that directly impacts every decision you make: your architecture, your API design, your error handling, your state management, your performance optimization. It shapes what you choose to build, how you choose to build it, and whether what you build actually matters.&lt;/p&gt;

&lt;p&gt;The engineers who understand these build products people use. Products that feel intuitive not because of clever design tricks, but because the underlying technical decisions were made with real usage patterns in mind. Products that handle errors gracefully because someone thought about what happens when things go wrong in practice, not just in theory. Products that perform well on the hardware people actually have, not just the development machines engineers use.&lt;/p&gt;

&lt;p&gt;The engineers who don't understand this build features that work in isolation and fail in context. Features that technically meet requirements but practically solve nothing. Code that's elegant to review and frustrating to use.&lt;/p&gt;

&lt;p&gt;This gap exists because we've been trained to think about users in abstract. In planning meetings, we talk about "the user" as a singular entity with consistent needs, behaviors, and capabilities. We create personas with names and demographics. We write user stories that fit neatly into acceptance criteria. We measure success with aggregate metrics that smooth out individual experience into trendlines and percentages.&lt;/p&gt;

&lt;p&gt;But "that perfect user" doesn't exist. There's no platonic ideal of a user with perfect understanding, infinite patience, and optimal conditions. There are only actual people, each with different contexts, constraints, and cognitive loads. Each with different hardware, different network conditions, different levels of urgency. Each with different mental models shaped by different experiences with different software.&lt;/p&gt;

&lt;p&gt;Yet we build for the abstraction. We optimize for the ideal case. We test under perfect conditions. We assume understanding doesn't exist. We design for focus that isn't there.&lt;br&gt;
This is the lie at the heart of most software development: that users are a knowable, predictable category we can build for in a general sense. That if we just follow best practices and ship clean code, the usage will take care of itself. That our job is to build features, and someone else's job is to make them usable.&lt;/p&gt;

&lt;p&gt;The gap persists because we've separated technical execution from practical impact. We've created a division of labor where engineers build functionality and designers add usability, as if these were separable concerns. As if you could architect a system without understanding how it will be used. As if you could write error handling without imagining the person encountering that error. &lt;br&gt;
This problem becomes particularly obvious during digital transformation, when businesses take existing analog processes and convert them to software. Here, the empathy gap widens fast!. Teams focus on replicating what exists: the paper form becomes a web form, the manual approval process becomes a workflow engine, the filing cabinet becomes a database. The assumption is that digital is inherently better, that moving the process online automatically improves it. But digitization without empathy often makes things worse.&lt;/p&gt;

&lt;p&gt;The paper form had implicit knowledge embedded in it, the loan officer who helped you fill it out, the ability to see all fields at once, and the flexibility to attach notes in margins. The software replicates the fields but not the context. It enforces validation that the paper form couldn't, creating new friction points. It breaks multi-step processes into separate screens, fragmenting what was previously visible as a whole. It assumes digital literacy doesn't exist, users who understood the paper process perfectly now struggle with dropdown menus, required fields, and error messages about data formats they've never heard of.&lt;br&gt;
Digital transformation teams often consist of people who understand the business domain deeply but have never watched someone struggle with basic UI patterns. They know every nuance of the loan approval process but don't realize that "Submit for Review" is ambiguous to someone who's never used workflow software. They're digitizing their mental model of the process, not the actual experience of the people executing it. The result is software that's technically correct, it implements every business rule, handles every edge case, but practically unusable for the field officers, clerks, and business owners who need to use it daily. The business got digitized. The users got left behind. This singular reason is why some large governmental organizations and parastatals have found it hard to transform or found it to be a grueling process. &lt;/p&gt;

&lt;p&gt;Engineering empathy means collapsing this false division. It means recognizing that understanding your users' reality is not a separate concern from building technical systems, it's fundamental to building those systems correctly. It means that every technical decision you make is, implicitly, a decision about how someone will experience your software. And if you're making those decisions without understanding that experience, you're building blind.&lt;br&gt;
The code that works in theory but fails in practice isn't good code. It's a waste. And the gap between the two is almost always a failure of empathy, a failure to understand the real conditions under which your software will be used, and to build accordingly.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The Cost of Low Empathy&lt;/strong&gt;&lt;br&gt;
Technical debt is a concept every engineer understands. You take shortcuts to ship faster. You skip refactoring. You let complexity accumulate. The code works, but it's fragile, hard to modify, and expensive to maintain. Eventually, you pay for those shortcuts, through slower development, more bugs, or complete rewrites.&lt;br&gt;
User frustration debt works the same way, but it's invisible to most engineering teams until it's severe.&lt;/p&gt;

&lt;p&gt;Every confusing interface is debt. Every unclear error message is debt. Every time a user has to guess what something does, or click three times when once should suffice, or wait without knowing if the system is working, that's debt accumulating. Like technical debt, it compounds. Unlike technical debt, most teams don't track it, don't measure it, and don't prioritize paying it down until it manifests as something dramatic: plummeting retention, viral complaint tweets, or mass user exodus to a competitor.&lt;br&gt;
By then, the debt is expensive to resolve. Features need redesigning. Mental models need changing. Users have already learned workarounds and become skeptical of improvements. The compounding interest on user frustration debt is lost trust, and trust is harder to rebuild than code.&lt;/p&gt;

&lt;p&gt;Low empathy creates phantom bugs. Users file issues that aren't technical failures, they're misunderstandings. "The save button doesn't work" means they're clicking the wrong button or not seeing feedback. "Data disappeared" means they don't understand the filter state. "Export is broken" means they expected CSV but got JSON, because the format of the exported data is unclear. &lt;br&gt;
Low empathy creates rework cycles. You build a feature. Users struggle. Support tickets pile up. You add tooltips. Still confusing. You write documentation. Adoption stays low. Product team escalates. You add a tutorial. Some improvement. Six months later, you rebuild it from scratch.&lt;br&gt;
This cycle is expensive. Not just the rework itself, but the opportunity cost. While you're fixing confusion from Feature A, you're not building Feature B. Your roadmap slips. Competitors ship. Users wait.&lt;/p&gt;

&lt;p&gt;Why Engineers Sometimes lack User Empathy&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Abstraction Is Our Core Skill&lt;/strong&gt;&lt;br&gt;
Engineers are literally trained to abstract. It's what makes us effective. We take messy, specific problems and extract general solutions. We see patterns across use cases. We build systems that work for many scenarios, not just one. This is good engineering.&lt;br&gt;
Good engineering is not good user experience, it should be the other way round, the engineering should be shaped around a good user experience, the product shouldn’t have to bend to how the supposedly “great” engineering was set up, the engineering architecture should be shaped around user behavior and use cases.&lt;br&gt;
Velocity Pressure Kills Reflection&lt;br&gt;
Most engineering teams operate under constant pressure to ship. Sprints are two weeks. Deadlines are tight. Backlogs are long. Your manager asks "when will this be done?" daily. In this environment, anything that slows you down feels irresponsible.&lt;br&gt;
Understanding users takes time, Talking to a customer success manager takes a meeting slot. Iterating on clarity after implementation takes another day. When you're already behind, these feel like luxuries you can't afford.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;We're Separated From Users&lt;/strong&gt;&lt;br&gt;
In most organizations, engineers don't talk to users. That's someone else's job. Product talks to users. Design talks to users. Customer success talks to users. Engineers get filtered information: requirements documents, design mockups, acceptance criteria.&lt;br&gt;
This separation seems efficient. Why have expensive engineering time in user research when researchers can do it? Why have engineers in support calls when support can handle it? Specialization makes sense.&lt;br&gt;
But it also means engineers never see the consequences of their decisions. You build a feature with multiple sequential loads rather than use optimistic updates. You never see the user refreshing repeatedly because they think it's broken. You implement validation logic that rejects malformed input. You never hear the support call where someone's crying because they can't submit their loan application and the error message doesn't explain why.&lt;br&gt;
The feedback loop is broken. You make decisions, ship code, and never witness the impact. Without that feedback, empathy can't develop. You're building in a vacuum, optimizing for metrics that feel abstract because you never meet the humans behind them.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The Smaller Your Agency, The More Your Details Matter&lt;/strong&gt;&lt;br&gt;
Here's the paradox: if you have low agency to change big decisions, the small decisions you control matter even more. You can't redesign the feature, but you can write a clear error message instead of a vague one. You can't change the workflow, but you can add loading indicators. You can't modify the requirements, but you can handle edge cases gracefully.&lt;br&gt;
These small acts of empathy compound. A feature might have a fundamentally confusing design that you can't fix. But if your error handling is clear, your loading states are informative, your edge cases are handled, and your performance is good, the feature becomes usable despite its flaws.&lt;br&gt;
Users rarely know whose decision created which problem. They just know the software is frustrating or not. Your contributions to reducing that frustration matter, even when they're small, even when they're invisible, even when they're just a good implementation of someone else's mediocre design.&lt;br&gt;
This isn't about accepting bad design. It's about recognizing that empathy is exercised in implementation details, not just in high-level product decisions. And those details are where most engineers actually have agency.&lt;br&gt;
These aren't excuses. They're explanations. The system creates conditions where empathy is difficult to practice and easy to skip. Recognizing this is important because it means fixing the problem requires systemic changes, and not just individual effort “alone”&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The Specificity Test&lt;/strong&gt;&lt;br&gt;
Before writing a single line of code, ask yourself: Can you name three actual people who will use this feature?&lt;br&gt;
Not personas, Not "busy professionals" or "small business owners”, but actual people. If you work at a company with real users, use their names, If you're building something new, find three people who match your target and talk to them until they're real to you. Know what time of day they'll use this. Know what else is happening around them. Know what they're trying to accomplish before they touch your feature and what they need to do after.&lt;br&gt;
This sounds trivial, but most features are built for abstractions. "Users want to filter their data" is an abstraction. "Marcus needs to find all product metrics because his manager asks for them every two days" is specific. The difference shapes everything, your UI priorities, your error messages, your performance targets, your default states. The difference could mean that you don’t need to build a real time system, you can have a background job that gathers metrics and data only at the end of day, and saves them for easy access for when “Marcus” needs it. You went from trying to solve for Realtime data computation to building something simple while still solving “Marcus’s” problem and making the best use of your time. &lt;br&gt;
When you can't name three people, you don't have enough information to build well. Full stop. Go talk to someone (or read the user persona’s documents properly) , a customer success manager, a support engineer, an actual user if possible, before you architect anything. The time you spend here prevents the time you'll waste refactoring later.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Build With Their Constraints, Not Yours&lt;/strong&gt;&lt;br&gt;
Your development environment is a lie. MacBook Pro with 32GB RAM, dual monitors, fast internet, latest Chrome with dev tools open. This is not reality for most people using your software.&lt;br&gt;
Create a "real world" environment and test there regularly. Old laptop with 4GB RAM. Throttled internet connection. Multiple browser tabs open. Notifications firing. Phone ringing. Calendar reminder popping up. This isn't about edge case testing, this is about testing under the conditions where most usage actually happens.&lt;br&gt;
Specifically:&lt;br&gt;
Throttle your connection. Chrome DevTools makes this trivial. Set it to "Fast 3G" or "Slow 3G" and use your feature. Notice how the two-second load time you optimized to 1.2 seconds feels infinite on a slow connection. Notice how your loading states, which you tested for 200ms, now display long enough for users to question if something broke.&lt;/p&gt;

&lt;p&gt;Test on older hardware. Borrow a laptop from 2017. Install your app on a mid-range Android phone from three years ago. Watch your smooth animations stutter. Watch your lazy-loaded components cause visible layout shifts. This isn't about supporting legacy hardware, it's about understanding that "performant" is relative.&lt;/p&gt;

&lt;p&gt;Test while distracted. Start a task in your feature, then switch tabs. Check Slack. Come back three minutes later. Can you remember where you were? Does the state make sense? Did anything time out? Real users don't give your interface their undivided attention. They're juggling six things at once.&lt;br&gt;
The goal isn't to make your local environment painful. It's to experience the friction that your decisions create for others. When you have to wait for that API call on a slow connection, you'll reconsider whether you really need to fetch data on component mount. When your form loses state after a page refresh, you'll implement auto-save. When you can't tell if something's loading or broken, you'll improve your feedback mechanisms.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The Brain Lies Exercise&lt;/strong&gt;&lt;br&gt;
Your brain is actively working against you when you test your own interfaces. This isn't a personal failing, it's neuroscience. You know where the buttons are. You understand what the labels mean. You expect certain behaviors. So your brain fills in missing affordances, unclear copy, and confusing flows. You literally see an interface that doesn't exist.&lt;br&gt;
Combat this with forced unfamiliarity:&lt;br&gt;
The design-beside-implementation technique: Put your Figma design or mockup on one monitor and your implementation on the other. Don't glance between them, study them side by side. Look for: spacing differences (1px matters), color tones, font weights, alignment, icon sizes, border radius. Your brain told you these were "close enough." They're not.&lt;br&gt;
The week-away test: Finish a feature on Friday. Don't look at it over the weekend. Open it fresh on Monday morning. Use it before checking any code. You'll notice things that were invisible to you on Friday. Unclear labels. Confusing flows. Missing feedback. Your familiarity was masking these issues.&lt;br&gt;
The annotation exercise: Screenshot your interface. Print it or open it in an image editor. Annotate every assumption you're making about what users understand. "Users will know this icon means 'save'" is an assumption. "Users will read this tooltip" is an assumption. "Users will understand that this button is disabled, not broken" is an assumption. Most interfaces have dozens of invisible assumptions. Make them visible.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Using your product With Intention&lt;/strong&gt;&lt;br&gt;
Using your own product with intention, only works if you do it correctly. Most engineers test their features by executing a perfect happy path: click the right buttons in the right order, fill fields with valid data, submit successfully. This proves nothing except that the feature can work under ideal conditions.&lt;br&gt;
Real testing means using your feature the way actual users will:&lt;br&gt;
Use it while tired. Not the fresh, caffeinated, focused version of you that built it. The 3 PM on Friday version of you who's been in meetings all day. The end-of-sprint version of you who just wants to finish one more task and go home. Notice how your cognitive load changes. Notice how you miss things. Notice how you want clearer feedback, more obvious buttons, simpler flows.&lt;br&gt;
Use it to solve a real problem. Don't test the feature in isolation. Integrate it into an actual workflow you have. If you build a reporting tool, use it to generate a report you actually need. If you build a form, use it to submit real data. The artificiality of "test data" and "test scenarios" hides real friction.&lt;br&gt;
Use it when it's not your focus. Open your feature while you're doing something else. Let it sit in a background tab. Come back to it later. Start a flow, get interrupted, return to it. This reveals what happens when attention is divided, which is how most software gets used.&lt;br&gt;
Deliberately make mistakes. Enter invalid data. Click the wrong button. Hit back in your browser mid-flow. Submit a form twice. Try to do things out of order. Your error handling and validation were designed for these scenarios, but have you experienced them? Does the error message actually help? Can you recover, or is the user stuck?&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Talk to People Who Talk to Users&lt;/strong&gt;&lt;br&gt;
If you can't access users directly, find people who can like Customer success managers, Support engineers, Sales people, Account managers or Product Managers. They hear the complaints, the confusion, the feature requests, the workarounds. They have pattern recognition you don't.&lt;br&gt;
Set up a monthly conversation. Ask:&lt;br&gt;
What questions are you hearing repeatedly?&lt;br&gt;
What features do people struggle with?&lt;br&gt;
What workarounds have users invented?&lt;br&gt;
What do people complain about that isn't getting filed as bugs?&lt;br&gt;
These conversations reveal the gap between your metrics and reality. Your dashboard might show 95% success rate on a feature. Support knows that the other 5% represents hundreds of confused users, but also that many successful uses involve users calling support for help. The feature "worked," but it wasn't usable alone.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Build for Recovery, Not Just Success&lt;/strong&gt;&lt;br&gt;
Every feature you build has three states: working, broken, and unclear. Most development time goes into making things work. Some time goes into handling when things break. Almost no time goes into handling when things are unclear.&lt;br&gt;
Unclear is the most common state:&lt;br&gt;
The user clicked submit. Form is processing. Are we loading? Did it work? Should I wait or try again?&lt;br&gt;
User entered data. Validation failed. What's wrong? Which field? How do I fix it?&lt;br&gt;
The user navigated to a page. Content is loading. How long should this take? Should I refresh?&lt;br&gt;
For every user-facing action in your feature, answer:&lt;br&gt;
What happens while this is processing? Show progress. Show state. Show time estimates if possible.&lt;br&gt;
What happens if this fails? Show a clear error. Explain what went wrong. Suggest a fix.&lt;br&gt;
What happens if this succeeds? Confirm it clearly. Show the outcome. Make the next step obvious.&lt;br&gt;
This isn't just about polish, it's about trust. Users trust systems that communicate clearly. They abandon systems that leave them guessing.&lt;/p&gt;

&lt;p&gt;None of these strategies are individually difficult. What's difficult is doing them consistently, especially under deadline pressure when it feels easier to just build the feature and move on. But this is the work. Empathy isn't a single moment of insight, it's a practice you repeat until it becomes automatic, until you can't build a feature without considering the person who will use it, until their context becomes as real to you as your code.&lt;/p&gt;

&lt;p&gt;Functional code is the baseline, not the achievement. Tests passing, deployments succeeding, features working, these are table stakes. They prove you can write code. They don't prove you've solved anyone's actual problem.&lt;/p&gt;

&lt;p&gt;Engineering empathy isn't about being nicer or more thoughtful or more user-focused in some abstract sense. It's about recognizing that the gap between "it works" and "people can use it" is a technical problem requiring technical solutions. It's about building systems that account for the reality of how they'll actually be used, not the idealized version you imagine while writing code.&lt;br&gt;
It's not secondary to "real" engineering work. It shapes your architecture decisions, your API design, your state management, your error handling, your performance priorities. Every technical choice you make is implicitly a choice about user experience. Making those choices without understanding the experience is building blind.&lt;/p&gt;

&lt;p&gt;When you practice empathy consistently, Your relationship with product and design changes. Conversations stop being adversarial, engineering defending what's "technically feasible" against product defending what's "user-friendly." When you understand user context deeply, you propose better solutions. You identify constraints earlier. You spot mismatches between requirements and reality before they become shipped features. You make different performance tradeoffs when you understand whose time you're optimizing for. You design different third-party APIs when you picture the developer who'll implement against them at 11 PM trying to ship a deadline feature.&lt;/p&gt;

&lt;p&gt;Your velocity changes. Not immediately, at first, slowing down to understand users feels like it's costing you speed. But compounding works in your favor. Six months in, you're not doing rework. You're not fixing confusion. You're not trapped in support escalations. You're building new things while teams without empathy are still fixing old ones.&lt;/p&gt;

&lt;p&gt;Building products that feel good to use isn't about polish or delight or exceeding expectations, though those can be outcomes. It's about building products that get out of people's way. Products where the interface disappears and users accomplish what they actually came to do. Products that respect people's time, attention, and cognitive load. &lt;/p&gt;

&lt;p&gt;"The perfect user" still doesn't exist. There are only actual people with actual constraints trying to accomplish actual tasks. Your job isn't to build for the abstraction. It's to build for them, specifically, concretely, deliberately. To make technical decisions that account for their reality, not just yours.&lt;/p&gt;

&lt;p&gt;That's engineering empathy. Not a soft skill. Not secondary. Not optional. A technical discipline that determines whether what you build actually works in the world, not just in your test suite.&lt;br&gt;
You already know how to write code that compiles. Now build code that people can use.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Oluwaferanmi Adeniji is a Frontend Engineer at Moniepoint Inc&lt;/strong&gt;&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>programming</category>
      <category>beginners</category>
      <category>productivity</category>
    </item>
    <item>
      <title>Design Patterns</title>
      <dc:creator>Bemigho Awala</dc:creator>
      <pubDate>Thu, 18 Sep 2025 14:20:38 +0000</pubDate>
      <link>https://dev.to/bemigho_awala_959f07d23df/design-patterns-4hn6</link>
      <guid>https://dev.to/bemigho_awala_959f07d23df/design-patterns-4hn6</guid>
      <description>&lt;p&gt;&lt;strong&gt;By Iyanuoluwa Faleye&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Design patterns are a collection of standard solutions to solve software development design problems. Software engineers need to know how to use design patterns as essential tools. They can utilize design patterns to discover elegant solutions for commonly occurring challenges in software design, just as architects in building architecture learn to address design difficulties using established patterns. The efficiency, scalability, and readability of code are all improved by comprehending and utilizing these patterns.&lt;/p&gt;

&lt;p&gt;The three categories that these patterns fall into are creational, behavioural, and structural. To keep things brief, we’ll define these categories and explore examples that fall into these categories over a series.&lt;/p&gt;

&lt;p&gt;Creational Pattern: These patterns address procedures for creating objects. They assist in crafting objects in a way that makes sense for the scenario. The simplest method of creating objects may lead to problems with design or more complexity in a design. This issue is resolved by creational design patterns, which regulate the creation process. Some of the popular creational patterns include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Builder&lt;/li&gt;
&lt;li&gt;Factory&lt;/li&gt;
&lt;li&gt;Abstract Factory&lt;/li&gt;
&lt;li&gt;Singleton&lt;/li&gt;
&lt;li&gt;Prototype&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Structural Pattern: The composition of classes and objects is central to structural patterns. They support the formation of complex structures with classes and objects. Structural patterns use inheritance to create interfaces and implementations. Several well-known patterns of structure include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Adapter&lt;/li&gt;
&lt;li&gt;Decorator&lt;/li&gt;
&lt;li&gt;Facade&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Behavioral Pattern: a category of software design patterns that helps control how various system elements communicate and interact. Example includes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Observer&lt;/li&gt;
&lt;li&gt;Strategy&lt;/li&gt;
&lt;li&gt;State&lt;/li&gt;
&lt;li&gt;Iterator&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;We’ll start the series with one of the creational patterns: Singleton.&lt;br&gt;
Singleton Pattern&lt;br&gt;
Singleton pattern ensures that the instance of a class is instantiated once and provides global access to the instance. It is part of the creational design pattern category.&lt;br&gt;
Motivation&lt;br&gt;
When building a system, sometimes we want the system to have access to a shared resource, e.g. a database and a logging system. To make this work as intended, a single instance of an object or resource must exist at a time. Instantiating a constructor would not work because it returns a new instance of an object whenever it is called. Singleton pattern solves for us by ensuring that the regular constructor is called only once under the hood, and that is when it is being created for the first time.&lt;br&gt;
Singleton pattern also provides global access to an object by making an object available everywhere in a program, which helps with;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Consistency: there should be at most one instance of a database in a system; if there is, it would further improve the level of consistency in the application's behaviour.&lt;/li&gt;
&lt;li&gt;It helps to conserve resources&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;It also helps to control the means to access an object.&lt;br&gt;
public class DataBaseService {&lt;/p&gt;

&lt;p&gt;public DataBaseService(){&lt;/p&gt;

&lt;p&gt;}&lt;br&gt;
}&lt;br&gt;
Creating a DataBaseService class like the example above,&lt;br&gt;
every time the class is instantiated, a new instance of the DatabaseService class is created, as shown below, which makes the class inconsistent for the intended use.&lt;br&gt;
dataBase3: singleton.DataBaseService@135fbaa4&lt;br&gt;
dataBase4: singleton.DataBaseService@45ee12a7&lt;br&gt;
This is the implementation of a singleton pattern with respect to multithreaded environments like a Java program. This code below exposes a getInstance() method, which is called when we want to access the DataBaseService object, and it handles creating or providing an existing instance of the DataBaseService object. The private constructor in the class ensures the creation of an object using the regular constructor calling is controlled internally by the class. If dataBaseService is null, the class has not been created before and the regular constructor will be called.&lt;br&gt;
public class DataBaseService {&lt;/p&gt;

&lt;p&gt;private static volatile DataBaseService dataBaseService = null;&lt;/p&gt;

&lt;p&gt;private DataBaseService() {&lt;/p&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;if (dataBaseService != null) {

    throw  new RuntimeException("There can only be one instance of Database");

}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;

&lt;p&gt;public static DataBaseService getInstance() {&lt;/p&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;if (dataBaseService == null){

synchronized (DataBaseService.class) {

    if (dataBaseService == null) {

        dataBaseService = new DataBaseService();

    }

}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;return dataBaseService;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;}&lt;br&gt;
When we want to access the DataBaseService, we simply call the getInstance method, which creates or returns one instance of the class.&lt;br&gt;
DataBaseService dataBaseService1 = DataBaseService.getInstance();&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    DataBaseService dataBaseService2 = DataBaseService.getInstance();

    System.out.println("dataBaseService1: "+ dataBaseService1);

    System.out.println("dataBaseService2: " + dataBaseService2);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;When the two instances are logged, it is evidently the same, which shows that our singleton pattern is properly implemented as shown below.&lt;br&gt;
dataBaseService1: singleton.DataBaseService@135fbaa4&lt;br&gt;
dataBaseService12: singleton.DataBaseService@135fbaa4&lt;br&gt;
Advantages&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;It is sure that there is only one instance of a class.&lt;/li&gt;
&lt;li&gt;You can provide a global instance to a class.
Disadvantages&lt;/li&gt;
&lt;li&gt;Violates single responsibility principles
Use cases
Databases
Logging system
Real-Life Examples
Java Runtime Library
Database connection on Android.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Singleton Pattern's approach to instance control makes it significant, but it's equally crucial to understand its strengths and weaknesses. Here's a link to check the full implementation - &lt;a href="https://github.com/falayy/design-patterns-example/tree/main/src/singleton" rel="noopener noreferrer"&gt;https://github.com/falayy/design-patterns-example/tree/main/src/singleton&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Iyanuoluwa Falaye is an Android Engineer at Moniepoint Inc&lt;/strong&gt;&lt;/p&gt;

</description>
      <category>android</category>
      <category>designpatterns</category>
      <category>mobile</category>
      <category>kotlin</category>
    </item>
    <item>
      <title>The Future of POS Devices in a Connected World</title>
      <dc:creator>Bemigho Awala</dc:creator>
      <pubDate>Thu, 26 Jun 2025 16:35:49 +0000</pubDate>
      <link>https://dev.to/bemigho_awala_959f07d23df/the-future-of-pos-devices-in-a-connected-world-4a4l</link>
      <guid>https://dev.to/bemigho_awala_959f07d23df/the-future-of-pos-devices-in-a-connected-world-4a4l</guid>
      <description>&lt;p&gt;A few years ago, I walked into a small electronics shop in Victoria Island where the cashier was frantically scribbling sales figures into a worn notebook while customers waited in line. Today, that same shop processes payment in seconds, automatically records sales, tracks inventory and gets insights about his best-selling products all through a device that fits in his palm.&lt;/p&gt;

&lt;p&gt;That transformation encapsulates the evolution I’ve closely followed in Africa’s financial space over the last four years. What we once knew as simple card readers have evolved into sophisticated business command centers, and frankly, we're just getting started.&lt;/p&gt;

&lt;p&gt;The future of POS devices lies not just in transactions, but in the ecosystem it enables, a connected platform that brings together advanced technology, integrated services, and actionable data to power smarter, more agile businesses.&lt;br&gt;
What's a POS Device, Anyway? (And Why It Matters)&lt;br&gt;
You might be asking yourself: what exactly makes these devices so special? Let me break it down simply.&lt;/p&gt;

&lt;p&gt;A POS (Point-of-Sale) device is the compact machine you use when you insert or tap your card to pay for anything, from suya at a street corner to clothes at a boutique. It's the invisible bridge connecting your bank account to a business's cash flow, making transactions faster and infinitely more secure than cash exchanges.&lt;/p&gt;

&lt;p&gt;The old generation of POS machines were painfully limited. They could barely keep up with the pace of modern business. They existed in complete isolation from the broader operations of a business, functioning more like digital cash registers than actual tools of business intelligence.&lt;/p&gt;

&lt;p&gt;Fast forward to today, POS devices have undergone a major transformation. Modern POS devices are no longer standalone gadgets; they are smart, connected ecosystems. They accept a wide range of payment methods, from debit and credit cards to mobile wallets and bank transfers.  Contactless payments, once considered a premium feature, are now expected as standard.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fadoalo50n4v8cctbhtzn.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fadoalo50n4v8cctbhtzn.png" alt="Image description" width="800" height="514"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;These devices now integrate directly with inventory systems, automatically updating stock levels after each sale. This means a business owner can track what's selling, what's not, and when to restock all without manually entering figures. &lt;/p&gt;

&lt;p&gt;Modern POS devices are built with reliability in mind, especially for markets like Nigeria, where internet connectivity can be low. These smart terminals are designed to function efficiently even in areas with low or unstable network coverage.&lt;/p&gt;

&lt;p&gt;Looking ahead, the future of POS devices is even more exciting. We’re entering an era where artificial intelligence (AI) will help POS devices predict customer needs and recommend restocks. Quantum-secure encryption will make digital transactions nearly unbreakable. And with global connectivity, even the smallest business in Lagos or Kaduna can process international payments as easily.&lt;br&gt;
From Card Readers to Business Brains&lt;br&gt;
Modern POS devices have evolved far beyond simple payment terminals. Today, they’re powerful mini-computers that manage and streamline entire business operations.&lt;/p&gt;

&lt;p&gt;Consider a single transaction in 2025:&lt;br&gt;
The payment processes instantly. &lt;br&gt;
Inventory updates automatically. &lt;br&gt;
Customer data flows straight into CRM systems. &lt;br&gt;
Sales analytics refresh in real-time.&lt;br&gt;
 Accounting software logs the transaction&lt;/p&gt;

&lt;p&gt;All happening simultaneously without a single spreadsheet or manual entry.&lt;/p&gt;

&lt;p&gt;The customisation potential is incredible.&lt;br&gt;
Businesses can now integrate loyalty programs, dynamic pricing models, promotional campaigns, and even customer feedback systems, all within their POS interface.&lt;/p&gt;

&lt;p&gt;A restaurant can automatically apply time-based discounts during off-peak hours to encourage traffic. Meanwhile, businesses can leverage SDKs provided by their payment platforms to build custom POS applications.&lt;/p&gt;

&lt;p&gt;This hands-on customisation empowers even small businesses to tailor their systems to fit operational needs and customer preferences without being locked into a one-size-fits-all solution.&lt;/p&gt;

&lt;p&gt;Integration capabilities have exploded.&lt;br&gt;
Modern POS systems now sync seamlessly with e-commerce platforms, delivery services, social media marketing tools, and financial software. &lt;/p&gt;

&lt;p&gt;One transaction can:&lt;br&gt;
Trigger inventory alerts&lt;br&gt;
Launch customer retention campaigns&lt;br&gt;
Automatically reorder from suppliers&lt;/p&gt;

&lt;p&gt;Business intelligence is now effortless&lt;br&gt;
The most exciting part? Small business owners now have access to enterprise-level business intelligence without needing IT teams or costly software. They’re making smarter, data-driven decisions about inventory, pricing, and customer service, right from their counter.&lt;br&gt;
What This Means for Businesses and Customers&lt;br&gt;
I’ve been having some interesting conversations lately with small business owners, and one thing keeps coming up: how much technology has changed the game for them.&lt;/p&gt;

&lt;p&gt;It’s easy to assume that big corporations still have all the advantages, like access to data, customer insights, automated systems, and everything else that used to cost a fortune. But here’s the truth: those tools aren’t just for the big players anymore. With a modern Point of Sale (POS) device, small and medium enterprises (SMEs) can now access the kind of powerful features that used to be reserved for companies with million-dollar budgets.&lt;/p&gt;

&lt;p&gt;Take Kemi, for example. She runs a stylish little fashion boutique in Abuja. A few years ago, she would’ve had to rely on guesswork and gut instinct to manage inventory and understand her customers. &lt;br&gt;
Today, her POS device system tells her:&lt;br&gt;
What products are in high demand at different times of the year&lt;br&gt;
Who her top-spending customers are&lt;br&gt;
When and how to send personalized discount offers to bring them back in.&lt;/p&gt;

&lt;p&gt;Kemi is now able to compete with major fashion retailers, but she’s doing it with tech that’s affordable, easy to use, and incredibly efficient. &lt;/p&gt;

&lt;p&gt;Another thing I keep hearing is how much time these systems are saving business owners. Hours that were once spent doing tedious inventory updates or trying to figure out customer trends are now handled automatically. That’s more time for what really matters: growing the business, connecting with customers, and building a brand.&lt;/p&gt;

&lt;p&gt;And the customer experience is on another level. People want fast, secure, and smooth shopping whether it’s online or in person. Modern POS devices  make checkouts lightning-quick. They help businesses offer personalized service based on past purchases. And because everything syncs across online and offline channels, customers get a seamless experience every time.&lt;/p&gt;

&lt;p&gt;All this just goes to show that we’re in a new era of entrepreneurship. You don’t need to be a tech giant to have smart tools. You just need the right system and a vision.&lt;br&gt;
The Future Is Bright (and Connected)&lt;br&gt;
The POS devices of tomorrow won’t just sit on counters they’ll be everywhere, embedded into the environment and making commerce seamless and intelligent.&lt;/p&gt;

&lt;p&gt;Ambient Commerce: Imagine walking into a store where your POS interaction happens without you even noticing. Biometric sensors will recognize you, AI will predict your needs, and payment will occur automatically as you leave with your items. The POS becomes invisible but infinitely more powerful.&lt;/p&gt;

&lt;p&gt;Predictive Business Intelligence: Future POS devices will use advanced machine learning to forecast market trends weeks in advance. A small retailer will know exactly what to stock based on market patterns, social media trends, and economic indicators all processed in real-time through their POS ecosystem.&lt;/p&gt;

&lt;p&gt;Global Marketplace Integration: Picture this: a street vendor in Lagos instantly accepting payments from a visitor from Tokyo, with automatic currency conversion, tax calculation, and compliance handling. The POS will become a gateway to the global economy for every business, regardless of size.&lt;/p&gt;

&lt;p&gt;Quantum-Secured Transactions: As quantum computing emerges, POS devices will integrate quantum encryption that makes current security methods look elementary. Every transaction will be mathematically impossible to hack.&lt;/p&gt;

&lt;p&gt;Autonomous Business Management: The most exciting possibility is that POS devices will run businesses autonomously. They'll handle inventory, customer service, marketing, and strategic decisions with minimal human intervention. Entrepreneurs will become conductors of AI-powered business orchestras.&lt;br&gt;
Final Thoughts: A Quiet Revolution in the Palm of Your Hand&lt;br&gt;
The blend of 5G, edge computing, and AI will enable real-time processing power that transforms every transaction into a data point for immediate business optimization.&lt;/p&gt;

&lt;p&gt;As someone deeply involved in shaping these systems, I'm thrilled about what's coming next. The humble POS device has evolved into a powerful tool of empowerment. It’s helping everyday entrepreneurs automate complex processes, make informed decisions, and compete on a whole new level.&lt;/p&gt;

&lt;p&gt;So the next time you tap your card or phone to make a purchase, remember that behind that simple interaction lies a sophisticated ecosystem of real-time data processing, intelligent business logic, and seamless connectivity that's transforming commerce globally.&lt;/p&gt;

&lt;p&gt;And the best part? We're just getting started.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Olorunferanmi Joel, is a Product Manager, at Moniepoint inc&lt;/strong&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  POS #programming #fintech
&lt;/h1&gt;

</description>
    </item>
  </channel>
</rss>
