💎一站式轻松地调用各大LLM模型接口,支持GPT4、智谱、星火、月之暗面及文生图 广告
反向重构:提炼类(182) ![](https://box.kancloud.cn/285313b923af452485225772917cec06_561x191.jpeg) ``` class Person {  get officeAreaCode() {return this._telephoneNumber.areaCode;}  get officeNumber()  {return this._telephoneNumber.number;} } class TelephoneNumber {  get areaCode() {return this._areaCode;}  get number() {return this._number;} } ``` ![](https://box.kancloud.cn/a3bed334e2e1f6d1a46c5039deb25af9_91x152.jpeg) ``` class Person {  get officeAreaCode() {return this._officeAreaCode;}  get officeNumber()  {return this._officeNumber;} ``` ### 动机 内联类正好与提炼类(182)相反。如果一个类不再承担足够责任,不再有单独存在的理由(这通常是因为此前的重构动作移走了这个类的责任),我就会挑选这一“萎缩类”的最频繁用户(也是一个类),以本手法将“萎缩类”塞进另一个类中。 应用这个手法的另一个场景是,我手头有两个类,想重新安排它们肩负的职责,并让它们产生关联。这时我发现先用本手法将它们内联成一个类再用提炼类(182)去分离其职责会更加简单。这是重新组织代码时常用的做法:有时把相关元素一口气搬移到位更简单,但有时先用内联手法合并各自的上下文,再使用提炼手法再次分离它们会更合适。 ### 做法 - 对于待内联类(源类)中的所有`public`函数,在目标类上创建一个对应的函数,新创建的所有函数应该直接委托至源类。 - 修改源类`public`方法的所有引用点,令它们调用目标类对应的委托方法。每次更改后运行测试。 - 将源类中的函数与数据全部搬移到目标类,每次修改之后进行测试,直到源类变成空壳为止。 - 删除源类,为它举行一个简单的“丧礼” ### 范例 下面这个类存储了一次物流运输(shipment)的若干跟踪信息(tracking information)。 ``` class TrackingInformation {  get shippingCompany() {return this._shippingCompany;}  set shippingCompany(arg) {this._shippingCompany = arg;}  get trackingNumber() {return this._trackingNumber;}  set trackingNumber(arg) {this._trackingNumber = arg;}  get display() {   return `${this.shippingCompany}: ${this.trackingNumber}`;  } } ``` 它作为`Shipment`(物流)类的一部分被使用。 ##### class Shipment... ``` get trackingInfo() {  return this._trackingInformation.display; } get trackingInformation() {return this._trackingInformation;} set trackingInformation(aTrackingInformation) {  this._trackingInformation = aTrackingInformation; } ``` `TrackingInformation`类过去可能有很多光荣职责,但现在我觉得它已不再能肩负起它的责任,因此我希望将它内联到`Shipment`类里。 首先,我要寻找`TrackingInformation`类的方法有哪些调用点。 ##### 调用方... `aShipment.trackingInformation.shippingCompany = request.vendor;`我将开始将源类的类似函数全都搬移到`Shipment`里去,但我的做法与做搬移函数(198)时略微有些不同。这里,我先在`Shipment`类里创建一个委托方法,并调整客户端代码,使其调用这个委托方法。 ##### class Shipment... ` set shippingCompany(arg) {this._trackingInformation.shippingCompany = arg;}`##### 调用方... `aShipment.trackingInformation.shippingCompany = request.vendor;`对于`TrackingInformation`类中所有为客户端调用的方法,我将施以相同的手法。这之后,我就可以将源类中的所有东西都搬移到`Shipment`类中去。 我先对`display`方法应用内联函数(115)手法。 ##### class Shipment... ``` get trackingInfo() { return `${this.shippingCompany}: ${this.trackingNumber}`; } ``` 再继续搬移“收货公司”(shipping company)字段。 ``` get shippingCompany() {return this._trackingInformation._shippingCompany;} set shippingCompany(arg) {this._trackingInformation._shippingCompany = arg;} ``` 我并未遵循搬移字段(207)的全部步骤,因为此处我只是改由目标类`Shipment`来引用`shippingCompany`,那些从源类搬移引用至目标类的步骤在此并不需要。 我会继续相同的手法,直到所有搬迁工作完成为止。那时,我就可以删除`TrackingInformation`类了。 ##### class Shipment... ``` get trackingInfo() {  return `${this.shippingCompany}: ${this.trackingNumber}`; } get shippingCompany() {return this._shippingCompany;} set shippingCompany(arg) {this._shippingCompany = arg;} get trackingNumber() {return this._trackingNumber;} set trackingNumber(arg) {this._trackingNumber = arg;} ```