组合性是SOLID的真正目标
当我们仔细检查S.O.L.I.D. 原则时, 我们能看见它真正目标是提供我们一种能力,一种改变和调整我们的软件的能力,这种能力体现在重新组合不同部件, 比如一个对象和另外一个对象的对换,但是从外表和行为来看,两者还是兼容的。
以下面这个股票交易应用的高层设计为例子:
通过划分任务变为分离的模块,每个都有特定的职责,然后结合不同模块通过依赖注入整进应用之中,将图中的Application类和各种抽象绑定在一起,而不是和具体能力实现绑定,这样,每个抽象能够有不同能力实现,不同用户界面,不同报表输出,不同数据库持久和不同的外部资源用来进行收集股票价格数据。
public Application(View view, Database database, Output output, StockData stockData) { | |
this.view = view; | |
this.database = database; | |
this.output = output; | |
this.stockData = stockData; | |
} |
我们能有一个Windows UI, 输出报表到Excel, 存储数据在Neo4J database, 然后从Bloomberg获得股票数据. 每个模块其实有3x3x3x3可能。
public static void main(String[] args) { | |
JdbcWriter writer = new JdbcWriter(); | |
Application application = new Application(new Windows(), new Neo4J(), new Excel(writer), new Bloomberg()); | |
} |
注意,这种模式是可重复的,比如对于Excel输出实现,有选项:我们选择使用JdbcWriter来进行输出写入到Excel文件. 一个不同的写入实现也许会是通过API自动输出,设计Application如下:
public Application() { | |
this.view = new Windows(); | |
this.database = new Neo4J(); | |
this.output = new Excel(new JdbcWriter()); | |
this.stockPrice = new Bloomberg(); | |
} |
这样,这个系统会提供给我们易于配置各种可能,我们使用配置为不同定制不同的Application class.
正确做S.O.L.I.D. , 我们的配置系统通过把一个对象注入对象方式结合在一起,而不是从顶层开始调用,这种系统的Web版本能够适合不同的项目启动模板。
通过增加新的模块,如水晶报表输出,是轻而易举的,因为系统其他部分只看得见Output接口,只是期待Output行为。
因此,组合性其实是SOLID的战略目标。
面向对象专题