库、“注入工厂”和扩展库的最佳实践
Posted
技术标签:
【中文标题】库、“注入工厂”和扩展库的最佳实践【英文标题】:Library, “Injecting factory” and best practices for extending a library 【发布时间】:2021-09-12 19:29:07 【问题描述】:我使用了一个需要修补的库。我需要分叉它,因为没有使用工厂设计模式。
库具有这样的结构:X 类包含对其他类的引用、对其他类的引用以及更多层。类层次结构是“树状”结构。
我寻找重构的最佳方式——足够灵活以防止人们分叉它。我找不到任何关于该问题的最佳实践。
多年来,我使用“注入工厂”来解决这个问题——工厂模式在工厂方法中注入父对象 (DI)。我找不到任何关于这种方法的文档,我需要一些反馈(例如理论或可能的问题)。
我用汽车的例子来描述它:
汽车有 CarInterior CarInterior 有里程表问题 - 无法创建自定义对象,尤其是里程表。
class Car
CarInterior interior;
public Car()
interior = new CarInterior();
class CarInterior
Odometer odo;
public CasInterior()
odo = new Odomether();
class Odometer
public Odometer()
仅使用简单工厂方法模式的按书解决方案(扩展性有限)
class Car
CarInterior interior;
public Car(CarFactory factory)
interior = createInterior();
CarInterior createInterior() return new CarInterior(); ;
class CasInterior
Odometer odo;
public CarInterior()
odo = createOdometer();
CarInterior createOdometer()
return new Odomether();
这种方法的主要问题
如果工厂方法需要参数,则该更改可能会给 lib 用户带来麻烦。因为扩展类应该改变方法定义。小问题
如果我需要不同的里程表,我应该同时扩展 Car 和 CarInterior 我需要 fork 的库的“级别”很少,因此这意味着在我设法调用工厂方法之前有很多级别的额外对象。可能的业务请求
里程表类的可能扩展#1:KM 或 Miles
汽车对象应该有targetCountry。如果是在法国,则应使用公制单位。如果在美国 - 英里。 该业务请求可以通过这种方式实现:
(重大更改)工厂方法 createOdometer() 获取参数:createOdometer(OdoUnits) (重大更改)工厂方法 createInterior() 获取参数:createInterior(OdoUnits) 或 createInterior(Country) 如果级别更多(我的情况),则需要进行更多更改里程表类的可能扩展#2:里程表值范围
0-220 公里/小时 0-300 公里/小时 等里程表类的可能扩展#3:里程表颜色应与汽车颜色相同
如果我们使用相同的方法,我们应该在方法中引入更多参数。以及更多“代理”功能。
问题
那么解决这个问题的最佳做法是什么?当新需求出现时,我们如何避免/减少方法定义的更改?
【问题讨论】:
【参考方案1】:《注塑厂》
工厂方法需要一个额外的参数——父对象。 里程表获取其工厂,获取 Car 对象并请求所有需要的数据以适应“汽车规格”代码:
class CarFactory
CarInterior createInterior(Car car) return new CarInterior(car);
Odometer createOdometer(CarInterior interior) return new Odometer(interior); ;
class Car
CarFactory factory;
CarInterior interior;
public Car(CarFactory factory)
this.factory = factory;
interior = factory.createInterior(this);
CarFactory getFactory() return factory; ;
class CarInterior
Car car;
Odometer odo;
public CarInterior(Car car)
this.car = car;
CarFactory factory = car.getFactory();
odo = factory.createOdometer( this );
class Odometer
public Odometer(CarInterior interior)
Car car = interior.getCar();
OdoUnits odoUnits = car.getTargetCountry().getUnits();
int maxEngineSpeed = car.getEngine().getTopSpeed;
Color color = car.getColor();
if (!car.isOptionColorOdometer())
color = DEFAULT_COLOR;
// etc
【讨论】:
以上是关于库、“注入工厂”和扩展库的最佳实践的主要内容,如果未能解决你的问题,请参考以下文章
不使用支持库的 Android 4.0、4.1 (<4.2) 中嵌套片段的最佳实践
Closure Compiler - JavaScript 库项目的最佳实践?