重构以将私有字段从一个类移至其辅助类?
编辑:我为此重构提交了 Eclipse 增强请求。
有没有办法将私有字段从一个类移动到其辅助类?下面的鸡爪 UML 显示了我现在手动执行的操作。 C1
类在重构之前具有私有 field
和对 Helper
对象的私有最终引用。
重构后,C1'
中对 field
的所有引用均更改为 helper.getField()
和 helper.setfield()< /code> 视情况而定。
class Field {}
class C1 {
final private Field field;
final private Helper helper;
public Field getField() {
return field;
}
public C1() {
helper = new Helper();
field = new Field();
}
}
class Helper {}
class C1Prime {
final private HelperPrime helper;
public Field getField() {
return helper.getField();
}
public C1Prime() {
helper = new HelperPrime();
}
}
class HelperPrime {
final private Field field;
public HelperPrime() {
field = new Field();
}
public Field getField() {
return field;
}
}
我已经经常使用 Eclipse 的重构功能,但我无法找到一种方法来自动执行此操作。
例如,理想情况下,我会将私有字段/属性/成员从一个类拖到另一个类,并希望 Eclipse 询问我要如何处理未解析的引用。它不提供任何建议并且破坏了所有参考文献。
我一直在重复的操作是分离不真正属于当前类的知识和行为。我正在将引用某些字段的属性和行为从原始类移至新的“帮助程序”类中。
我重构的第一步是移动字段。对帮助程序类的引用作为我正在重构的类中的一个字段存在。为了在重构期间不破坏 C1
,我认为如果 Eclipse 能够在 Helper'
中生成 getter 和 setter 并更新 中的引用,那就太好了C1
在新类中使用 getter/setter。
EDIT : I submitted an Eclipse enhancement request for this refactoring.
Is there a way to move a private field from one class to its helper class? The below chicken-scratch UML shows what I'm doing manually right now. Class C1
has private field
and a private final reference to a Helper
object before the refactoring.
After the refactoring, all references in C1'
to field
are changed to helper.getField()
and helper.setfield()
as appropriate.
class Field {}
class C1 {
final private Field field;
final private Helper helper;
public Field getField() {
return field;
}
public C1() {
helper = new Helper();
field = new Field();
}
}
class Helper {}
class C1Prime {
final private HelperPrime helper;
public Field getField() {
return helper.getField();
}
public C1Prime() {
helper = new HelperPrime();
}
}
class HelperPrime {
final private Field field;
public HelperPrime() {
field = new Field();
}
public Field getField() {
return field;
}
}
I've used Eclipse's refactoring capabilities quite a bit, but I can't figure out a way to automate this.
For instance, ideally I would drag the private field/attribute/member from one class to another and hope that Eclipse asks me how I want to handle the unresolved references. It offers no suggestions and breaks all of the references.
The operation that I've been repeating is to separate knowledge and behavior that doesn't really belong in the current class. I'm moving attributes and behavior that references certain fields out of the original class into a new "helper" class.
The first step in my refactoring is to move the fields. A reference to the helper class exists as a field in the class I'm refactoring from. In order not to break C1
during the refactoring, I think it would be nice if Eclipse offered to to generate getters and setters in Helper'
and update the references in C1
to use the getters/setters in the new class.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
嗯,一般而言,这种做法根本没有意义。从语义上讲,这是一个奇怪的操作。如果将该字段移动到一个新的、不相交的类(例如从 String 到 Integer),则引用它的代码将不会有新类的实例可用于获取实例字段。
因此,只有在特殊情况下才有意义:当字段是静态成员时,或者您将其移动到父类时。
对于静态成员,右键单击要移动的字段(变量名称),然后单击“重构”->“移动”即可。选择新类型。引用会自动更新(你自己试试看)
当你将它移入/移出父类时,你可以使用 Refactor->Pull Up 或 Push Down,但这不会自动为您更改引用(只有下推有问题;上拉多态性表明引用仍然没问题)。
Well, it simply doesn't make sense for this to work in general. Semantically, it's a weird operation. If you move the field to a new, disjoint class (say from String to Integer) the code that referenced it wouldn't have an instance of the new class to use to get the instance field.
So there are only special cases where it makes sense: when the field is a static member, or you're moving it to a parent class.
For static members, it works fine to right-click on the field you want to move (the variable name), and click Refactor->Move. Choose the new type. References will automatically be updated (try it yourself and see)
For when you're moving it to/from a parent class, you can use Refactor->Pull Up or Push Down, but this will not automatically change references for you (only an issue with Push Down; with Pull Up polymorphism dictates that the references are all still fine).
问题是,你的字段必须是私有的(我什至不知道为什么存在创建公共非最终字段的能力)。那么你怎么可能从另一个类访问它呢?
如果您不想在重构过程中破坏它,我可以给您一个我使用的小技巧,有时会有所帮助。
创建类时,使其成为现有类的内部类或同一文件中的第二个类。
如果将其设为内部类,则可以先复制方法,它们可以引用另一个类中的成员。一旦您移植了所有功能,您就可以移动变量。此时,不应更新对该变量的任何引用,因为无论它位于哪个类,您都以相同的方式访问它。
如果您也拆分功能,则将一个类作为同一文件中的第二个类可能会很好 - -它可以让您一次访问所有内容,而无需在窗口之间移动鼠标。完成后,只需将新类拖到它自己的 java 文件中,重新计算导入,重新格式化使其公开并保存。
在创建与现有类交互的新类时,我几乎总是使用其中一种方法。
The thing is, your field must be private (I don't even know why the ability to create public non-final fields exists). So how could you possibly access it from another class?
If you don't wish to break it during a refactor I can give you a little trick I use that kinda helps sometimes.
When you create your class, make it either an inner class of the existing class or a second class in the same file.
If you make it an inner class you can copy the methods over first and they can refer to the member in the other class. Once you get all the functionality ported over you can move the variable. At this point none of the references to the variable should be updated since you access it the same way regardless of which class it was in.
Making a class a second class in the same file can be nice if you are splitting apart functionality as well--it lets you access everything at once without mousing between windows. When you are done just drag the new class into it's own java file, recalculate imports, reformat make it public and save it.
I nearly always use one of these methodologies when creating a new class that interacts with existing classes.
场地上的移动操作将无法正常进行。您可以移动字段,但 eclipse 不会移动 getter 和 setter。这是一个有趣的问题,如果这可能的话,我认为不可能。
The move operation on a field won't work appropriately. You can move a field but eclipse won't move the getters and setters. It's an intresting question if this is possible i don't think it is.
不会
右键单击该字段>重构>移动
做什么?是的,它不会更新引用,但想象一下它必须做什么 - 在引用您的字段的所有地方,它都必须实例化新类。那不切实际。
Won't
right click the field > Refactoring > Move
do?Yes, it does not update references, but imagine what would it have to do - in all places where your field is referenced, it will have to instantiate the new class. That's not practical.
对于 Java 函数,您只需右键单击其名称,然后选择
Refactor > 即可。移动。在向导中,选择现在将管理此方法的新类。
我认为这可以帮助您完成任务,即使您无法一次选择必须移动的多个元素......
For a Java function, you can simply right click on its name, then select
Refactor > Move
. In the wizard, select the new class that will now manage this method.I think this can help you in your task, even if you can't choose several elements at once that must be moved...
如果目标类尚不存在,您可以使用
Refactor >;提取类
。这将创建一个包含您选择的字段的新类,并将这种类型的字段添加到您的原始类中。我不确定您是否可以对确实存在的类执行此操作 - 但您始终可以使用提取类,然后将其内容剪切并粘贴到新类中。
If the target class doesn't already exist, you can use
Refactor > Extract Class
. This will create a new class containing the fields you select, and add a field of this type into your original class.I'm not sure if you can do it for a class that does exist - but you could always use Extract Class and then cut'n'paste its contents into your new class.