Ever tried swapping LocalStorage for Dexie DB in your Angular app? That was me yesterday—surrounded by coffee cups, error messages, and regret.
My Angular service was tightly coupled to LocalStorage like peanut butter to jelly. Changing to Dexie meant rewriting EVERYTHING. Then I remembered the SOLID principles:
Single Responsibility: Each class should do one job (not my service juggling data AND storage)
Open/Closed: Classes open for extension, closed for modification (my code was welded shut)
Liskov Substitution: Subtypes should be substitutable (my storage wasn't)
Interface Segregation: Don't force clients to depend on methods they don't use
But the real hero? Dependency Inversion! By depending on abstractions instead of concrete implementations, I created a StorageService interface that both LocalStorage and Dexie could implement.
Suddenly, switching databases was just swapping implementations, not rebuilding Rome.
The "D" in SOLID (Dependency Inversion) became my hero when I created a storage interface that both implementations could satisfy. Now my components don't care where data lives; they just ask nicely for it.
class UserService {
private localStorage = window.localStorage;
saveUser(user: User) {
this.localStorage.setItem('user', JSON.stringify(user));
}
}
interface StorageProvider {
save(key: string, data: any): Promise<void>;
get(key: string): Promise<any>;
}
class UserService {
constructor(private readonly storage: StorageProvider) {}
saveUser(user: User): Promise<void> {
return this.storage.save('user', user);
}
}
Swapping implementations became as simple as changing underwear (but less embarrassing when done in public).

Moral of the story: When you SOLID-ify your code, future you will send present you a thank-you cake. Or at least fewer angry Slack messages.