
refactoring
by duc01226
SKILL.md
name: refactoring description: Use when restructuring code without changing behavior - extract method, extract class, rename, move, inline, introduce parameter object. Triggers on keywords like "extract", "rename", "move method", "inline", "restructure", "decompose". allowed-tools: Read, Write, Edit, Bash, Grep, Glob, Task, TodoWrite infer: true
Code Refactoring
Expert code restructuring agent for EasyPlatform. Focuses on structural changes that improve code quality without modifying behavior.
Refactoring Catalog
Extract Patterns
| Pattern | When to Use | Platform Example |
|---|---|---|
| Extract Method | Long method, duplicated code | Move logic to private method |
| Extract Class | Class has multiple responsibilities | Create Helper, Service, or Strategy class |
| Extract Interface | Need abstraction for testing/DI | Create I{ClassName} interface |
| Extract Expression | Complex inline expression | Move to Entity static expression |
| Extract Validator | Repeated validation logic | Create validator extension method |
Move Patterns
| Pattern | When to Use | Platform Example |
|---|---|---|
| Move Method | Method belongs to different class | Move from Handler to Helper/Entity |
| Move to Extension | Reusable repository logic | Create {Entity}RepositoryExtensions |
| Move to DTO | Mapping logic in handler | Use PlatformEntityDto.MapToEntity() |
| Move to Entity | Business logic in handler | Add instance method or static expression |
Simplify Patterns
| Pattern | When to Use | Platform Example |
|---|---|---|
| Inline Variable | Temporary variable used once | Remove intermediate variable |
| Inline Method | Method body is obvious | Replace call with body |
| Replace Conditional | Complex if/switch | Use Strategy pattern or expression |
| Introduce Parameter Obj | Method has many parameters | Create Command/Query DTO |
Workflow
Phase 1: Analysis
- Identify Target: Locate code to refactor
- Map Dependencies: Find all usages with Grep
- Assess Impact: List affected files and tests
- Verify Tests: Ensure test coverage exists
Phase 2: Plan
Document refactoring plan:
## Refactoring Plan
**Target**: [file:line_number]
**Type**: [Extract Method | Move to Extension | etc.]
**Reason**: [Why this refactoring improves code]
### Changes
1. [ ] Create/modify [file]
2. [ ] Update usages in [files]
3. [ ] Run tests
### Risks
- [Potential issues]
Phase 3: Execute
// BEFORE: Logic in handler
protected override async Task<Result> HandleAsync(Command req, CancellationToken ct)
{
var isValid = entity.Status == Status.Active &&
entity.User?.IsActive == true &&
!entity.IsDeleted;
if (!isValid) throw new Exception();
}
// AFTER: Extracted to entity static expression
// In Entity.cs
public static Expression<Func<Entity, bool>> IsActiveExpr()
=> e => e.Status == Status.Active &&
e.User != null && e.User.IsActive &&
!e.IsDeleted;
// In Handler
var entity = await repository.FirstOrDefaultAsync(Entity.IsActiveExpr(), ct)
.EnsureFound("Entity not active");
Phase 4: Verify
- Run affected tests
- Verify no behavior change
- Check code compiles
- Review for consistency
Platform-Specific Refactorings
Handler to Helper
// BEFORE: Reused logic in multiple handlers
var employee = await repo.FirstOrDefaultAsync(Employee.UniqueExpr(userId, companyId), ct)
?? await CreateEmployeeAsync(userId, companyId, ct);
// AFTER: Extracted to Helper
// In EmployeeHelper.cs
public async Task<Employee> GetOrCreateEmployeeAsync(string userId, string companyId, CancellationToken ct)
{
return await repo.FirstOrDefaultAsync(Employee.UniqueExpr(userId, companyId), ct)
?? await CreateEmployeeAsync(userId, companyId, ct);
}
Handler to Repository Extension
// BEFORE: Query logic in handler
var employees = await repo.GetAllAsync(
e => e.CompanyId == companyId && e.Status == Status.Active && e.DepartmentIds.Contains(deptId), ct);
// AFTER: Extracted to extension
// In EmployeeRepositoryExtensions.cs
public static async Task<List<Employee>> GetActiveByDepartmentAsync(
this IPlatformQueryableRootRepository<Employee> repo, string companyId, string deptId, CancellationToken ct)
{
return await repo.GetAllAsync(
Employee.OfCompanyExpr(companyId)
.AndAlso(Employee.IsActiveExpr())
.AndAlso(e => e.DepartmentIds.Contains(deptId)), ct);
}
Mapping to DTO
// BEFORE: Mapping in handler
var config = new AuthConfig
{
ClientId = req.Dto.ClientId,
Secret = encryptService.Encrypt(req.Dto.Secret)
};
// AFTER: DTO owns mapping
// In AuthConfigDto.cs : PlatformDto<AuthConfig>
public override AuthConfig MapToObject() => new AuthConfig
{
ClientId = ClientId,
Secret = Secret // Handler applies encryption
};
// In Handler
var config = req.Dto.MapToObject()
.With(c => c.Secret = encryptService.Encrypt(c.Secret));
Safety Checklist
Before any refactoring:
- Searched all usages (static + dynamic)?
- Test coverage exists?
- Documented in todo list?
- Changes are incremental?
- No behavior change verified?
Code Responsibility Refactoring (Priority Check)
Before any refactoring, verify logic is in the LOWEST appropriate layer:
Entity/Model (Lowest) → Service → Component/Handler (Highest)
| Wrong Location | Move To | Example |
|---|---|---|
| Component | Entity/Model | Dropdown options, display helpers, defaults |
| Component | Service (Factory) | Command building, data transformation |
| Handler | Entity | Business rules, static expressions |
| Handler | Repository Ext | Reusable query patterns |
// Frontend: Component → Entity refactoring
// BEFORE: Logic in component (causes duplication)
readonly statusTypes = [{ value: 1, label: 'Active' }, { value: 2, label: 'Inactive' }];
getStatusClass(config) { return !config.isEnabled ? 'disabled' : 'active'; }
// AFTER: Logic in entity (enables reuse)
readonly statusTypes = EntityConfiguration.getStatusTypeOptions();
getStatusClass(config) { return config.getStatusCssClass(); }
Component HTML Template Standard (BEM Classes)
All UI elements in component templates MUST have BEM classes, even without styling needs. This makes HTML self-documenting like OOP class hierarchy.
<!-- ✅ CORRECT: All elements have BEM classes -->
<div class="settings-panel">
<div class="settings-panel__header">
<h2 class="settings-panel__title">Settings</h2>
</div>
<div class="settings-panel__body">
<div class="settings-panel__section">
<label class="settings-panel__label">Option</label>
<input class="settings-panel__input" formControlName="option" />
</div>
</div>
</div>
<!-- ❌ WRONG: Missing BEM classes -->
<div class="settings-panel">
<div>
<h2>Settings</h2>
</div>
<div>
<div>
<label>Option</label>
<input formControlName="option" />
</div>
</div>
</div>
Refactoring Action: When refactoring components, ensure all HTML elements have proper BEM classes.
Component SCSS Standard
Always style both the host element (Angular selector) and the main wrapper class:
@import '~assets/scss/variables';
// Host element styling - ensures Angular element is a proper block container
my-component {
display: flex;
flex-direction: column;
}
// Main wrapper class with full styling
.my-component {
display: flex;
flex-direction: column;
width: 100%;
flex-grow: 1;
&__header {
// BEM child elements...
}
&__content {
flex: 1;
overflow-y: auto;
}
}
Why both?
- Host element: Makes the Angular element a real layout element (not an unknown element without display)
- Main class: Contains the full styling, matches the wrapper div in HTML
// Backend: Handler → Entity refactoring
// BEFORE: Logic in handler
var isValid = entity.Status == Status.Active && entity.User?.IsActive == true;
// AFTER: Logic in entity
var entity = await repository.FirstOrDefaultAsync(Entity.IsActiveExpr(), ct);
Anti-Patterns
- Big Bang Refactoring: Make small, incremental changes
- Refactoring Without Tests: Ensure coverage first
- Mixing Refactoring with Features: Do one or the other
- Breaking Public APIs: Maintain backward compatibility
- Logic in Wrong Layer: Leads to duplicated code - move to lowest appropriate layer
Task Planning Notes
- Always plan and break many small todo tasks
- Always add a final review todo task to review the works done at the end to find any fix or enhancement needed
スコア
総合スコア
リポジトリの品質指標に基づく評価
SKILL.mdファイルが含まれている
ライセンスが設定されている
100文字以上の説明がある
GitHub Stars 100以上
3ヶ月以内に更新がある
10回以上フォークされている
オープンIssueが50未満
プログラミング言語が設定されている
1つ以上のタグが設定されている
レビュー
レビュー機能は近日公開予定です