2017-01-05 2 views
2

Итак, я работаю над веб-приложением стороннего проекта, которое позволяет отслеживать пакеты из нескольких компаний на одном веб-сайте. т. е. вы можете ввести любой номер отслеживания, и сервер проверит его формат и высветит соответствующую информацию отслеживания.Как мне двигаться вперед с рефакторингом этого кода?

Click here to see my file directory!

Я решил двигаться вперед с шаблоном стратегии, и фасад, потому что я думаю, что он будет служить цели применения хорошо.

Выше моего текущего репо.

структура будет:

Клиент -> DeliveryFacade -> DeliveryController -> TrackingInterface -> Различные API лица компании (FedEx, CanadaPost, 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

Не забудьте отметить это как ответ, если считаете, что это имеет смысл :) –

Смежные вопросы