문제

이것은 "분석에 의한 마비"가 취한 것처럼 보이는 시나리오 중 하나입니다.

프로젝트

부품 참조, 어떤 차량에 맞는 차량 등과 같은 세부 사항을 포함하는 상당히 간단한 자동차 제품 목록.

프론트 엔드는 ASP.NET MVC 응용 프로그램입니다.

백엔드는 SQL이며 Subonic을 사용하여 제품을 도메인 객체로 투사합니다.

기능

화면 중 하나는 제품 세부 사항 화면입니다. ASP.NET MVC 컨트롤러는 제품 저장소를 호출하여 제품 세부 사항을 검색하고 (일부 자동 캡처를 통해 뷰 모델로)를 반환합니다.

이제 킬러 세부 사항은 채널에 따라 웹 사이트에 2 ~ 3 개의 채널이있어 사용자는 다른 부품 번호를 볼 필요가 있다는 것입니다.

예를 들어 소매 채널이라면 부품 번호가 데이터베이스에있는 것과 같지만 사용자가 거래 채널을 통해 사이트에 오면 부품 참조의 시작이 대체 번호로 대체됩니다.

예를 들어 0900876 트레이드 채널을 통해 보는 경우 1700876이됩니다.

내가 어려움을 겪고있는 곳은 부품 참조 (및 변경 될 수있는 기타 세부 사항)와 관련하여 "채널 규칙"을 캡슐화 할 위치를 결정하는 것입니다.

나는이 대안들을 고려했다.

로직을 도메인 객체에 직접 씁니다

제품 클래스 우리는 번역 된 부품 참조를 얻을 수있는 방법/속성을 가질 수 있습니다.

public string TranslatedPartRef()
    {
        if (this.Channel == "Trade")
        {
            return PartRef.Replace("0900", "1700");
        }
        else
        {
            return PartRef;
        }
    }      

이 시나리오에서 제품 인스턴스는 채널에 대해 알아야합니다.

다른 객체에서 논리를 캡슐화하십시오

우리는이 부분 참조 번역을 처리하기 위해 수업을 작성하거나 채널 이 논리를 포함하는 클래스.

내가 이해하지 못하는 것은 두 클래스를 조정하는 방법입니다.

컨트롤러가 리포지토리를 호출하여 제품을 검색 한 경우 사용 된 채널을 작성하고 부품 참조를 번역해야합니까? 그렇다면 어떻게 뷰로 번역 된 부품 참조로 제품을 보내려면?

또한이 부분 참조는 검색 결과 및 기타 시나리오에 나타나야한다는 점도 주목할 가치가 있습니다. 이런 이유로 도메인 어딘가에 깔끔하게 포함되어야한다고 생각합니다.

도움이 되었습니까?

해결책

나는 C# 가이가 아니지만 자바의 데코레이터로 이것을 공격 할 것이라고 생각합니다.

제품에 대한 인터페이스가 있다고 가정하면 부품 번호 문제를 관리하는 데코레이터를 만들 수 있습니다.

class Product implements IProduct {
    public String getProductCode();
    // etc
}

class ProductChannelDecorator implements IProduct
{
    // constructor, like this in C#?
    public ProductChannelDecorator(IProduct product, Channel channel) { 
        this.product = product;
        this.channel = channel;
    }
    public String getProductCode() {
        switch (this.channel) {
            case Channel.RETAIL:
                return this.decorated.getProductCode();
            case Channel.TRADE:
                return retailToTradeTransformer(this.product.getProductCode());
            // etc
        }
    }
    // etc
}

다른 팁

자신에게 물어봐야 할 첫 번째 질문은 채널의 개념이 도메인 개념인지 아닌지입니다. 당신의 질문은 그것이 그렇지 않다는 것을 나타내는 것처럼 보이지만 반면에, 나는 그것이 응용 프로그램에 따라 들린다 고 생각하지 않습니다.

당신이 물을 수있는 추가 질문은 다음과 같습니다. 앞으로이 도메인 모델 (예 : 웹 서비스 또는 풍부한 클라이언트) 위에 다른 응용 프로그램을 구축해야한다면 여전히 채널의 개념을 처리해야합니까?

제 생각에는 대답이 될 수 있습니다 .

내가 귀하의 질문을 이해하는 한, 채널은 어떤 방식 으로든 요청 컨텍스트와 관련이 있습니다. 아마도 그것은 실제로 사용자의 속성 일 것입니다. 또는 아마도 응용 프로그램 구성 자체의 속성 일 수도 있습니다.

어쨌든, 나는 그것이 실제로 도메인 개념이 아닌지에 대해 열심히 생각할 것입니다. 그렇다면 도메인 객체에 멋지게 속할 수 있습니다.

그렇지 않다면 PTOMLI가 제안한 데코레이터 구현은 좋은 접근 방식처럼 들립니다.

부품 번호의 여러 가지 변수가있을 것입니다. 그것이 단지 거래 v 소매라면 나는 단순히 제품 객체에 두 숫자를 모두 가지고 있고 UI에 어떤 표시를 할 것인지 결정하도록 매우 유혹을받습니다. 제품에서 행동 할 때는 신원이 "유형 {Trade, Retail}, 번호"일 수 있습니다.

유연한 모드를 위해서는 그것이 당신의 채널 아이디어가 괜찮다고 생각합니다. 그러나 양방향 책임이 있다면 소매점을 무역으로 매핑하는 경우, 이것은 효과가있는 것 같습니다. 채널 객체는 다른 변환 및 농축이 가능한 어댑터로 간주됩니다.

구현으로서 나는 각 채널에 대해 별도의 채널 객체를 생성하여 사례 문을 피하려고 시도하고 다른 논리를 피하려고합니다. 소매의 경우 채널 객체는 무역을위한 Noop Object가 될 수 있습니다. 공장은 Approporaye 채널 객체를 생성 할 수 있습니다.

부품 번호 매핑이 변경 될 수 있다면 어떨까요? 지금은 바로 변경되는 접두사이지만 다른 유형의 변경 사항이있을 수 있습니까? 어쩌면 당신은 이것을 필요로하지 않을 수도 있지만 :

비즈니스 수준에서, 당신은 제품이 채널에 따라 다른 부품 번호를 가질 수 있다고 말하고 있습니다 (모든 기본 비즈니스 개념). 따라서 데이터베이스 수준에서는 ProductID, ChannelID 및 PartNumber 열이있는 파트너십 테이블이있을 수 있습니다. 이것은 시간이 지남에 따라 더 많은 채널이 나타나는 경우를 다룰 것입니다 (오늘날 소매 또는 거래, 내일 웹, 우편 주문 등을 추가 할 수 있습니다.

객체 수준 에서이 맵은 a에 맵핑됩니다 Product 인스턴스가있는 인스턴스 Dictionary<Channel, PartNumber> 주어진 적절한 부품 번호를 얻는 데 사용할 수 있습니다. Channel.

이제 킬러 세부 사항은 채널에 따라 웹 사이트에 2 ~ 3 개의 채널이있어 사용자는 다른 부품 번호를 볼 필요가 있다는 것입니다.

간단한 솔루션 :

public interface IChannel
    function GetNumber(Part as IPart) as String
end interface

데코레이터, 스위치 없음, 제어의 역전 없음.

특정 채널의 부품 번호가 필요할 때 마다이 방법을 호출합니다.

dim Channel as IChannel = ...
dim Part as IPart = ...
dim PartNumber = Channel.GetNumber(Part)

다른 부품 번호 계산 방법이 필요할 때 마다이 인터페이스를 구현합니다.

public class TradeChannel
    implements IChannel

    public function GetNumber(Part as IPart) as String implements IChannel.GetNumber
        return Part.Number.Replace("0900", "1700")
    end function
end class
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top