2017-01-05 5 views
2

그래서 한 웹 사이트에서 여러 회사의 패키지를 추적 할 수있는 사이드 프로젝트 웹 응용 프로그램을 만들고 있습니다. 즉, 추적 번호를 입력하면 서버가 형식을 확인하고 적절한 추적 정보를 추출합니다.이 코드를 리펙토링하여 앞으로 나아갈 수있는 방법은 무엇입니까?

Click here to see my file directory!

나는 그것을 잘 응용 프로그램의 목적을 봉사 할 것입니다 생각하기 때문에하는 전략 패턴외관 앞으로 이동하기로 결정했습니다.

위 내 현재 repo입니다.

구조는 다음과 같습니다

클라이언트 -> DeliveryFacade -> DeliveryController -> TrackingInterface -> 다양한 회사의 API의 (페덱스, 캐나다 포스트, UPS).

저는 현재 DeliveryController에서 작업 중이며 작업 중 일부 코드가 발생했습니다.

이것이다 :

export default class DeliveryController{ 
 

 
    /** Checks the format of tracking number to determine the shipping company it 
 
    * has been given. If the tracking number is able to be validated, then return 
 
    * the correct shipping company. If it is not able to be validated (not a string), return 
 
    * null. 
 
    * 
 
    * @params trackingNumber : string 
 
    * @return shippingCompany : string 
 
    * 
 
    * e.g. returns "Fedex" , "CanadaPost", "UPS" 
 
    * */ 
 
    public checkFormat(trackingNumber : string) : string{ 
 

 
     if (typeof trackingNumber == "string" || trackingNumber instanceof String) { 
 

 
      // CanadaPost 
 
      if (/{regex}/.test(trackingNumber)){ 
 
       return "CanadaPost"; 
 
      } 
 

 
      // FedEx 
 
      if (/{regex}/.test(trackingNumber)) { 
 
       return "FedEx"; 
 
      } 
 
      // UPS 
 
      if (/{regex}/.test(trackingNumber)) { 
 
       return "UPS"; 
 
      } 
 
     } 
 
     else return null; 
 
    } 
 

 
    /** Processes a tracking number and returns a deliveryInfo. 
 
    * @param trackingNumber 
 
    * @return deliveryInfo 
 
    */ 
 

 
    public process(trackingNumber : string) : deliveryInfo{ 
 
     var company = this.checkFormat(trackingNumber); 
 
     switch (company){ 
 
      case "CanadaPost": 
 
       break; 
 
      case "FedEx": 
 
       break; 
 
      case "UPS": 
 
       break; 
 
     } 
 
     return /*some deliveryInfo*/; 
 
    }

내 질문은 이것이다 : 나는 각 전략의 명백한 반복을 제거 할 수있는 방법은 무엇입니까?

새로운 유형의 회사에서 새 추적 번호 형식을 추가하려는 경우 내 추적 전략 폴더에 새 클래스를 추가해야하며이 경우 사례를 checkFormat 및 프로세스에 추가해야합니다 (이는 분명합니다). 다듬지 않은).

이것을 방지하기 위해 사용할 수있는 추상화가 있습니까?

답변

0

TypeScript를 사용한다는 사실을 잊어 버렸습니다. 새 배달 회사를 추가해야하는 경우

interface IDeliveryCompany { 
    tackingNumberMatch(trackingNumber: string): boolean; 
    process(): void; 
} 

class UPSDeliveryCompany implements IDeliveryCompany { 

    trackingNumberMatch(trackingNumber: string): boolean { 
     return /{regex}/.test(trackingNumber); 
    } 

    process(): void { 
      // ... do the processing 
    } 
} 

// ... similar other delivery companies ... 

class DeliveryCompanyFactory { 

    private _companies: Array<IDeliveryCompany>; 

    constructor() { 
     _companies = [ 
      new UPSDeliveryCompany(), 
      new CanadaPostDeliveryCompany(), 
      new FedExDeliveryCompany() 
     ]; 
    } 

    getCompany(trackingNumber: string): IDeliveryCompany { 
     return this._companies.find((c) => c.trackingNumberMatch(trackingNumber)); 
    } 
} 

/// example usage: 
const factory = new DeliveryCompanyFactory(); 
factory.getCompany("some_tracking_number").process(); 

그 방법은, 당신이 그 모든 로직을 캡슐화합니다 그것을위한 새로운 클래스를 만들어야합니다 :

나는 그런 일을 할 것 배달 회사를 선택하고 DeliveryCompanyFactory에 해당 인스턴스를 추가하십시오.

모든 배송 업체에 공통적 인 로직이있는 경우 IDeliveryCompany 인터페이스를 공통 로직 인 DeliveryCompany 기본 클래스로 바꿀 수 있습니다.

+0

와우, 알았어, 그건 실제로 많은 의미가 있습니다. 고맙습니다! – astraeus

+0

그것이 의미가 있다고 생각한다면 대답으로 표시하는 것을 잊지 마십시오. :) –