2017-01-05 7 views
2

私は1つのウェブサイト上の複数の企業のパッケージを追跡できるサイドプロジェクトのWebアプリケーションに取り組んでいます。すなわち、任意の追跡番号を入力することができ、サーバはその追跡フォーマットをチェックし、適切な追跡情報を吐き出す。このコードをリファクタリングして前進する方法

Click here to see my file directory!

私はそれがうまくアプリケーションの目的を果たすと思うので、私は、戦略パターン、およびファサードで前方に移動することを決めました。

上記は私の現在のレポです。

構造は次のようになります。

クライアント - > 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

それが意味をなさないと思うなら、それを答えとしてマークすることを忘れないでください:) –

関連する問題