AI-Assisted Software Engineering With OOPS, SOLID Principles, and Documentation
Top-down defines the "what"; bottom-up builds the "how." OOP and SOLID enable flexible, reusable design. AI helps, but only with a clear structure and context.
Join the DZone community and get the full member experience.
Join For FreeTop-down and bottom-up approaches are two problem-solving approaches to divide and conquer a problem.
What Is the Top-Down Approach?
Take any problem, break it down until you are in a position to schedule it to a machine, OS, SDK, or software system.
What Is the Bottom-Up Approach?
You have pluggable solutions or building blocks such as machine, os, sdk, which you are aware of, given a problem you put the building blocks together to build a complete solution.
How Did OOPS Promote the Bottom-Up Approach in Software?
With OOPS, we started building more and more software building blocks that could be reused and combined. A lot of libraries providing many components emerged from OOPS languages like Java, C++, etc.
Did OOPS and Bottom-Up Approach Solve the Problem?
Yes, partially. Still, most requirements come to us from the top (i.e., from a business perspective), and we have to solve them using a top-down approach to stitch the components together to meet the requirements.
The business landscape keeps changing. We need reusable components, but we also need them plugged into our system to solve business problems. The business identifies "needs," which are then converted to "user stories," and these use cases are converted again into "requirement specifications." As the saying goes, 1 need turns to 100 user stories and 100 user stories turn into 1000 requirements. The Needs also keep changing over time, thereby changing user stories and requirement specifications as well. This breakdown is still top-down.
Here’s a practical example:
Business Need
“Improve customer retention by enabling a personalized shopping experience.”
User Stories
- As a returning customer, I want to see product recommendations based on my previous purchases so I can find relevant products faster.
- As a logged-in user, I want to see my recently viewed products on the homepage so I can resume shopping easily.
- As a customer, I want to save items to a wishlist so I can revisit them later.
Technical Specification (for Story #1)
- API:
GET /api/recommendations/{userId} - Data source: Purchase history, user behavior tracking
- Algorithm: Collaborative filtering or external ML service
- Security: GDPR-compliant data usage and opt-out capabilities
- Front-end integration: Carousel component in homepage layout
This breakdown shows how business strategy leads to concrete technical outcomes. While reusable components help implement these specifications, the requirements flow remains top-down.
But what should you do if you want to slow down these landscaping changes while still adapting to fast-changing business needs?
To adapt to such a changing landscape, we are supposed to make use of SOLID principles.
- Single Responsibility Principle (SRP): Each module or class should do one thing well.
- Open/Closed Principle (OCP): Components should be open for extension but closed for modification.
- Liskov Substitution Principle (LSP): Derived types must be substitutable for their base types.
- Interface Segregation Principle (ISP): Favor many small, specific interfaces over large, general-purpose ones.
- Dependency Inversion Principle (DIP): High-level modules should not depend on low-level modules; both should depend on abstractions.
Inversion of control principle, when putting components together, it is simply "called" in other terms, such as dependency injection. While we aspire to work on the highest maturity level, like runtime dependency switch, we should be in a position to build reusable components, each having a single responsibility, each open for extension and closed for modifications, and each is ready to be substituted.
While each SOLID principle is helpful, start with the Dependency Injection principle. This is a missing piece that can help us slow down the fast-paced changing landscape of needs and increase our churn time or turnaround time, and also introduce us to other principles.
How to Apply AI Assistance While Doing It?
Even if there is an AI OS tomorrow, the art of building software with reusable components won't change, but AI assistance should be aware of all reusable components and libraries on the market that are maintained and secure to use. AI assistance should know how the components that are present in the current developed system work and their responsibilities, and how they can be extended and substituted. While addressing the business needs, we should make ourselves aware of the need for AI assistance.
To reiterate,
- A catalog of well-maintained reusable components and libraries is required.
- Needs, user stories, and requirement specification document required.
- Documentation of component of current software with responsibilities, extendability, and substitutability is required.
Are the current AI assistants not doing the required? Yes, but partially no. While LLMs are doing their best to understand the entire workspace, it is only the instructions from the developers that is going to guide AI assistant. In this post, we have only pulled out a systematic approach to leverage an AI assistant effectively.
Conclusion
In this article, we highlighted bottom up and top down approaches and how top down changes the needs, user stories and requirements and how we adopt OOPS principles and why to rely on SOLID principles, especially dependency injection and dependency over abstractions to build softwares bottom up and how to extend this methods with AI by preparing necessary documents relevant that can align with developer intent.
Opinions expressed by DZone contributors are their own.
Comments