The Professional Standard
Writing 'code that works' is easy; writing 'code that lasts' requires discipline. As an Engineering Manager, you should enforce a set of core principles across your team to ensure that the Revochamp platform remains agile. These practices focus on readability, maintainability, and minimizing the cost of future changes.
- The LIFT Principle
The Angular team recommends the LIFT principle for organizing your project structure. If you can't find a file in under 5 seconds, your architecture is too complex.
- Locate code quickly: Keep a flat folder structure where possible.
- Identify at a glance: Use clear naming conventions (e.g.,
project-list.component.ts). - Flat structure as long as possible: Don't nest folders unless you have more than 7 files in a directory.
- Try to stay DRY: Avoid 'Repeat Yourself' by moving shared logic into services or pipes.
- Smart vs. Dumb Components
As an Architect, you should separate your UI into two distinct types of components. This 'Separation of Concerns' makes your application much easier to test and debug.
| Feature | Smart (Container) | Dumb (Presentational) |
|---|---|---|
| Responsibility | Data fetching & Logic | Displaying UI & Emitting events |
| Dependencies | Services, Store, Router | None (Only @Input and @Output) |
| Reusability | Low (specific to a feature) | High (generic UI widgets) |
| Change Detection | Default / OnPush | Always ChangeDetectionStrategy.OnPush |
- Performance: Immutability & OnPush
Never mutate data directly. Use the spread operator (...) to create new object references. This allows you to use ChangeDetectionStrategy.OnPush across your app, which prevents Angular from re-rendering components unless their specific data has actually changed. For a Flutter dev, this is the equivalent of an optimized StatelessWidget that only rebuilds when its properties change.
- Clean Code Checklist
- Small Functions: Keep methods under 20 lines. If it's longer, it's doing too much.
- Unsubscribe: Always use the
asyncpipe or atakeUntilpattern to prevent memory leaks. - Strong Typing: Avoid using
any. Define interfaces for every API response and data model. - Logic-less Templates: Keep logic in the TypeScript class. Templates should only handle display logic.
- Provide in Root: Use
providedIn: 'root'for services to enable tree-shaking by default.