所以我正在研究一个侧面项目的Web应用程序,它允许您在一个网站上跟踪来自多个公司的软件包。即您可以输入任何跟踪号码,服务器将检查其格式并吐出相应的跟踪信息。
Click here to see my file directory!
我决定推进策略模式和 facade ,因为我认为它可以很好地满足应用程序的目的。
以上是我目前的回购。
结构将是:
客户 - > 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和process(这显然是未完成的)。
我可以用某种形式的抽象来避免这种情况吗?
答案 0 :(得分: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();
这样,当您需要添加新的交付公司时,您将不得不为其创建一个新类,它将封装该交付公司的所有逻辑,并将其实例添加到{{1} }。
如果您有一些对所有交付公司都很常见的逻辑,那么您可以将DeliveryCompanyFactory
接口替换为具有通用逻辑的IDeliveryCompany
基类。