Extract Package -- 抽取包
2013-03-18 12:25
85 查看
Refactoring contributed by Gerard M. Davison
A package either has too many classes to be easily understandable or it suffers from the 'Promiscuous packages' smell.
一个包有太多类以至于不易理解或者有种“混杂包”的坏味道。
Extract a sub package depending on their gross dependencies or usages.
根据依赖关系或者用法进行子包的抽取。
无论项目大小,依赖关系早晚会引起问题,所以这就意味着重构应尽早进行,要搞清楚每一部分代码都用来干什么。
This sort of change can make the code more flexible. For example if you are writing a UI tool and then decide a command line variant is required. Then unless the code is properly structured you will have trouble re-using
certain components. Packaging is one way of making dependencies explicit.
抽取包能使代码更灵活。例如,你正在写UI工具,并且还得利用命令行来实现需求。良好的组织包使得依赖更清晰。
This refactoring can be useful when a package becomes too large to be easily understood. For example in a diagrammer framework you might like to extra sub packages for important groups such as 'shapes'; 'ui' and 'printing'.
This makes it easier to identify the use of a class by its implied association in a package.
当包太大不易理解时,抽取包是一种有用的重构手段。例如图表制作仪框架,你会抽取重要的子包,“Shapes”、“UI”、“Printing”。这使得容易辨别包与包之间的隐含关系。
The structure produced here is also one that is recommeneded for use with the Abstract Factory pattern. Indeed this is how the example I have provided is structured.
推荐使用Abstract Factory pattern来进行组织。
制定出类分组。首先看看哪里需要使用extractSuperclass手段将通用的代码组织在一起。
Create the new package and perform moveClass for each file that needs to be moved. It is often efficient to move groups of classes at once.
创建一个新包,使用moveClass手段重构需要移动的类。
Compile the code in the parent package and retest. The code in the sperate package will have been tested as part of the moveClass refactoring.
编译,测试。
The refactorings at this point can be considered complete.
此时重构就算完成了。
You might like to convert the code in the factory to using dynamic class loading by using the convertStaticToDynamicConstruction. This would enable selective inclusion of
sub-packages depending on the build environment.
你可能需要使用ConvertStaticToDynamicConstruction重构手段在工厂中实现动态加载类。使得在特定环境使用特定的子包。
例子可以参考Move Class重构手段。
有时候我利用抽取包重构手段一口气移动了所有的类。(因为在编译期可以发现所有错误,所以使我能够大胆的进行一大步重构)
I ensure the original package is dependent on the extracted package but the extracted package is independent of the original. Once I've done the move I compile the original package. The errors here can be fixed with import statements in the offending classes.
I fix these errors until the original package compiles
我应该保证原始包依赖于抽取出来的包,但是抽取出来的包必须是独立于原始包的。抽取包之后,编译原始包,利用import语句解决编译错误。
Then I work on the extracted package. This may compile fine, the problem lies if you have a class in the extracted package referring to a class in the original package. I move it back if I can. If not I use extractInterface to
create an interface which captures the way the classes in the extracted pacakge refer to the original class. I then place the extracted interface in the extracted package.
然后我开始处理抽取出来的包。如果抽取出来的包引用了原始包,尽可能重构回退,不行的话,利用extractInterface创建一个接口,这个接口主要是抽取包引用原始包的接口,然后将这个接口放到抽取出来的包里。
Martin Fowler
A package either has too many classes to be easily understandable or it suffers from the 'Promiscuous packages' smell.
一个包有太多类以至于不易理解或者有种“混杂包”的坏味道。
Extract a sub package depending on their gross dependencies or usages.
根据依赖关系或者用法进行子包的抽取。
interface org.davison.data.DataProvider class org.davison.data.DataFactory // Database classes class org.davison.data.JDBCProvider class org.davison.data.JDBCHelper class org.davison.data.JDBCUtils
interface org.davison.data.DataProvider class org.davison.data.DataFactory // Database classes class org.davison.data.jdbc.JDBCProvider class org.davison.data.jdbc.JDBCHelper class org.davison.data.jdbc.JDBCUtils
Motivation
Dependencies will eventually cause problem in projects of any size, so it make sense to start refactoring sooner rather than later in order to make it clear which part of the code uses what.无论项目大小,依赖关系早晚会引起问题,所以这就意味着重构应尽早进行,要搞清楚每一部分代码都用来干什么。
This sort of change can make the code more flexible. For example if you are writing a UI tool and then decide a command line variant is required. Then unless the code is properly structured you will have trouble re-using
certain components. Packaging is one way of making dependencies explicit.
抽取包能使代码更灵活。例如,你正在写UI工具,并且还得利用命令行来实现需求。良好的组织包使得依赖更清晰。
This refactoring can be useful when a package becomes too large to be easily understood. For example in a diagrammer framework you might like to extra sub packages for important groups such as 'shapes'; 'ui' and 'printing'.
This makes it easier to identify the use of a class by its implied association in a package.
当包太大不易理解时,抽取包是一种有用的重构手段。例如图表制作仪框架,你会抽取重要的子包,“Shapes”、“UI”、“Printing”。这使得容易辨别包与包之间的隐含关系。
The structure produced here is also one that is recommeneded for use with the Abstract Factory pattern. Indeed this is how the example I have provided is structured.
推荐使用Abstract Factory pattern来进行组织。
Mechanics
Work out groupings for your classes. Where required use the extractSuperclass to pull together any generic code first.制定出类分组。首先看看哪里需要使用extractSuperclass手段将通用的代码组织在一起。
Create the new package and perform moveClass for each file that needs to be moved. It is often efficient to move groups of classes at once.
创建一个新包,使用moveClass手段重构需要移动的类。
Compile the code in the parent package and retest. The code in the sperate package will have been tested as part of the moveClass refactoring.
编译,测试。
The refactorings at this point can be considered complete.
此时重构就算完成了。
You might like to convert the code in the factory to using dynamic class loading by using the convertStaticToDynamicConstruction. This would enable selective inclusion of
sub-packages depending on the build environment.
你可能需要使用ConvertStaticToDynamicConstruction重构手段在工厂中实现动态加载类。使得在特定环境使用特定的子包。
Example
There are no code examples as most of the work in done in moveClass.例子可以参考Move Class重构手段。
Additional Comments 附加说明
The way I've done this is to move all the classes in one go. (I'm prepared to take the big step first here since all the errors can be found with compiling.)有时候我利用抽取包重构手段一口气移动了所有的类。(因为在编译期可以发现所有错误,所以使我能够大胆的进行一大步重构)
I ensure the original package is dependent on the extracted package but the extracted package is independent of the original. Once I've done the move I compile the original package. The errors here can be fixed with import statements in the offending classes.
I fix these errors until the original package compiles
我应该保证原始包依赖于抽取出来的包,但是抽取出来的包必须是独立于原始包的。抽取包之后,编译原始包,利用import语句解决编译错误。
Then I work on the extracted package. This may compile fine, the problem lies if you have a class in the extracted package referring to a class in the original package. I move it back if I can. If not I use extractInterface to
create an interface which captures the way the classes in the extracted pacakge refer to the original class. I then place the extracted interface in the extracted package.
然后我开始处理抽取出来的包。如果抽取出来的包引用了原始包,尽可能重构回退,不行的话,利用extractInterface创建一个接口,这个接口主要是抽取包引用原始包的接口,然后将这个接口放到抽取出来的包里。
Martin Fowler
相关文章推荐
- 使用Datax抽取ORACLE数据到MYSQL或TiDB
- 基于神经网络的实体识别和关系抽取联合学习
- JavaEE之BaseServlet的抽取
- Dubbo接口抽取及依赖版本统一-03
- 记录一次powercenter数据抽取问题解决
- ETL工具kettle怎么进行增量数据抽取:一、通过标志位
- 【转贴】java抽取word,pdf的四种武器
- Rss应用(二) 抽取Rss
- ACCESS如何随机抽取数据
- 数据仓库自动抽取:通过 SQL Server 企业管理器中的数据转换服务 (DTS) 设计器 创建 Analysis Services 处理任务
- java抽取word,pdf的四种武器
- Java语言中抽取Office、PDF的四件兵器
- WEB网页结构化信息抽取技术介绍(网页库级)
- 数据抽取技术大全--欢迎大家补充
- [原]基于统计的中文网页正文抽取的研究
- 一个长度为10000的字符串,通过随机从a-z中抽取10000个字符组成.请用c#语言编写主要程序来实现
- jacob 抽取word文档
- Java抽取网页信息
- c# 正则表达式对网页进行有效内容抽取
- 从文档中抽取文本,实现 Word, Excel, PowerPoint 文件的全文搜索