<?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>Forem: xh1m</title>
    <description>The latest articles on Forem by xh1m (@xh1m).</description>
    <link>https://forem.com/xh1m</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%2F3820283%2F05168b70-121d-4568-8721-989c2b630105.jpg</url>
      <title>Forem: xh1m</title>
      <link>https://forem.com/xh1m</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/xh1m"/>
    <language>en</language>
    <item>
      <title>The Architect’s Manifesto 2026: Engineering in the Age of Autonomy 🌐</title>
      <dc:creator>xh1m</dc:creator>
      <pubDate>Sat, 14 Mar 2026 15:09:06 +0000</pubDate>
      <link>https://forem.com/xh1m/the-architects-manifesto-2026-engineering-in-the-age-of-autonomy-54dc</link>
      <guid>https://forem.com/xh1m/the-architects-manifesto-2026-engineering-in-the-age-of-autonomy-54dc</guid>
      <description>&lt;p&gt;For years, software engineering was a game of control. We controlled the state, the memory, and the flow. But as we move deeper into 2026, the industry is pivoting toward Orchestration. We are no longer just writing instructions; we are managing ecosystems of autonomous agents and distributed data.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;1. The Decentralisation of Logic:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Edge Computing &amp;amp; SLMs&lt;/em&gt;&lt;br&gt;
The "Cloud First" era is being challenged by the "Edge Native" movement. In your early units, you likely learned about the Client-Server model. You send data to a massive data centre (The Cloud), it processes, and sends it back.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;The 2026 Shift:&lt;/em&gt;&lt;br&gt;
We are moving the "Brain" closer to the user. This is Edge Computing.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;The Problem:&lt;/em&gt;&lt;br&gt;
Sending massive amounts of data to a central server creates Latency and High Bandwidth Costs.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;The Solution:&lt;/em&gt;&lt;br&gt;
Small Language Models (SLMs).&lt;/p&gt;

&lt;p&gt;While the massive LLMs require an entire farm of GPUs, SLMs are small, distilled versions of AI that can run on standard hardware. When considering my Dell Vostro, that’s a game-changer. While my integrated AMD graphics might struggle to handle the 70 billion parameter LLM, it should be perfectly fine for the highly specialized 3 billion parameter “Micro-LLM.”&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%2Fcxvc52zi2pmqlm987iho.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%2Fcxvc52zi2pmqlm987iho.png" alt=" " width="800" height="678"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;2. From DevOps to AI-Native SDLC ⚙️&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;You’ve probably covered the Waterfall vs. Agile debate in your Professional Practice units. But in 2026, we are talking about the AI-Native Software Development Life Cycle (SDLC).&lt;/p&gt;

&lt;p&gt;This is where "Agentic Engineering" becomes the norm. Instead of a single "AI Assistant" that helps you write a function, you are managing a Fleet of Agents:&lt;/p&gt;

&lt;p&gt;&lt;em&gt;The Feature Architect:&lt;/em&gt; &lt;br&gt;
Drafts the structural logic and interface definitions.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;The Test Generator:&lt;/em&gt;&lt;br&gt;
Automatically creates property-based and edge-case tests.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;The Security Auditor:&lt;/em&gt; &lt;br&gt;
Constant scanning for vulnerabilities and "hallucinated" dependencies.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;The Documentation Agent:&lt;/em&gt; &lt;br&gt;
Ensures the README.md and technical specs are updated in real-time.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Your Role:&lt;/em&gt;&lt;br&gt;
You are the Human-in-the-Loop (HITL). Your job isn't to write the for loop anymore; it’s to provide the Governance. You are the one who decides if the agent's proposal matches the Business Requirements.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;3. The "Shift Up": High-Level Design Takes Focus 🏗️&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;As we leave the tedium of syntax fixes to the AI, the engineering world is shifting our focus upwards in abstraction.&lt;/p&gt;

&lt;p&gt;In your Object-Oriented Programming (OOP) section, you still learn about encapsulation and inheritance. They are important concepts, yet by 2026, we are applying these concepts to systems, not just to code.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Micro Frontends:&lt;/em&gt;&lt;br&gt;
Break down the web application into independent, self-contained units.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Micro Services:&lt;/em&gt;&lt;br&gt;
Break down the backend to the point where if "Payment Agent" fails, "User Profile Agent" will not fail.&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%2F5w1a11cmxj7qyexnbf7a.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%2F5w1a11cmxj7qyexnbf7a.png" alt=" " width="800" height="611"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;To achieve a Distinction grade for your Graded Unit, you must demonstrate the modularity of your system. Showing the ability to replace a single component of your system without affecting the other components demonstrates your achievement of Professional-Level Architecture.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;4. Sustainable Software Engineering: The Green Code Mandate 🌿&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;It’s an area that students may not pay enough attention to, but for 2026 recruiters, it’s a highly desirable skill. &lt;em&gt;Why?&lt;/em&gt; Well, software has a footprint, and the truth is that training and executing massive AI models consumes a tremendous amount of power. In the HND, your Professional Practice and Emerging Technologies modules now incorporate a ‘Sustainability’ perspective. Green coding principles to keep in mind:&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Computational Efficiency:&lt;/em&gt;&lt;br&gt;
 O(1) isn’t just fast; it’s battery life. An inefficient O(N^2) algorithm on a billion mobile devices is an ecological catastrophe.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Carbon Aware Computing:&lt;/em&gt; &lt;br&gt;
Design software that runs computationally intensive jobs when the power grid is renewable, using tools such as the Carbon Aware SDK.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Asset Optimisation:&lt;/em&gt; &lt;br&gt;
Reduce the weight of your webpage and use efficient caching to reduce the load on the data center.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;5. Cybersecurity: The New Battlefront of Agentic Attacks 🛡️&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Cybersecurity is more than simply fighting "SQL Injections" (though that’s important knowledge for your Database section). By 2026, the threat is no longer the "script kiddie" or the cyber-terrorist. It’s the Autonomous Adversary.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The New Threats:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Shadow AI:&lt;/em&gt;&lt;br&gt;
Employees use unauthorized external AI models that leak confidential company information.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Prompt Injection:&lt;/em&gt;&lt;br&gt;
Cyber attackers exploit your AI agent to bypass security protocols and access the content of your database.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Supply Chain Hallucination:&lt;/em&gt;&lt;br&gt;
Cyber attackers insert malware into open-source software that your AI might use as a solution.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;The Solution:&lt;/em&gt;&lt;br&gt;
DevSecOps. You have to shift security left. Every action your agentic system takes should be logged, explained, and reversible.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;6. Strategy for Your Graded Unit: The Roadmap to Distinction 🎓&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;While you’re waiting for the feedback and you have some time in the Block Week, here is the plan of action on how you can transform these ideas into a good project.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Explain the “Why”:&lt;/em&gt; &lt;br&gt;
Explain the Decision Matrix. Explain why you used Python instead of C# for the AI part of the project. Explain why you used a certain database normalization scheme.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Show the Guardrails:&lt;/em&gt; &lt;br&gt;
If you used AI in your project, show the Safety Layer. Explain how you prevent the AI from running a DROP TABLE command.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Sustainability Statement:&lt;/em&gt;&lt;br&gt;
Explain how you made the project more sustainable in terms of resources. It is a small part of the project that shows you are a professional.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Unit Testing is Non-Negotiable:&lt;/em&gt;&lt;br&gt;
As previously discussed, unit testing is the best way to impress the tutor or the recruiter.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>programming</category>
      <category>systemdesign</category>
      <category>learning</category>
    </item>
    <item>
      <title>The "Vibe Coding" Reality Check: Are You Actually Engineering or Just Prompting? 🚀</title>
      <dc:creator>xh1m</dc:creator>
      <pubDate>Sat, 14 Mar 2026 14:46:01 +0000</pubDate>
      <link>https://forem.com/xh1m/the-vibe-coding-reality-check-are-you-actually-engineering-or-just-prompting-1186</link>
      <guid>https://forem.com/xh1m/the-vibe-coding-reality-check-are-you-actually-engineering-or-just-prompting-1186</guid>
      <description>&lt;p&gt;The term "Vibe Coding" is often used by developers. It means that the developer uses their big AI tools in a way that they are "describing the vibes" of an app and are able to make large amounts of code instantaneously. This is great for getting the app to market, but it leaves open the possibility that code that looks right is not architecturally correct.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The Foundations vs. The Shortcuts 🧠&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;In the professional development process, how we deal with logic changes in steps:&lt;/p&gt;

&lt;p&gt;&lt;em&gt;The Syntax Phase:&lt;/em&gt;&lt;br&gt;
This is where we learn the syntax of the language, how to write a for loop in Java, how to connect to Oracle SQL, etc. At this stage, the role of the AI is that of a super smart autocomplete.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;The Architecture Phase:&lt;/em&gt; &lt;br&gt;
This is where the real engineering takes place. It’s where we reason about why we prefer one way over another. If we have an app that’s super “slick” and “vibe-coded” but uses a transitive dependency that violates Database Normalisation, then the app remains shaky even though it looks nice on the outside.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Why Vibes Don’t Cut It in Production🏗️&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The problem with relying solely on auto-generated code is that it does not reveal how it’s generated. While an executable code is essential in production, the real challenge lies in making it maintainable.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;The Vibe trap is real.&lt;/em&gt; The tendency of AI code is to only work on the “happy path.” The “happy path” is where everything goes right.&lt;/p&gt;

&lt;p&gt;Vibes-only coding might get you a login screen that works.&lt;/p&gt;

&lt;p&gt;An engineer might build a login screen that’s not only functional but also includes BCrypt for password hashing, try-catch for database timeouts, and an MVC structure with validation.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The Plan: Augment, Don’t Replace 🛠️&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;To use AI to improve our engineering advantage, we should strive to establish a consistent and disciplined process:&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Pseudocode First:&lt;/em&gt; &lt;br&gt;
Before we ask the AI, let’s try to write the logic out in plain English or with a basic flowchart. If the logic is indescribable, then we’re unlikely to engineer it well.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;The Line-by-Line Rule:&lt;/em&gt;&lt;br&gt;
Don’t write code that you can’t describe in excruciating detail. If the generated lambda is confusing, then take a moment to understand how it works at a basic level.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Architectural Refactoring:&lt;/em&gt;&lt;br&gt;
AI tools seem to favor “monolithic” code blocks. Use the principle of Separation of Concerns to divide the code into separate, more digestible parts.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Final Thought: Keep the Architect in the Loop 🏢&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The idea is to work smarter, not harder. Let AI handle the boilerplates and repetitive tasks, but retain ownership of System Design and Architectural Strategy. This way, your portfolio - and your career rests on actual engineering prowess rather than your ability to quickly prompt AI.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>promptengineering</category>
      <category>vibecoding</category>
      <category>programming</category>
    </item>
    <item>
      <title>Sleep Better at Night: Why Unit Testing is Your Secret Weapon for Graded Units 🛡️</title>
      <dc:creator>xh1m</dc:creator>
      <pubDate>Thu, 12 Mar 2026 15:56:58 +0000</pubDate>
      <link>https://forem.com/xh1m/sleep-better-at-night-why-unit-testing-is-your-secret-weapon-for-hnd-graded-units-4ce6</link>
      <guid>https://forem.com/xh1m/sleep-better-at-night-why-unit-testing-is-your-secret-weapon-for-hnd-graded-units-4ce6</guid>
      <description>&lt;p&gt;Let’s be frank: Most students treat Unit Testing as much as the terms and conditions of a software project - presented to be there, to be ignored, to be quickly scanned to the end in hopes that something good is to be found.&lt;/p&gt;

&lt;p&gt;When you are studying Software Engineering or Quality Assurance courses, testing is what separates a Pass from a Distinction. &lt;em&gt;Why?&lt;/em&gt; Anyone can write code that works as long as everything is aligned. A Lead Developer is someone who writes code that still works as long as a user decides to type their name in a field labeled “Phone Number.”&lt;/p&gt;

&lt;p&gt;&lt;em&gt;What is Unit Testing?&lt;/em&gt;&lt;br&gt;
Unit testing is testing a small piece of code, called a unit or a function. For us Java programmers, we use JUnit to accomplish this.&lt;/p&gt;

&lt;p&gt;Rather than running the entire application, logging in, and manually clicking through to verify that the CRUD wrapper is working (which is a slow and flaky process), you write a script that does all these tests for you in a matter of milliseconds.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Three Ways to Show Distinction 🏆&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;When you write the Graded Unit, instead of just showing a single test, you must show a “Test Suite” with three different cases:&lt;/p&gt;

&lt;p&gt;&lt;em&gt;1. The Happy Path (Works)&lt;/em&gt;&lt;br&gt;
The happy path is where everything works. So, if I pass a StudentID to deleteUser(), does it return true?&lt;/p&gt;

&lt;p&gt;What to achieve with the test:&lt;br&gt;
Test if the core function works.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;2. The Edge Case (What If)&lt;/em&gt;&lt;br&gt;
What if I pass a null or empty StudentID? Does it crash with a NullPointerException, or does it handle it well?&lt;/p&gt;

&lt;p&gt;What to achieve with the test:&lt;br&gt;
Test if the code is robust.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;3. The Fail Case (Wrong Type)&lt;/em&gt;&lt;br&gt;
What if I pass a string to a function expecting an integer? Does the exception handling work well?&lt;/p&gt;

&lt;p&gt;What to achieve with the test:&lt;br&gt;
Test if the guardrails are in place.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The Java Example: Testing Your CRUD Wrapper 💻&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Let’s take a look at how you would write a simple test for the Java CRUD Wrapper, a topic we discussed earlier in this post and in detail on another post.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;org.junit.jupiter.api.Test&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;static&lt;/span&gt; &lt;span class="n"&gt;org&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;junit&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;jupiter&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;api&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;Assertions&lt;/span&gt;&lt;span class="o"&gt;.*;&lt;/span&gt;

&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;DatabaseTest&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

    &lt;span class="c1"&gt;// 1. Happy Path&lt;/span&gt;
    &lt;span class="nd"&gt;@Test&lt;/span&gt;
    &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;testConnectionSuccess&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="nc"&gt;DatabaseWrapper&lt;/span&gt; &lt;span class="n"&gt;db&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;DatabaseWrapper&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
        &lt;span class="n"&gt;assertTrue&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;connect&lt;/span&gt;&lt;span class="o"&gt;(),&lt;/span&gt; &lt;span class="s"&gt;"Database should connect successfully with valid credentials."&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

    &lt;span class="c1"&gt;// 2. Edge Case&lt;/span&gt;
    &lt;span class="nd"&gt;@Test&lt;/span&gt;
    &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;testEmptyQuery&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="nc"&gt;DatabaseWrapper&lt;/span&gt; &lt;span class="n"&gt;db&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;DatabaseWrapper&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
        &lt;span class="n"&gt;assertThrows&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;IllegalArgumentException&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;class&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;executeQuery&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;""&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// Should not allow empty strings&lt;/span&gt;
        &lt;span class="o"&gt;});&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

    &lt;span class="c1"&gt;// 3. Fail Case&lt;/span&gt;
    &lt;span class="nd"&gt;@Test&lt;/span&gt;
    &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;testInvalidUserDelete&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="nc"&gt;DatabaseWrapper&lt;/span&gt; &lt;span class="n"&gt;db&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;DatabaseWrapper&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
        &lt;span class="c1"&gt;// Testing a non-existent ID should return false, not crash&lt;/span&gt;
        &lt;span class="n"&gt;assertFalse&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;deleteUser&lt;/span&gt;&lt;span class="o"&gt;(-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;),&lt;/span&gt; &lt;span class="s"&gt;"Should return false for non-existent IDs."&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Why Tutors Lecturers Love This 🎓&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;If your tutor spots a test folder within your project, you've already won half the battle. This shows you're interested in &lt;em&gt;Maintainability.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;If you decide to refactor your code (for instance, from a local Oracle DB to a Cloud-based one), you can run your tests to ensure your logic is working correctly. This is called 'Lead Dev' thinking. This converts your documentation from a list of features to a &lt;em&gt;Technical Report&lt;/em&gt; that shows your application is ready for production.&lt;/p&gt;

</description>
      <category>testing</category>
      <category>java</category>
      <category>softwaredevelopment</category>
      <category>database</category>
    </item>
    <item>
      <title>Building Your First Simple AI Agent in Python: An Introduction Guide to Intelligent Logic 🤖</title>
      <dc:creator>xh1m</dc:creator>
      <pubDate>Thu, 12 Mar 2026 15:10:40 +0000</pubDate>
      <link>https://forem.com/xh1m/building-your-first-simple-ai-agent-in-python-an-introduction-guide-to-intelligent-logic-24jf</link>
      <guid>https://forem.com/xh1m/building-your-first-simple-ai-agent-in-python-an-introduction-guide-to-intelligent-logic-24jf</guid>
      <description>&lt;p&gt;Don’t chase the hype. If you’ve spent the last two or three years of your studies creating CRUD applications, then you already have the basic building blocks. An AI Agent isn’t magical – it’s simply a &lt;em&gt;smart wrapper&lt;/em&gt; around the code you already know how to write. &lt;/p&gt;

&lt;p&gt;Think about it. Your Visual Studio and NetBeans projects have already been creating Reactive systems. A user clicks on a button and some function is called. But an AI Agent is Proactive. It doesn’t just call the function - it decides which function to call based on the goal that’s been set. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The Architecture of an AI Agent&lt;br&gt;
Perception ➡️ Thought ➡️ Action 🧠&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;In the professional world, the flow of an AI Agent’s activities is called a loop. This is basic Software Engineering and directly maps to the rubric of the unit on System Analysis and the unit on Advanced Programming. &lt;/p&gt;

&lt;p&gt;&lt;em&gt;The Brain (The LLM):&lt;/em&gt; &lt;br&gt;
This is your Large Language Model (LLM), similar to GPT-4 or Llama 3. This isn’t something that “knows” anything - it’s simply logic. &lt;/p&gt;

&lt;p&gt;&lt;em&gt;The Tools (Your Functions):&lt;/em&gt; &lt;br&gt;
This is the set of Python functions that you’ve learned how to program. A function to access an Oracle SQL database, a function to check the weather, or a function to send an email. &lt;/p&gt;

&lt;p&gt;&lt;em&gt;The Loop (The Agentic Cycle):&lt;/em&gt; &lt;br&gt;
This is the “While Loop” that the AI Agent will execute until the goal is met.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The Student Level Use Case: The Smart Library Assistant 📚&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Here is a simple example of a basic "Library Management System".&lt;/p&gt;

&lt;p&gt;&lt;em&gt;The Traditional CRUD Process:&lt;/em&gt;&lt;br&gt;
A user enters the word "Peaceful" into the search box. Your SQL code will be executed as follows: SELECT * FROM Books WHERE Title LIKE '%Peaceful%'. If no book contains the word "Peaceful" in the title, the user will be presented with no search results.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;The AI Agent&lt;/em&gt;&lt;br&gt;
The user says to the AI Agent: "I've had a really stressful day at college. Find me something to help me relax."&lt;/p&gt;

&lt;p&gt;&lt;em&gt;The Agentic Process - Perception&lt;/em&gt;&lt;br&gt;
The AI Agent "sees" the user's input.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Thought&lt;/em&gt;&lt;br&gt;
The "Brain" of the AI recognises that the user is stressed and needs to be presented with topics related to "relaxation."&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Action&lt;/em&gt;&lt;br&gt;
The AI Agent will execute your search_database() function using its own set of keywords, such as "Meditation," "Nature Photography," or "Fiction."&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The Tech Stack: Lead Dev Approved 🛠️&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;You don’t need to use high-end hardware for the Artificial Intelligence and Data Science unit. A standard setup, such as a Dell Vostro which I use, with lightweight APIs is fine.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Python:&lt;/em&gt;&lt;br&gt;
This is the main industry standard for AI.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Claude/OpenAPI:&lt;/em&gt; &lt;br&gt;
This is the “Brain.” Using an API prevents a bottleneck from my AMD integrated graphics.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;LangChain:&lt;/em&gt;&lt;br&gt;
This is a library to help you link ideas together. This library handles prompt engineering and tool calling logic, allowing you to focus on the structure.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The Code: Defining Your First Tool 💻&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;In an agent-based system, your tools are just Python functions with a clear description. This is an important part, as the LLM reads this to determine when to use the function.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;#a standard college level function (the tool)
&lt;/span&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;query_library_database&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;search_term&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="sh"&gt;"""&lt;/span&gt;&lt;span class="s"&gt;
    Queries the library SQL database for books based on a keyword.
    Use this when the user is looking for specific reading material.
    &lt;/span&gt;&lt;span class="sh"&gt;"""&lt;/span&gt;
    &lt;span class="c1"&gt;# Imagine your Oracle SQL connection logic here
&lt;/span&gt;    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Searching database for: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;search_term&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;The Art of Stillness&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Nature Walks in Scotland&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Why this is important for your Graded Unit 🎓&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;When you write this for your project, you are not just writing “I used AI.” What you are doing is showing Abstraction. What you are doing is applying the Single Responsibility Principle by keeping the “Reasoning” part separate from the “Execution” part.&lt;/p&gt;

&lt;p&gt;If the user wants to search for books, the LLM is responsible for the goal, and your Python is responsible for the data, keeping your application secure and predictable.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>python</category>
      <category>datascience</category>
      <category>learning</category>
    </item>
    <item>
      <title>Beyond the Logic: Transitioning from Software Dev to AI &amp; Data Science 🤖</title>
      <dc:creator>xh1m</dc:creator>
      <pubDate>Thu, 12 Mar 2026 14:10:09 +0000</pubDate>
      <link>https://forem.com/xh1m/beyond-the-logic-transitioning-from-hnd-software-dev-to-ai-data-science-4jm3</link>
      <guid>https://forem.com/xh1m/beyond-the-logic-transitioning-from-hnd-software-dev-to-ai-data-science-4jm3</guid>
      <description>&lt;p&gt;If you have spent the last couple of years of HNC/HND studies honing your skills in OOP, MVC, and the art of building standard CRUD applications, chances are good that you are familiar with a world of "If/Then" logic. &lt;/p&gt;

&lt;p&gt;You define the rules, and the computer follows them. However, as you begin your journey in Data Science, the script changes. Suddenly, instead of defining the rules and feeding them into the computer, you are feeding the computer the data and letting it discover the rules on its own.&lt;/p&gt;

&lt;p&gt;As an HND student, the transition from traditional programming into AI does not require a PhD in Mathematics; it requires a paradigm shift in how you perceive the data.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The Shift: From Static Databases to Predictive Models 📊&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;In a standard HND project, your SQL Database is a storage locker: you put stuff in; you get stuff out. In Data Science, the exact same database becomes a goldmine of hidden patterns.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Software Development:&lt;/em&gt; You write a function to determine a discount if a user has a "Premium" status in the database.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;AI/Data Science:&lt;/em&gt; You feed a model thousands of past transactions and have it predict which users will likely be "Premium" next month.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Core HND Concepts in the AI World 🧠&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The good news is that you don’t have to forget everything you have learned in your units. In fact, your HND background is probably your greatest strength.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;OOP (Object Oriented Programming):&lt;/em&gt; Most of the work in Artificial Intelligence programming happens in Python. Your understanding of Classes and Objects becomes crucial as you start using libraries like Scikit-Learn or PyTorch.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;CRUD &amp;amp; Data Integrity:&lt;/em&gt; You can’t have Artificial Intelligence with Bad Data. Your understanding of Database Normalization and SQL ensures that the data fed into an Artificial Intelligence model is good, clean, and consistent.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Algorithms:&lt;/em&gt; Do you remember Big O Notation? Well, in Artificial Intelligence programming, the only thing that matters is efficiency above all else. If you are trying to process a dataset with millions of rows of data, it needs to be an O(n) operation. If your data preprocessing script runs at an O(n²) operation, forget about training the model in a reasonable time - &lt;em&gt;it’ll take days rather than minutes!&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Getting Started: The Python &amp;amp; SQL Power Couple 🛠️&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;If your academic path is meandering into Data Science, your best bet is to learn the Python ecosystem. You may be comfortable with languages like C# or Java from your current coursework, but Python is the lingua franca of AI.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Pandas:&lt;/em&gt; Think of this as "SQL for Python." It allows you to manipulate data frames as effortlessly as you query an Oracle table.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;NumPy:&lt;/em&gt; This is where you perform the heavy-duty math operations (Linear Algebra) that are happening behind the scenes of every AI model.&lt;/p&gt;

&lt;p&gt;_Matplotlib/Seaborn: _This is where raw data comes alive as the visualizations that Lead Developers and Stakeholders care about.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Final Academic Advice 🎓&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;When you begin your HND Graded Unit or your final projects, try to incorporate a "Predictive" element into your project. Instead of simply creating a library management system that tracks books (CRUD operations), could you incorporate a Python script that recommends a book to a user based on their history? &lt;em&gt;That is how you become a Software Developer turned Data Scientist.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>machinelearning</category>
      <category>datascience</category>
      <category>python</category>
    </item>
    <item>
      <title>From ERD to SQL: Implementing a Normalised Database Step-by-Step</title>
      <dc:creator>xh1m</dc:creator>
      <pubDate>Thu, 12 Mar 2026 13:54:25 +0000</pubDate>
      <link>https://forem.com/xh1m/from-erd-to-sql-implementing-a-normalised-database-step-by-step-3igk</link>
      <guid>https://forem.com/xh1m/from-erd-to-sql-implementing-a-normalised-database-step-by-step-3igk</guid>
      <description>&lt;p&gt;If you’re working towards a Degree in Computer Science or Software Development, I bet you have looked at a messy spreadsheet and have heard someone say, “Normalise it.” It might sound like some boring academic exercise, but it is, in fact, the most important skill in a Database Developer’s arsenal.&lt;/p&gt;

&lt;p&gt;The biggest challenge seems to be when you go from designing a diagram (ERD) into an actual SQL database. You get the general idea, but making it into solid SQL statements with all the appropriate Primary and Foreign Keys can be like trying to assemble a jigsaw puzzle without all the pieces.&lt;/p&gt;

&lt;p&gt;Today, we’re going to cut through all the technical jargon and show, in very basic steps, how we can take a messy data sample and turn it into a beautiful, clean, 3NF-compliant Oracle SQL Database.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The "Messy" Starting Point: Unnormalised Form (UNF) 🗑️&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Imagine we are building a database for a local college. We start with a flat file or a spreadsheet that looks like this:&lt;br&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%2Fkuszhbjr4ru5o42j2qcm.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%2Fkuszhbjr4ru5o42j2qcm.png" alt=" " width="800" height="257"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This is a nightmare. We have Redundancy (John Smith’s name is repeated) and Update Anomalies (If Dr. Brown leaves, we have to change the name in every single row).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 1: 1NF (Atomic Values &amp;amp; Unique Keys) ⚛️&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;To reach First Normal Form (1NF), we must ensure every cell contains a single value (atomicity) and that every row is unique.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Rule: No repeating groups or multi-valued attributes.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Result: Our table is technically in 1NF because each cell has one value, but the redundancy is still there. We identify our Composite Primary Key: StudentID + CourseID.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 2: 2NF (Removing Partial Dependencies) ✂️&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This is where students often struggle and where I did when i first learned the concept. Second Normal Form (2NF) is about making sure every non-key column depends on the entire Primary Key.&lt;/p&gt;

&lt;p&gt;In our 1NF table, StudentName only depends on StudentID. It doesn't care about the CourseID. This is a Partial Dependency.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Action: We break the table apart.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Table 1 (Student): StudentID (PK), StudentName.&lt;/p&gt;

&lt;p&gt;Table 2 (Course_Enrollment): StudentID (FK), CourseID (FK), Grade.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 3: 3NF (Removing Transitive Dependencies) 🧹&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Now we look at Third Normal Form (3NF). Here, we remove Transitive Dependencies. This means a non-key column shouldn't depend on another non-key column.&lt;/p&gt;

&lt;p&gt;In our current structure, LecturerName depends on CourseID, but CourseName also depends on CourseID. If the lecturer is tied to the course, we need to move them out to keep the data clean.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Final Entities:&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Student: ID, Name.&lt;/p&gt;

&lt;p&gt;Course: ID, Title, LecturerID.&lt;/p&gt;

&lt;p&gt;Lecturer: ID, Name.&lt;/p&gt;

&lt;p&gt;Enrollment: StudentID, CourseID, Grade.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The Translation: From Logic to SQL 🛠️&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Now that we have our clean, 3NF logic, we need to write the Oracle SQL to build it. As a Lead Developer, I expect to see strict constraints to protect Data Integrity.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;1. The Student Table&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;CREATE&lt;/span&gt; &lt;span class="k"&gt;TABLE&lt;/span&gt; &lt;span class="n"&gt;Student&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;StudentID&lt;/span&gt; &lt;span class="nb"&gt;INT&lt;/span&gt; &lt;span class="k"&gt;PRIMARY&lt;/span&gt; &lt;span class="k"&gt;KEY&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;StudentName&lt;/span&gt; &lt;span class="n"&gt;VARCHAR2&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;NOT&lt;/span&gt; &lt;span class="k"&gt;NULL&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;em&gt;2. The Lecturer Table&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;CREATE&lt;/span&gt; &lt;span class="k"&gt;TABLE&lt;/span&gt; &lt;span class="n"&gt;Lecturer&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;LecturerID&lt;/span&gt; &lt;span class="nb"&gt;INT&lt;/span&gt; &lt;span class="k"&gt;PRIMARY&lt;/span&gt; &lt;span class="k"&gt;KEY&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;LecturerName&lt;/span&gt; &lt;span class="n"&gt;VARCHAR2&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;NOT&lt;/span&gt; &lt;span class="k"&gt;NULL&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;em&gt;3. The Course Table (Linking to Lecturer)&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;CREATE&lt;/span&gt; &lt;span class="k"&gt;TABLE&lt;/span&gt; &lt;span class="n"&gt;Course&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;CourseID&lt;/span&gt; &lt;span class="n"&gt;VARCHAR2&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;PRIMARY&lt;/span&gt; &lt;span class="k"&gt;KEY&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;CourseName&lt;/span&gt; &lt;span class="n"&gt;VARCHAR2&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;NOT&lt;/span&gt; &lt;span class="k"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;LecturerID&lt;/span&gt; &lt;span class="nb"&gt;INT&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="k"&gt;CONSTRAINT&lt;/span&gt; &lt;span class="n"&gt;fk_lecturer&lt;/span&gt; 
        &lt;span class="k"&gt;FOREIGN&lt;/span&gt; &lt;span class="k"&gt;KEY&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;LecturerID&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; 
        &lt;span class="k"&gt;REFERENCES&lt;/span&gt; &lt;span class="n"&gt;Lecturer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;LecturerID&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;em&gt;4. The Enrollment Table (The "Bridge" Table)&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;This table handles the Many-to-Many relationship between Students and Courses.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;CREATE&lt;/span&gt; &lt;span class="k"&gt;TABLE&lt;/span&gt; &lt;span class="n"&gt;Enrollment&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;StudentID&lt;/span&gt; &lt;span class="nb"&gt;INT&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;CourseID&lt;/span&gt; &lt;span class="n"&gt;VARCHAR2&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="n"&gt;Grade&lt;/span&gt; &lt;span class="nb"&gt;CHAR&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="k"&gt;PRIMARY&lt;/span&gt; &lt;span class="k"&gt;KEY&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;StudentID&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;CourseID&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="c1"&gt;-- Composite PK&lt;/span&gt;
    &lt;span class="k"&gt;CONSTRAINT&lt;/span&gt; &lt;span class="n"&gt;fk_student&lt;/span&gt; 
        &lt;span class="k"&gt;FOREIGN&lt;/span&gt; &lt;span class="k"&gt;KEY&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;StudentID&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; 
        &lt;span class="k"&gt;REFERENCES&lt;/span&gt; &lt;span class="n"&gt;Student&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;StudentID&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="k"&gt;CONSTRAINT&lt;/span&gt; &lt;span class="n"&gt;fk_course&lt;/span&gt; 
        &lt;span class="k"&gt;FOREIGN&lt;/span&gt; &lt;span class="k"&gt;KEY&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;CourseID&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; 
        &lt;span class="k"&gt;REFERENCES&lt;/span&gt; &lt;span class="n"&gt;Course&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;CourseID&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Why This Matters for Your Project 🎓&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;When you submit your Database unit, don't just hand in the SQL. Show the transition.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Show the Messy Data: Prove you identified the problems.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Show the ERD: Use a tool like LucidChart to visualize the 3NF structure.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Explain the Constraints!&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;In your report, mention why you used NOT NULL or REFERENCES. This shows you aren't just copy-pasting code; you’re managing Referential Integrity.&lt;/p&gt;

&lt;p&gt;By following this step-by-step pipeline, you ensure that your database is efficient, scalable, and - most importantly - easy to query using CRUD operations.&lt;/p&gt;

</description>
      <category>sql</category>
      <category>database</category>
      <category>learning</category>
      <category>datastructures</category>
    </item>
    <item>
      <title>Why Your Code is Slow: A Practical Guide to Algorithms and Big O Notation</title>
      <dc:creator>xh1m</dc:creator>
      <pubDate>Thu, 12 Mar 2026 13:32:21 +0000</pubDate>
      <link>https://forem.com/xh1m/why-your-code-is-slow-a-practical-guide-to-algorithms-and-big-o-notation-2lfc</link>
      <guid>https://forem.com/xh1m/why-your-code-is-slow-a-practical-guide-to-algorithms-and-big-o-notation-2lfc</guid>
      <description>&lt;p&gt;If you’re a Software Development student and they’ve given you the Algorithms unit to work on, then you’re probably having a problem by now. It’s not enough to simply get your code working to pass a unit assessment. You may have a simple CRUD application that works fine with ten records in your Oracle database. But as you add more records, your application slows down. It’s not a hardware problem; it’s a problem of your code getting more expensive to run. In other words, it’s a Big O Notation problem.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The Academic Barrier: Why Big O Matters 🎓&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;In class, Big O Notation is often explained as a series of math proofs that put students to sleep. You see O(n log n) or O(2^n) scribbled on a blackboard, and your eyes glaze over. But as someone who just completed the unit, I’m here to tell you that Big O Notation is simply a way of measuring how your code gets slower as your input gets larger. Think of it as a “Scale Grade.” If your code is Grade A, it means it remains speedy even as your input reaches a million records. But if your code is Grade F, it means it may work for your assignment but will kill your server if you’re a real-world developer. &lt;/p&gt;

&lt;p&gt;&lt;em&gt;Getting your loop wrong doesn’t just mean your code is slow; it means your code is a failure.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The Bottleneck: The O(N²) Nightmare 🐌&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Students of HND level or higher often make the same mistake: a nested loop. Here is a simple example: finding duplicates in an array.&lt;/p&gt;

&lt;p&gt;Let's think of a list of user IDs; we want to check if there are any IDs that are repeated. A new programmer might use a Brute Force approach. They take the first ID and compare it to all other IDs. They take the second ID and compare it to all other IDs.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;In Java code:&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="c1"&gt;// The O(N^2) "Brute Force" approach&lt;/span&gt;
&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;boolean&lt;/span&gt; &lt;span class="nf"&gt;hasDuplicate&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="o"&gt;[]&lt;/span&gt; &lt;span class="n"&gt;nums&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;nums&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;length&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;++)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;j&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="n"&gt;j&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;nums&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;length&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="n"&gt;j&lt;/span&gt;&lt;span class="o"&gt;++)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;nums&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;nums&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="n"&gt;j&lt;/span&gt;&lt;span class="o"&gt;])&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
                &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// Duplicate found&lt;/span&gt;
            &lt;span class="o"&gt;}&lt;/span&gt;
        &lt;span class="o"&gt;}&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;em&gt;&lt;strong&gt;What makes this a disaster?&lt;/strong&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;It’s an O(n^2) algorithm. If you have an array of 10 items, it does 100 comparisons. If you have an array of 1,000 items, it does 1,000,000 comparisons. If you have an array of 100,000 records, your program does 10 billion operations. It maxes out the CPU and RAM.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The Solution: Make it O(N) Efficient ⚡&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;To solve this problem, stop comparing every item with every other item. Think of a more intelligent data structure. If you’re an object-oriented programmer, you can use a Hash Set or a Dictionary in Python. It’s a data structure that lets us remember what we have seen so far. We only need one loop.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;The Python code looks like this:&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;# The O(N) Optimised approach
&lt;/span&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;has_duplicate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;nums&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;seen&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;set&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="c1"&gt;# Create a Hash Set
&lt;/span&gt;    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;num&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;nums&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;num&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;seen&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="bp"&gt;True&lt;/span&gt; &lt;span class="c1"&gt;# Duplicate found in "Constant Time"
&lt;/span&gt;        &lt;span class="n"&gt;seen&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;num&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="bp"&gt;False&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;The Transformation:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This runs in O(n), or linear time. What this means is that if you are working with 100,000 pieces of data, the computer is working through 100,000 operations. &lt;em&gt;What used to take you minutes now takes less than a second to accomplish.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Real World Application: CRUD and SQL 🗄️&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This is not just about loops. Loops are important in Database Development as well. Have you ever written a SQL query without an index? What happens is that you are performing an O(n) problem. What about if you are working with two unindexed tables? Suddenly you are working with an O(n × m) problem, or a problem equivalent to a nested loop. Remember to always ask yourself in your projects: “What happens if I add 10,000 more pieces of data to my application?”&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Final Thoughts: Don’t Over-Engineer 🛠️&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Efficiency is great, but don’t get caught up in micro-optimizations. If your list is only ever going to have 5 items, an O(n^2) loop is perfectly acceptable if it’s easier to read. In your Unit Graded Assessment, you need to demonstrate your understanding of this. Tell your lecturer that you picked a HashMap/HashSet because you had thought about Computational Complexity. &lt;em&gt;This is what separates a “coder” from an “engineer.”&lt;/em&gt;&lt;/p&gt;

</description>
      <category>algorithms</category>
      <category>javascript</category>
      <category>python</category>
      <category>programming</category>
    </item>
    <item>
      <title>Waterfall is Dead? When to Choose Agile Methodologies in Software Projects 🚀</title>
      <dc:creator>xh1m</dc:creator>
      <pubDate>Thu, 12 Mar 2026 13:16:37 +0000</pubDate>
      <link>https://forem.com/xh1m/waterfall-is-dead-when-to-choose-agile-methodologies-in-software-projects-2ifm</link>
      <guid>https://forem.com/xh1m/waterfall-is-dead-when-to-choose-agile-methodologies-in-software-projects-2ifm</guid>
      <description>&lt;p&gt;In the realm of Software Development Life Cycles (SDLC), people have two broad ideas: Waterfall with its linear steps or Agile with its flexible changes. Students in HND projects need to get the right idea because it's not only about getting something done, but something useful.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Rigid vs. Adaptive&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;The ability to use these techniques is crucial for a Lead Developer.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Waterfall (The Linear Giant): It's a linear process: Requirements, Design, Implementation, Testing, and Maintenance. It's good for projects where safety is a concern or the project scope won't change. If a design flaw happens in Waterfall, it'll be costly during the testing phase.&lt;/p&gt;

&lt;p&gt;Agile (The Iterative Ninja): It's good for modern applications like CRUD-based applications or e-commerce applications because the project requirements may change over time.&lt;/p&gt;

&lt;p&gt;Professional verdict: Waterfall should be used if the project's ultimate goal is clear and static. Agile should be used if the project requires flexibility and dynamic updates.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Practical Agile Workflow&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Junior developers think Agile means you just discuss your code. But for a real project, you need a workflow.&lt;/p&gt;

&lt;p&gt;Backlog: Write each feature, like "User Login" or "SQL Database Connection," as a User Story.&lt;/p&gt;

&lt;p&gt;Sprint: Plan a two-week period where your team focuses on completing a set of backlog items.&lt;/p&gt;

&lt;p&gt;Visual Management: Use GitHub Projects to track your progress. Moving a task from "To-Do" to "Done" is like a professional Lead Developer setup.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Summary&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;When writing your project for your unit rubric, use logic as your basis. Agile is not just "quicker." Agile is a means of decreasing your risk. By using an iterative methodology, you test your MVC (Model-View-Controller) architecture early and often instead of waiting until the end of your project to have a huge failure.&lt;/p&gt;

</description>
      <category>agile</category>
      <category>scrum</category>
      <category>beginners</category>
      <category>software</category>
    </item>
    <item>
      <title>INTERFACES VS. ABSTRACT CLASSES: A REAL-WORLD JAVA EXAMPLE</title>
      <dc:creator>xh1m</dc:creator>
      <pubDate>Thu, 12 Mar 2026 12:42:50 +0000</pubDate>
      <link>https://forem.com/xh1m/interfaces-vs-abstract-classes-a-real-world-java-example-3f34</link>
      <guid>https://forem.com/xh1m/interfaces-vs-abstract-classes-a-real-world-java-example-3f34</guid>
      <description>&lt;p&gt;If you’re familiar with OOP (Object Oriented Programming), you’ll probably recognise the following code: an Animal class, a Dog class, and a method called bark.&lt;/p&gt;

&lt;p&gt;It’s good code if you want to learn Java syntax. It’s bad code if you want to understand software architecture. Nobody in the real world writes code to make digital dogs bark. If you only learn these abstract metaphors, you’ll never understand why we use polymorphism or why an interface might be a good idea.&lt;/p&gt;

&lt;p&gt;Today, we’ll skip the zoo. We’ll write a real-world e-commerce checkout application using Java and show how using an interface helps your application scale without changing your core code.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;The problem: the tightly coupled nightmare&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Let’s say you’re building a checkout application. At first, your boss says: “Hey, we only accept Credit Cards.” So you write a service class called &lt;code&gt;CheckoutService&lt;/code&gt; that calls a &lt;code&gt;CreditCardAPI&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;A month passes. Your boss says: “Hey, we need to accept PayPal.” Then: “Hey, we need to accept Crypto.”&lt;/p&gt;

&lt;p&gt;If you’re not using polymorphism, your code will become a nightmare of if/else statements&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;BadCheckoutService&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;processPayment&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;paymentType&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;double&lt;/span&gt; &lt;span class="n"&gt;amount&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;paymentType&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;equals&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"CREDIT_CARD"&lt;/span&gt;&lt;span class="o"&gt;))&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
            &lt;span class="nc"&gt;CreditCardAPI&lt;/span&gt; &lt;span class="n"&gt;cc&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;CreditCardAPI&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
            &lt;span class="n"&gt;cc&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;charge&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;amount&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
        &lt;span class="o"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;paymentType&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;equals&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"PAYPAL"&lt;/span&gt;&lt;span class="o"&gt;))&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
            &lt;span class="nc"&gt;PayPalAPI&lt;/span&gt; &lt;span class="n"&gt;pp&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;PayPalAPI&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
            &lt;span class="n"&gt;pp&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;sendFunds&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;amount&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
        &lt;span class="o"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;paymentType&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;equals&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"CRYPTO"&lt;/span&gt;&lt;span class="o"&gt;))&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
            &lt;span class="nc"&gt;CryptoWallet&lt;/span&gt; &lt;span class="n"&gt;cw&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;CryptoWallet&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
            &lt;span class="n"&gt;cw&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;transfer&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;amount&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
        &lt;span class="o"&gt;}&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;So, why is this bad?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;For every new payment type you add, you must go into this fundamental class and change the logic in your if statements. This is a problem because you're altering something that could potentially break your entire checkout process. This is a violation of the Open Closed principle. Our code should be open to extension and closed to modification.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;THE SOLUTION: PRACTICAL POLYMORPHISM&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;We're going to avoid hardcoding every type of payment. What is an Interface? An Interface is a contract that tells the world how something will behave without worrying about how it's implemented.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Step 1: Define the Interface&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;We're going to make a simple contract that all our payment classes must follow.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;interface&lt;/span&gt; &lt;span class="nc"&gt;PaymentProcessor&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="kt"&gt;boolean&lt;/span&gt; &lt;span class="nf"&gt;processTransaction&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;double&lt;/span&gt; &lt;span class="n"&gt;amount&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;em&gt;Step 2: Implement the Interface&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Now, we create distinct, isolated classes for each payment method. They all implement PaymentProcessor, meaning they are forced to provide their own specific logic for processTransaction.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;CreditCardProcessor&lt;/span&gt; &lt;span class="kd"&gt;implements&lt;/span&gt; &lt;span class="nc"&gt;PaymentProcessor&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="nd"&gt;@Override&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;boolean&lt;/span&gt; &lt;span class="nf"&gt;processTransaction&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;double&lt;/span&gt; &lt;span class="n"&gt;amount&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Connecting to Stripe API... Charging £"&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;amount&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt; 
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;PayPalProcessor&lt;/span&gt; &lt;span class="kd"&gt;implements&lt;/span&gt; &lt;span class="nc"&gt;PaymentProcessor&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="nd"&gt;@Override&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;boolean&lt;/span&gt; &lt;span class="nf"&gt;processTransaction&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;double&lt;/span&gt; &lt;span class="n"&gt;amount&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Redirecting to PayPal OAuth... Transferring £"&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;amount&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt; 
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;em&gt;Step 3: The Polymorphic Checkout Service&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;This is where the magic happens. We inject the interface into our checkout service rather than the concrete classes.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;CheckoutService&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

    &lt;span class="c1"&gt;// The service doesn't care IF it's PayPal or Crypto. &lt;/span&gt;
    &lt;span class="c1"&gt;// It only knows it holds an object that can 'processTransaction'.&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;executeCheckout&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;PaymentProcessor&lt;/span&gt; &lt;span class="n"&gt;processor&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;double&lt;/span&gt; &lt;span class="n"&gt;amount&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="kt"&gt;boolean&lt;/span&gt; &lt;span class="n"&gt;success&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;processor&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;processTransaction&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;amount&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;

        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;success&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
            &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Order complete!"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
        &lt;span class="o"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
            &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Payment failed."&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
        &lt;span class="o"&gt;}&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If your boss wants you to implement Apple Pay tomorrow, you should not touch the existing code in CheckoutService. Instead, create a new class, ApplePayProcessor, that implements PaymentProcessor and pass it in. Your core code remains unchanged and stable.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;HND WARNING: AVOID OVER-COMPLICATION&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;When implementing interfaces in your unit rubrics, ensure that your code remains uncomplicated and easy to maintain. Avoid complicating your code further by implementing advanced Abstract Factory patterns or Spring Boot Dependency Injection (DI) unless your assignment specifically requires you to. It is very easy to get into an error where you create an Interface for every class. For example, you might create an Interface like IUser, an Interface like IDatabase, and an Interface like IButton. This results in too many interfaces. Only create an Interface if you expect that there will be multiple, distinct implementations of that Interface. &lt;/p&gt;

&lt;p&gt;Otherwise, use basic constructor passing, like above, if you want top marks.&lt;/p&gt;

</description>
      <category>java</category>
      <category>oop</category>
      <category>programming</category>
      <category>beginners</category>
    </item>
    <item>
      <title>BUILDING A CLEAN CRUD WRAPPER FOR ORACLE SQL IN JAVA</title>
      <dc:creator>xh1m</dc:creator>
      <pubDate>Thu, 12 Mar 2026 12:27:38 +0000</pubDate>
      <link>https://forem.com/xh1m/building-a-clean-crud-wrapper-for-oracle-sql-in-java-2e87</link>
      <guid>https://forem.com/xh1m/building-a-clean-crud-wrapper-for-oracle-sql-in-java-2e87</guid>
      <description>&lt;p&gt;If you are currently working on a Database Design and Development assignment, you know the pain of transforming a database from 1NF to 3NF. But after the normalization nightmare comes another challenge: connecting your Java application to your Oracle database.&lt;/p&gt;

&lt;p&gt;When Java developers sit down at their IDEs like JetBrains or NetBeans to write their CRUD operations like Create, Read, Update, Delete, they soon find that their code is a mess. They are copying and pasting their database connection string into a lot of different methods, failing to close database connections that cause timeout exceptions, and concatenating strings to build SQL queries that leave themselves vulnerable to SQL injection attacks.&lt;/p&gt;

&lt;p&gt;Today, we’re going to solve this problem once and for all by creating a clean and secure object-oriented programming interface to our Oracle database using standard Java JDBC.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;THE PROBLEM: THE COPY-PASTE ANTI-PATTERN&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Here is what a standard, messy database call looks like when you put everything in one place:&lt;br&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%2Fjl04hdrxn4hheex9btv0.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%2Fjl04hdrxn4hheex9btv0.png" alt=" " width="800" height="410"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This code is a major security risk and breaks the principle of DRY (Don't Repeat Yourself). If a user were to input ' OR '1'='1 as their username, then the query would be compromised.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The Solution: A Dedicated Database Utility Class&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;To ensure that our application interacts with Oracle in a consistent manner, it is necessary to refactor the database connection logic into a single class.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Step 1: The Database Manager&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;We will create a class called DatabaseHelper. This class centralises the connection string so that any changes to the password or server are required only in this class.&lt;br&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%2Fqvm0c25s9haxcfvd7fw7.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%2Fqvm0c25s9haxcfvd7fw7.png" alt=" " width="800" height="406"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Step 2: Secure CRUD Using Prepared Statements&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Let’s now re-implement our INSERT method with our new helper and a prepared statement. Prepared statements will automatically escape our user input and prevent SQL injection entirely.&lt;/p&gt;

&lt;p&gt;We’ll use a try-with-resources statement. This is a really nice feature of Java that ensures your database connections and statements are closed right after you finish with them, no matter how you left your method. No more timeout exceptions!&lt;br&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%2Fwn27hsjcdihu0s7tdp1h.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%2Fwn27hsjcdihu0s7tdp1h.png" alt=" " width="796" height="690"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;THE ARCHITECTURAL WIN&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;By structuring your code like this, you have demonstrated your understanding of a Data Access Object (DAO) pattern.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Security: Using a PreparedStatement prevents SQL injection attacks.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Stability: The use of try-with-resources prevents memory leaks and Oracle connection limits from being exceeded.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Maintainability: Your CRUD operations are completely decoupled from your UI layer and your connection string.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;HND WARNING: KEEP IT SIMPLE&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;When researching database connectivity for Java projects, you will most likely come across various Enterprise Java frameworks like Hibernate, JPA, or Spring Data. However, remember that your solution doesn’t need to be more complicated than a standard unit question asks. While ORMs are great tools, creating your own ORM system without understanding the fundamentals of JDBC is a recipe for a complicated mess that is hard to grade. A clean and well-structured JDBC utility class using Prepared Statements is exactly what a Lecturer wants to see to ensure that you know your data access patterns.&lt;/p&gt;

&lt;p&gt;Master the basic wrapper first, and you will ace the unit.&lt;/p&gt;

</description>
      <category>java</category>
      <category>oracle</category>
      <category>database</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>STOP PUTTING LOGIC IN YOUR BUTTONS: A BEGINNER'S GUIDE TO SEPARATING CONCERNS IN C#</title>
      <dc:creator>xh1m</dc:creator>
      <pubDate>Thu, 12 Mar 2026 11:58:46 +0000</pubDate>
      <link>https://forem.com/xh1m/stop-putting-logic-in-your-buttons-a-beginners-guide-to-separating-concerns-in-c-23a4</link>
      <guid>https://forem.com/xh1m/stop-putting-logic-in-your-buttons-a-beginners-guide-to-separating-concerns-in-c-23a4</guid>
      <description>&lt;p&gt;If you are new to building GUIs in C# using Windows Forms or WPF, you are probably about to fall into the most common trap in software development. You know, you double-click on a button in your designer, Visual Studio generates a _Click event handler for you, and you just copy-paste about 150 lines of database access, validation, and business logic straight into that function.&lt;/p&gt;

&lt;p&gt;Well, guess what? It works. The data is saved. You are a genius.&lt;/p&gt;

&lt;p&gt;However, in actual software development, this is a terrible structure. It is a terrible structure because you are violating some fundamental principles of Object-Oriented Programming (OOP), you are making unit testing virtually impossible, and you are going to lose points on a strict grading scheme.&lt;/p&gt;

&lt;p&gt;Today, we are going to show you how to save your logic from your UI using a simple Model-View-Controller (MVC) structure.&lt;/p&gt;

&lt;p&gt;THE MONOLITHIC NIGHTMARE (THE "BAD" WAY)&lt;/p&gt;

&lt;p&gt;Let’s look at a classic beginner mistake. We have a simple form to register a new user.&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%2Fi7d49049g342y47ndpih.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%2Fi7d49049g342y47ndpih.png" alt=" " width="595" height="616"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Why is this a problem?&lt;/p&gt;

&lt;p&gt;The UI (the View) now knows how your database is set up. If you move from an Oracle SQL database to an API, you have to change your UI code. If you want to test your registration logic, you have to click the button on the screen. It is too much work for the UI.&lt;/p&gt;

&lt;p&gt;ENTER MVC AND SEPARATION OF CONCERNS&lt;/p&gt;

&lt;p&gt;The concept of Separation of Concerns is that a program should be divided into sections, with each section being responsible for a single task. To illustrate this concept, we will introduce a simple MVC pattern:&lt;/p&gt;

&lt;p&gt;THE MODEL: This section holds the data. It holds the properties but does not perform any work on the data.&lt;/p&gt;

&lt;p&gt;THE VIEW: Simple UI. It displays the data and accepts input from the user. It does not make any decisions.&lt;/p&gt;

&lt;p&gt;THE CONTROLLER: This section is the brain. It accepts input from the View, runs the business logic, interacts with the database, and notifies the View.&lt;/p&gt;

&lt;p&gt;THE REFACTORED APPROACH (THE "GOOD" WAY)&lt;/p&gt;

&lt;p&gt;Let us refactor that monolithic button click into three distinct, professional files.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;The Model (UserModel.cs)
First, we define what a user is. This is purely an # OOP data container.&lt;/li&gt;
&lt;/ol&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%2F1rx2a1uouiv1296qiopd.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%2F1rx2a1uouiv1296qiopd.png" alt=" " width="543" height="170"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;The Controller (UserController.cs)
Next, we extract all the database and business logic into a dedicated controller class.&lt;/li&gt;
&lt;/ol&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%2F36fv723iybaqg9r58jse.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%2F36fv723iybaqg9r58jse.png" alt=" " width="713" height="622"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;The View (Form1.cs)
Finally, look at how clean our button click becomes. The UI simply collects the data, hands it to the controller, and displays the result.&lt;/li&gt;
&lt;/ol&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%2Fry8m8d0ablxyx4si28wk.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%2Fry8m8d0ablxyx4si28wk.png" alt=" " width="590" height="490"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;IMPORTANT WARNING: AVOIDING OVER-ENGINEER&lt;/p&gt;

&lt;p&gt;A quick note for students: It's easy to get caught up in very advanced software architectures when reading about separating concerns.&lt;/p&gt;

&lt;p&gt;For a normal course rubric, the simple controller setup above is perfectly fine. It clearly demonstrates modularity and proper separation of CRUD operations. Avoid over-complicating the solution with unnecessary use of advanced Dependency Injection frameworks or tools like Inversion of Control or Command Query Responsibility Segregation. A normal controller class with creation of your models demonstrates understanding of the basics of software architecture without over-complicating the code.&lt;/p&gt;

&lt;p&gt;Just remember to avoid putting logic in the UI, and you'll have a professional-grade codebase.&lt;/p&gt;

</description>
      <category>csharp</category>
      <category>programming</category>
      <category>basic</category>
      <category>tutorial</category>
    </item>
  </channel>
</rss>
