애자일은 방법론이나 툴이 아니라, 일하는 방식의 철학이다. 이번 포스팅에서는 2001년 발표된 애자일 선언문과 12가지 원칙을 실무 관점에서 다시 해석해본다.

 

https://hsunnystory.tistory.com/261

 

[Software Enginnering] 에자일(Agile) 이란?

오픈을 한 달 앞둔 시점, 기획팀 혹은 고객사로부터 이런 피드백을 받은 경험이 한 번쯤은 있을 것이다. "이거 우리가 원했던 기능이 아닌데요????"이러한 비극은 왜 터지는 것일까? 이는 우리가

hsunnystory.tistory.com

 

 

1. 가치(Value)를 중심에 둔 애자일 선언문 4가지 핵심

공정과 도구보다 개인과 상호작용

Jira 티켓에 댓글만 남기며 핑퐁을 치는 것보다 프론트엔드 개발자나 기획자와 화이트보드 앞에서 아키텍처를 논의하는 것이 훨씬 빠르고 정확하다.

 

포괄적인 문서보다 작동하는 소프트웨어

100장짜리 완벽한 API 명세서를 작성하느라 시간을 쏟기보다, 핵심 기능만 동작하는 API를 빠르게 배포하고 Swagger를 통해 실시간으로 스펙을 맞춰나가는 것이 실무적이다.

 

계약 협상 보다 고객과의 협력

방어적으로 코딩하는 대신, 비즈니스 목표 달성을 위해 시스템 구조를 어떻게 유연하게 가져갈지 함께 고민해야 한다.

 

계획을 따르기보다 변화에 대응

초기 아키텍처 설계가 완벽할 것이라는 환상을 버려야 한다. 변화를 수용할 수 있는 확장성 있는 코드 베이스를 유지하는 것이 핵심이다.

 

2. 개발자가 명심해야 할 애자일 원칙 3가지

가치 있는 소프트웨어를 일찍, 그리고 지속적으로 전달한다.

이는 곧 CI/CD 파이프라인의 구축을 의미한다. 개발자가 코드를 푸시하면 자동으로 테스트가 돌고 스테이징 서버에 배포되어야만 지속적인 전달이 가능하다.

 

기술적 탁월함과 좋은 설계에 대한 지속적 관심이 기민성을 높인다.

애자일을 단순히 빨리 대충 개발하는 것으로 오해하면 안 된다. 탄탄한 객체지향 설계와 리팩토링, 그리고 테스트 코드가 뒷받침되지 않으면 기술 부채가 쌓여 결국 변화에 대응할 수 없는 레거시가 된다.

 

단순성 - 안해도 될 일을 최대한 하지 않는 기술이 필수적이다.

미래에 발생할지도 모르는 오버 엔지니어링을 경계해야 한다. YAGNI(You Aren't Gonna Need It) 원칙에 따라 현재의 비즈니스 요구사항을 해결하는 가장 단순하고 우아한 구조를 선택해야 한다.

 

3.무늬만 애자일을 피하는 기술적 탁월함

요구사항이 매 스프린트마다 변경되는 애자일 환경에서, 기술적 탁월함이 결여된 코드는 어떻게 무너지는지, 그리고 어떻게 방어해야 하는지 살펴보자

 

할인정책(Discount Policy)이 수시로 변하는 이커머스 도메인을 가정해 보자. 기획팀은 이번 주에는 정액 할인을, 다음주에는 비율 할인을, 그 다음 주에는 특정 등급 전용할인을 테스트해보고 싶어 한다.

 

[Bad Code : 기술적 탁월함이 결여된 Fake Agile]

새로운 정책이 추가될 때마다 기존 OrderService 클래스의 코드를 직접 수정해야 한다. 사이드 이펙트가 두려워 배포를 주저하게 되고, 결국 요구사항 변경을 환영할 수 없는 상태가 된다.

 

@Service
public class OrderService {
    
    // 비즈니스 로직에 분기문(if-else)이 덕지덕지 붙기 시작함 (OCP 위반)
    public long calculatePrice(Order order, String discountType) {
        long price = order.getOriginalPrice();
        
        if ("FIXED".equals(discountType)) {
            price -= 1000; // 정액 할인
        } else if ("PERCENT".equals(discountType)) {
            price = price - (price * 0.1); // 10% 할인
        } else if ("VIP".equals(discountType)) {
            // 요구사항이 추가될 때마다 이 거대한 클래스를 수정해야 함
            price = price - (price * 0.2); 
        }
        return price;
    }
}

 

[Good Code: 변화를 환영하는 True Agile 아키텍처]

Spring Boot의 DI와 다형성을 적극 활용한 전략 패턴(Strategy Pattern) 구조다. 새로운 할인 정책이 필요하다면 기존 코드는 단 한 줄도 건드리지 않고, 새로운 클래스만 추가하여 확장에 열려 있는(OCP) 시스템을 만든다.

 

// 1. 추상화된 할인 인터페이스
public interface DiscountPolicy {
    boolean isSatisfiedBy(String discountType);
    long applyDiscount(long price);
}

// 2. 개별 정책 구현 (새로운 정책은 새로운 클래스 추가만으로 해결)
@Component
public class FixedDiscountPolicy implements DiscountPolicy {
    @Override
    public boolean isSatisfiedBy(String type) { return "FIXED".equals(type); }
    @Override
    public long applyDiscount(long price) { return price - 1000; }
}

// 3. 핵심 비즈니스 로직 (변화로부터 격리됨)
@Service
@RequiredArgsConstructor
public class OrderService {
    
    // Spring이 구현체 List를 런타임에 자동 주입
    private final List<DiscountPolicy> discountPolicies;

    public long calculatePrice(Order order, String discountType) {
        return discountPolicies.stream()
            .filter(policy -> policy.isSatisfiedBy(discountType))
            .findFirst()
            .map(policy -> policy.applyDiscount(order.getOriginalPrice()))
            .orElse(order.getOriginalPrice()); // 일치하는 정책이 없으면 원가 반환
    }
}

 

안전한 테스트 코드와 위와 같은 클린 아키텍처가 존재할 때, 개발자는 기획팀의 요구사항 변경을 스트레스가 아닌 프로덕트의 성장을 위한 자연스러운 실험으로 받아들일 수 있다.

 

결론

애자일은 기획자나 스크럼 마스터만의 전유물이 아니다. 훌륭한 프로세스를 도입하더라도, 개밭팀의 코드가 스파게티처럼 얽혀있다면 그 팀은 절대 애자일해질 수 없다.

 

무늬만 애자일을 피하고 진정한 기민성을 얻고 싶다면, Jira의 티켓 상태를 업데이트하는 것만큼이나 코드를 리팩토링하고, 자동화된 테스트를 작성하며, 아키텍처의 결합도를 낮추는 일(엔지니어링 프랙티스)에 팀의 리소스를 투자해야 한다. 시스템의 구조가 유연해야만 비즈니스도 유연해질 수 있다.

+ Recent posts