CSCI 370 - Lecture 8: SOLID Principles Continued, Low-Code/No-Code Platforms, and Dependency Inversion
1. Low-Code and No-Code Development Tools
- Low-Code platforms allow app development using mostly visual tools, requiring minimal traditional programming.
- Example tools: Google AppSheet, Microsoft Power Apps, ServiceNow
- No-Code platforms go further by enabling app development without any programming knowledge.
- Example tools: Wix, WordPress
- Benefits:
- Faster development cycles
- Accessible to non-developers
- Easier prototyping and iteration
- Business users can create tools without needing a dev team
- Challenges:
- Limited customization and scalability
- Risk of vendor lock-in
- Performance may degrade with complex or data-heavy apps
2. SOLID Principles - Continued
Liskov Substitution Principle (Review)
- A derived class should be substitutable for its base class without altering the correctness of the program.
- Example:
- If
Rectangleis a base class andSquareinherits from it, then calling methods onSquareshould behave likeRectangle. - If
Rectangle.getArea()gives expected results, so shouldSquare.getArea().
- If
Interface Segregation Principle (ISP)
- Clients should not be forced to depend on methods they do not use.
- Explanation:
- Rather than having one large interface with unrelated methods, split into smaller, more cohesive interfaces.
- Example:
- Interface
Mathhasadd()andprintResult(). Calculatorclass shouldn’t be forced to implementprintResult()if it just does math.- Solution: Split into
MathandPrintMathResultinterfaces.
- Interface
Dependency Inversion Principle (DIP)
- High-level modules should not depend on low-level modules. Both should depend on abstractions.
- Explanation:
- Rather than hardcoding a dependency (e.g.,
BankAccountusesMySQL), depend on an interface. - Example:
- Create a
Databaseinterface with methodsaveBalance(). MySQLandOracleboth implementDatabase.BankAccountdepends onDatabase, not specific implementations.
- Create a
- Rather than hardcoding a dependency (e.g.,
- Benefits:
- Easier to switch implementations
- Promotes code reuse and testability
- Reduces tight coupling
3. Precision in Financial Software
- Avoid using
doublefor financial calculations due to floating-point inaccuracies. - Preferred solutions:
- Use integers representing the smallest unit (e.g., pennies)
- For $1.00, store 100 (pennies)
- Real-world practice:
- Companies like Stripe store monetary values in integers (pennies or smaller)
- Ensures accuracy, especially when dividing amounts
4. Using Interfaces for Flexibility
- Scenario: Switching from
MySQLtoOraclerequires refactoring if tightly coupled. - Solution:
- Define an interface
Database BankAccountuses aDatabasereference instead of a concrete class- Pass either
MySQLorOracleobjects at runtime
- Define an interface
- Key Design Idea:
- Depend on the most general type possible (e.g., interfaces) to support flexibility and reduce change
5. Designing for Generalization
- Prefer general data structures (e.g.,
Iterable) over specific ones (e.g.,List) when possible - Example:
- A method takes
List<BankAccount>but only iterates through it - Better to use
Iterable<BankAccount>to allow more data structures (e.g., sets, queues)
- A method takes
- Lesson:
- The more general your method parameter types, the more reusable and flexible your code becomes
Summary of Key Takeaways
- Use low-code/no-code tools for quick prototypes and simple apps
- Interface Segregation Principle: Keep interfaces cohesive and purpose-specific
- Dependency Inversion Principle: Depend on abstractions, not concrete implementations
- Financial software should avoid floating-point errors by storing money in integer units
- Generalize method inputs to reduce coupling and increase compatibility
Next Class: No Thursday class due to Wednesday schedule. Exam expected on March 25th (as per course schedule).