【问题标题】:How Should I Move Forward With Refactoring This Code? [closed]我应该如何继续重构这段代码? [关闭]
【发布时间】:2017-01-05 01:13:40
【问题描述】:

所以我正在开发一个辅助项目 Web 应用程序,它可以让您在一个网站上跟踪来自多家公司的包裹。即您可以输入任何跟踪号,服务器将检查其格式并输出相应的跟踪信息。

Click here to see my file directory!

我决定继续使用策略模式外观,因为我认为它可以很好地服务于应用程序的目的。

以上是我目前的回购。

结构是:

Client -> 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 和处理(这显然是未完成的)。

我可以使用某种抽象形式来避免这种情况吗?

【问题讨论】:

    标签: javascript design-patterns abstraction repeat


    【解决方案1】:

    你忘了说你正在使用 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 基类。

    【讨论】:

    • 哇,好吧,这实际上很有意义。谢谢!
    • 如果您认为有意义,请不要忘记将其标记为答案 :)
    猜你喜欢
    • 2021-05-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-12-28
    • 2023-02-12
    • 1970-01-01
    相关资源
    最近更新 更多