If you're writing Java in production, these best practices are non-negotiable. Whether you're mentoring juniors or scaling systems, these habits define senior-level engineering.
1. ✅ Name Things Clearly
Bad:
public void d(User u) { ... }
Good:
public void deleteUser(User user) { ... }
Clear names reduce bugs and make code easier to debug and maintain.
2. 🧱 Apply SOLID Principles
Example – Open/Closed Principle (OCP)
Instead of:
if (shape instanceof Circle) { ... }
Use:
interface Shape {
double area();
}
Add new shapes without modifying existing logic. That’s real extensibility.
3. 🚫 Avoid null
– Use Optional
Optional<User> user = userRepo.findById(id);
user.ifPresent(u -> sendEmail(u.getEmail()));
Encourages defensive coding and avoids NullPointerException
.
4. 🧼 Keep Business Logic Out of Controllers
Anti-pattern:
@GetMapping("/register")
public void register(@RequestParam String name) {
if (name.length() > 10) ...
}
Best Practice:
Move validation and logic into service classes. Keep controllers thin.
5. 🔄 Prefer Composition Over Inheritance
Instead of:
class PremiumUser extends User { ... }
Use:
class PremiumUser {
private User user;
private LoyaltyProgram loyaltyProgram;
}
Composition = more flexibility, fewer surprises.
6. 🔒 Secure at Method Level
Use annotations like:
@PreAuthorize("hasRole('ADMIN')")
public void deleteUser(Long id) { ... }
Never rely only on frontend enforcement or URL security.
7. 🔍 Log Intelligently
Avoid:
System.out.println("Order placed");
Do:
log.info("Order placed for orderId={}, userId={}", orderId, userId);
Structured logging helps with observability and tracing.
8. 🧪 Write Focused Tests
Bad:
@Test void testAll() { ... }
Good:
Write one assert per test scenario. Use JUnit 5, Mockito, and Testcontainers where applicable.
9. 🧹 Validate Early, Validate Always
Use Bean Validation:
public class PaymentRequest {
@NotNull
private String accountId;
@Min(1)
private BigDecimal amount;
}
Combine with @Validated
in service or controller layers.
10. 🛑 Don't Optimize Before It's Needed
Don’t:
buildHyperCustomCacheThatNoOneAskedFor()
Do:
Profile first. Optimize second. Trust JFR, VisualVM, or YourKit.
Top comments (0)