java-best-practices-refactor-legacy
Refactors legacy Java code to modern patterns and best practices. Use when modernizing old Java code, converting to Java 8+ features, refactoring legacy applications, applying design patterns, improving error handling, extracting methods/classes, converting to streams/Optional/records, or migrating from old Java versions. Works with pre-Java 8 code, procedural Java, legacy frameworks, and outdated patterns.
What this skill does
# Java Legacy Code Refactoring
## Quick Start
Point to any legacy Java file and receive a refactored version:
```bash
# Refactor a single legacy class
Refactor LegacyUserService.java to modern Java
# Refactor entire legacy package
Modernize all Java files in src/main/java/com/example/legacy/
```
## When to Use
Use this skill when you need to:
- Modernize pre-Java 8 code to use streams, lambdas, and Optional
- Refactor legacy applications to modern Java patterns
- Convert anonymous inner classes to lambda expressions
- Replace imperative loops with Stream API
- Apply SOLID principles to existing code
- Extract methods from long methods (>50 lines)
- Break up god classes into focused components
- Replace null returns with Optional
- Convert to try-with-resources for resource management
- Apply design patterns (Strategy, Builder, etc.)
- Migrate from old frameworks to modern alternatives
- Improve error handling with custom exceptions
## Instructions
### Step 1: Analyze Legacy Code
Read the target file and identify legacy patterns:
**Pre-Java 8 Patterns:**
- Anonymous inner classes instead of lambdas
- Manual iteration instead of Stream API
- Null checks instead of Optional
- Manual resource management instead of try-with-resources
- StringBuffer instead of StringBuilder
- Vector/Hashtable instead of modern collections
**Code Smells:**
- God classes (classes doing too much)
- Long methods (over 50 lines)
- Deep nesting (over 3 levels)
- Code duplication
- Poor naming
- Magic numbers and strings
- Tight coupling
**Anti-Patterns:**
- Singleton abuse
- Service locator pattern
- God objects
- Anemic domain models
- Transaction script pattern
### Step 2: Plan Refactoring Strategy
Prioritize refactorings by impact and risk:
**High Priority (High Impact, Low Risk):**
1. Extract constants for magic numbers/strings
2. Rename poorly named variables/methods
3. Convert to try-with-resources
4. Replace StringBuffer with StringBuilder
**Medium Priority (High Impact, Medium Risk):**
1. Convert loops to Stream API
2. Replace null returns with Optional
3. Extract methods from long methods
4. Apply design patterns
**Low Priority (Medium Impact, High Risk):**
1. Extract classes from god classes
2. Restructure architecture
3. Change public APIs
### Step 3: Apply Modern Java Features
**Lambda Expressions:**
```java
// Before: Anonymous inner class
Comparator<User> comparator = new Comparator<User>() {
@Override
public int compare(User u1, User u2) {
return u1.getName().compareTo(u2.getName());
}
};
// After: Lambda and method reference
Comparator<User> comparator = Comparator.comparing(User::getName);
```
**Stream API:**
```java
// Before: Imperative loops
List<String> names = new ArrayList<>();
for (User user : users) {
if (user.isActive()) {
names.add(user.getName().toUpperCase());
}
}
Collections.sort(names);
// After: Functional streams
List<String> names = users.stream()
.filter(User::isActive)
.map(User::getName)
.map(String::toUpperCase)
.sorted()
.toList();
```
**Optional:**
```java
// Before: Null returns
public User findUser(String id) {
User user = repository.findById(id);
return user != null ? user : DEFAULT_USER;
}
// After: Optional
public Optional<User> findUser(String id) {
return repository.findById(id);
}
// Usage
User user = findUser(id).orElse(DEFAULT_USER);
```
**Records (Java 14+):**
```java
// Before: Boilerplate DTO
public class UserDTO {
private final String name;
private final String email;
// constructor, getters, equals, hashCode...
}
// After: Record
public record UserDTO(String name, String email) {}
```
**Try-with-resources:**
```java
// Before: Manual resource management
BufferedReader reader = null;
try {
reader = new BufferedReader(new FileReader("file.txt"));
// use reader
} finally {
if (reader != null) {
try { reader.close(); } catch (IOException e) {}
}
}
// After: Try-with-resources
try (BufferedReader reader = new BufferedReader(new FileReader("file.txt"))) {
// use reader
} catch (IOException e) {
log.error("Failed to read file", e);
}
```
### Step 4: Extract Methods and Classes
**Extract Method:**
```java
// Before: Long method
public void processOrder(Order order) {
// Validation (20 lines)
// Calculate total (15 lines)
// Save order (10 lines)
}
// After: Extracted methods
public void processOrder(Order order) {
validateOrder(order);
double total = calculateTotal(order);
saveOrder(order, total);
}
```
**Extract Class:**
```java
// Before: God class
public class OrderProcessor {
public void processOrder(Order order) { /* ... */ }
public void validateOrder(Order order) { /* ... */ }
public double calculateTotal(Order order) { /* ... */ }
public void sendEmail(Order order) { /* ... */ }
public void updateInventory(Order order) { /* ... */ }
}
// After: Separated responsibilities
public class OrderProcessor {
private final OrderValidator validator;
private final OrderCalculator calculator;
private final OrderNotifier notifier;
private final InventoryManager inventory;
public void processOrder(Order order) {
validator.validate(order);
double total = calculator.calculateTotal(order);
order.setTotal(total);
inventory.updateInventory(order);
notifier.sendOrderConfirmation(order);
}
}
```
### Step 5: Apply Design Patterns
See [references/design-patterns.md](./references/design-patterns.md) for:
- Strategy pattern for conditional logic
- Builder pattern for complex objects
- Factory pattern for object creation
- Repository pattern for data access
### Step 6: Improve Error Handling
**Replace printStackTrace with Logging:**
```java
// Before
try {
processPayment(order);
} catch (Exception e) {
e.printStackTrace();
}
// After
try {
processPayment(order);
} catch (PaymentException e) {
log.error("Payment processing failed for order {}", order.getId(), e);
throw new OrderProcessingException("Failed to process order payment", e);
}
```
**Create Custom Exceptions:**
```java
public class UserNotFoundException extends RuntimeException {
public UserNotFoundException(Long id) {
super("User not found with ID: " + id);
}
}
```
## Supporting Files
- **[references/refactoring-examples.md](./references/refactoring-examples.md)** - Comprehensive before/after examples
- **[references/design-patterns.md](./references/design-patterns.md)** - Strategy, Builder, Factory patterns
- **[references/modernization-guide.md](./references/modernization-guide.md)** - Java 8+ feature migration guide
## Requirements
### Tools Needed
- Java 8+ (for lambdas, streams, Optional)
- Java 11+ (for var, improved String methods)
- Java 14+ (for records, switch expressions)
- Java 17+ (for sealed classes, pattern matching)
- Modern IDE with refactoring support
### Dependencies
```xml
<!-- Lombok (for reducing boilerplate) -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.30</version>
<scope>provided</scope>
</dependency>
<!-- SLF4J for logging -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>2.0.9</version>
</dependency>
```
## Refactoring Checklist
Before refactoring:
- [ ] Ensure tests exist (or create them first)
- [ ] Understand the current behavior completely
- [ ] Create a backup or commit current state
During refactoring:
- [ ] Make one change at a time
- [ ] Run tests after each change
- [ ] Keep commits small and focused
After refactoring:
- [ ] Verify all tests pass
- [ ] Check for performance regressions
- [ ] Review code with team
## Output Format
When refactoring, provide:
1. **Analysis** of legacy code issues
2. **Refactoring plan** with prioritized changes
3. **Refactored code** with detailed explanations
4. **Before/After comparison** highlighRelated in Design
contribute
IncludedLocal-only OSS contribution command center. Auto-refreshes the user's in-flight PR and issue state on invoke so conversations start with full context — no need to brief Claude on what's in flight. Helps the user find issues to contribute to on GitHub, builds per-repo dossiers of what each upstream expects (CLA, DCO, branch convention, AI policy, draft-first, review bots, issue templates), runs deterministic gates before any external action so AI-assisted contributions don't reach maintainers as slop. State is markdown-only: candidate files at ~/.contribute-system/candidates/, repo dossiers at ~/.contribute-system/research/, append-only event log at ~/.contribute-system/log.jsonl. No database, no cloud calls. Use when the user asks about their PRs / issues / contributions, wants to find new work to take on, claim an issue, build/refresh a repo's dossier, or draft a Design Issue or PR. Trigger with "/contribute", "what's my PR status", "find a contribution", "claim issue X", "draft a Design Issue for Y", "refresh dossier for Z".
architectural-analysis
IncludedUser-triggered deep architectural analysis of a codebase or scoped subtree across eight modes — information architecture, data flow, integration points, UI surfaces, interaction patterns, data model, control flow, and failure modes. This skill should be used when the user asks to "diagram this codebase," "map the architecture," "show the data flow," "give me an ERD," "trace control flow," "find the integration points," "verify the layout pattern," "audit the UX architecture," or any similar request whose primary deliverable is mermaid diagrams plus cited reports under docs/architecture/. Dispatches haiku/sonnet sub-agents in parallel for per-mode exploration, then verifies every citation mechanically before any node lands in a diagram. Not for one-off prose explanations of code (use code-explanation) or for high-level system design from scratch (use system-design).
mcp
IncludedModel Context Protocol (MCP) server development and tool management. Languages: Python, TypeScript. Capabilities: build MCP servers, integrate external APIs, discover/execute MCP tools, manage multi-server configs, design agent-centric tools. Actions: create, build, integrate, discover, execute, configure MCP servers/tools. Keywords: MCP, Model Context Protocol, MCP server, MCP tool, stdio transport, SSE transport, tool discovery, resource provider, prompt template, external API integration, Gemini CLI MCP, Claude MCP, agent tools, tool execution, server config. Use when: building MCP servers, integrating external APIs as MCP tools, discovering available MCP tools, executing MCP capabilities, configuring multi-server setups, designing tools for AI agents.
react-native-skia
IncludedDesign, build, debug, and optimise high-polish animated graphics in React Native or Expo using @shopify/react-native-skia, Reanimated, and Gesture Handler. Use when the user wants canvas-driven UI, shaders, paths, rich text, image filters, sprite fields, Skottie, video frames, snapshots, web CanvasKit setup, or performance tuning for custom motion-heavy elements such as loaders, hero art, cards, charts, progress indicators, particle systems, or gesture-driven surfaces. Also use when the user asks for fluid, glow, glass, blob, parallax, 60fps/120fps, or GPU-friendly animated effects in React Native, even if they do not explicitly say "Skia". Do not use for ordinary form/layout work with standard views.
plaid
IncludedProduct Led AI Development — guides founders from idea to launched product. Six capabilities: Idea (discover a product idea), Validate (pressure-test the idea against fatal flaws, problem reality, competition, and 2-week MVP feasibility), Plan (vision intake + document generation), Design (translate image references into a design.md spec), Launch (go-to-market strategy), and Build (roadmap execution). Use when someone says "PLAID", "plaid idea", "help me find an idea", "product idea", "idea from my business", "idea from my expertise", "plaid validate", "validate my idea", "pressure-test", "is this idea good", "find fatal flaws", "validate the problem", "plan a product", "define my vision", "generate a PRD", "product strategy", "plaid design", "design from image", "translate image to design", "create design.md", "extract design tokens", "plaid launch", "go-to-market", "launch plan", "GTM strategy", "launch playbook", "plaid build", "build the app", "start building", or "execute the roadmap".
nextjs-framer-motion-animations
IncludedAdds production-safe Motion for React or Framer Motion animations to Next.js apps, including reveal, hover and tap micro-interactions, whileInView, stagger, AnimatePresence, layout and layoutId transitions, reorder, scroll-linked UI, and lightweight route-content transitions. Use when the user asks to add, refactor, or debug Motion or Framer Motion in App Router or Pages Router codebases, especially around server/client boundaries, reduced motion, LazyMotion, bundle size, hydration, or route transitions. Avoid for GSAP-style timelines, WebGL or 3D scenes, heavy scroll storytelling, or CSS-only effects unless Motion is explicitly requested.