Move Class -- 移动类

本文介绍了一种重构技术——移动类,即将与当前包内其他类功能不相关的类移动到更合适的包中,以减少包间的依赖复杂度并提高代码重用性。文中详细解释了移动类的动机、操作步骤及示例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Move Class

Refactoring contributed by Gerard M. Davison

You have a class that is in a package that contains other classes that it is not related to in function.

在包里有一个类和其他的类在功能上没啥关系。

Move the class to a more relevant package. Or create a new package if required for future use.

将这个类移动到相关的包里,或者创建一个将来可能会使用的包,并移动到里面。

class org.davison.ui.TextThing
class org.davison.ui.TextProcessor
class org.davison.log.Logger

depends on 

class org.davison.ui.StringUtil

class org.davison.ui.TextThing
class org.davison.ui.TextProcessor
class org.davison.log.Logger

depends on

class org.davison.util.StringUtil

Motivation

Classes are often created in a packages close to where they are being used, this can make sense until the class starts to be re-used by other parts of the product. The package in question might also have just become too big. (I have a preference that my packages never have more than about 10 classes)

通常将功能相近的类组织到一个包里,这使得其他组件可以重用。

It is often better to move to this class to a package more related to it in form or function. This can help remove complex package level dependencies and make it easier for developers to find and re-use classes.

将一些形式或者相近功能的类组织到各自的包中,这样可以减少包与包之间的依赖复杂度,而且使得开发者更容易找到或者重用类。

If there are many dependencies for the class within its own package, then Extract Class could be used first to split out the relevant parts.

如果类在其自身的包中有很多依赖关系,然后使用首先提取类分离相关的部分。

Another example where is this used often is to move String resource objects into sub a res package to simplify localization compilation.

将国际化的String resource objects移动到一个子包里,便于管理以及修改。


Mechanics

  • Move the class to its new folder on the source tree.
  • 将这个类移动到新的包中。
  • Remove any class files generated from compiling this class at its old location.
  • 移除所有使用此类源文件头的import语句。
  • Alter the package statement in the source file to reflect the new package.
  • 修改类的旧package语句为新的package语句。
  • Create import statements for any dependant classes in original package.
  • 为所有依赖此类的java文件中添加新的import语句。
  • Compile and test the class in its new package, updating and moving unit tests as required using this same method.
  • 编译,并将移动类的单元测试移动相应的包中。
  • Alter, and create in some cases, the import statements on any dependee class. Note this is easier if wide imports are not used.
  • Check for classes that might dynamically instantiate this class using java.lang.reflect or the ResourceBundle api. Also look for code that might reference this class as an absolute class literal.
  • 还需要修改通过反射生成移动类的代码,或者ResourceBundle相关东西。
  • Compile and test all code that was dependant on the original class.
  • 编译,更新一下单元测试中对移动类的依赖点。
  • Consider applying extractPackage when you have many classes of different functionality in a given package.
  • 当一个包中有不同功能时,考虑使用extractPackage重构手段。

Example

Lets look at the header of StringUtil

看下类StringUtil文件类头。

package org.davison.ui

// imports

public class StringUtil

...

We move the file and change the package header.

移除旧package添加新package。

package org.davison.util

// imports

public class StringUtil

...

I can now compile and unit test this class in its new package. If the unit tests are in a different package class file then they might need to be updated.


I can now go on to update the dependant classes. For example here I update the import statements, I have not used a wide imports in this example but the principle is the same.


package org.davison.log

// imports

import org.davison.ui.StringUtils;

// more imports

public class Logger

...

This becomes:

package org.davison.log

// imports

import org.davison.util.StringUtils;

// more imports

public class Logger

...

Again compile and test this new class with the imports.

As mentioned before there are other ways of dynamically loading classes. You may have to look for class literals and strings constants containing the fully qualified name of the old class.

另外你可能需要在项目中搜索下,使用待移动类的类字面量(即类的绝对位置字符串)

// A class literal

public Class m_utils = org.davison.ui.StringUtils.class;

// A dynamically loaded class

public Class m_utils = Class.forName("org.davison.ui.StringUtils");

// A loaded resource bundle

public ResourceBundle m_bundle = ResourceBundle.getBundle(
   "org.davison.ui.StringUtils");

These can be fixed using simple find and replaces, these dynamic examples will also be found using the units tests for all classes.

然后将类字面量替换为新的类字面量。

// A class literal, this will be found by the compiler.

public Class m_utils = org.davison.util.StringUtils.class;

// A dynamically loaded class

public Class m_utils = Class.forName("org.davison.util.StringUtils");

// A loaded resource bundle

public ResourceBundle m_bundle = ResourceBundle.getBundle(
   "org.davison.util.StringUtils");

One all static and dynamic cases have been dealt with, and all unit tests have run. The refactoring is complete.

当所有的静态引用和动态引用解决后,测试一下。重构就算完成了。


通常在Ecplise中,选中要移动的类,拖动到待移动的包中,Ecplise会查找所有的引用点,并进行修改。但是一定还要根据作者的重构步骤,检查下待移动类的动态代码,将其修改掉,还有单元测试相关连的也需要修改。

在 Vue.js 中,过渡动画是一种在元素插入、更新或移除时添加动画效果的方式。`<transition>` 组件是 Vue 提供的用于处理过渡动画的组件之一。其中,`move-class` 属性用于指定在元素移动过程中应用的 CSS 。 `move-class` 属性允许你为元素在移动过程中的不同状态定义不同的 CSS 。当元素在进行插入、更新或移除时,Vue 会自动添加或删除这些 CSS 。 下面是 `move-class` 属性的详细解释: 1. **基本用法**:你可以将 `move-class` 属性添加到 `<transition>` 组件上,并指定一个用于移动过程中应用的 CSS 。 ```html <transition move-class="custom-move-class"> <!-- 元素内容 --> </transition> ``` 2. **名规则**:`move-class` 属性的值可以是一个字符串,也可以是一个对象。如果是一个字符串,它将被视为应用于所有移动过程中的状态;如果是一个对象,可以指定分别应用于不同状态的名。 ```html <!-- 字符串形式 --> <transition move-class="custom-move-class"> <!-- 元素内容 --> </transition> <!-- 对象形式 --> <transition :move-class="{ enter: 'enter-class', enterActive: 'enter-active-class', leave: 'leave-class', leaveActive: 'leave-active-class', appear: 'appear-class', appearActive: 'appear-active-class' }"> <!-- 元素内容 --> </transition> ``` 在对象形式中,可以定义以下名: - `enter`:插入时的起始状态名; - `enterActive`:插入时的过渡状态名; - `leave`:移除时的起始状态名; - `leaveActive`:移除时的过渡状态名; - `appear`:初次渲染时的起始状态名; - `appearActive`:初次渲染时的过渡状态名。 3. **CSS 定义**:你需要在 CSS 样式中定义这些名,以实现相应的过渡效果。例如: ```css .custom-move-class { transition: transform 0.3s ease; } .custom-move-class-enter { transform: translateX(-100%); } .custom-move-class-enter-active { transform: translateX(0); } .custom-move-class-leave { transform: translateX(0); } .custom-move-class-leave-active { transform: translateX(100%); } ``` 在上述示例中,我们定义了一个简单的过渡效果,使元素从左侧滑入和滑出。 通过使用 `move-class` 属性,你可以根据元素在插入、更新或移除时的不同状态,为其添加不同的 CSS ,从而实现自定义的过渡动画效果。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值