2010-10-04 35 views
10

EDIT: Tôi đã gửi Eclipse enhancement request for this refactoring.Tái cấu trúc để di chuyển một trường riêng tư từ một lớp đến lớp trợ giúp của nó?

Có cách nào để di chuyển trường riêng tư từ một lớp này sang lớp trợ giúp khác không? UML dưới đầu gà cho thấy những gì tôi đang làm bằng tay ngay bây giờ. Lớp C1 có riêng tư field và tham chiếu cuối cùng riêng tư đối tượng Helper trước khi tái cấu trúc.

Sau khi tái cấu trúc, tất cả các tham chiếu trong C1' đến field được đổi thành helper.getField()helper.setfield() nếu thích hợp.

UML Diagram

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; 
    } 
} 

Tôi đã sử dụng khả năng sắp xếp của Eclipse khá một chút, nhưng tôi không thể tìm ra một cách để tự động này.

Ví dụ, lý tưởng tôi sẽ kéo lĩnh vực/thuộc tính/viên tin từ nhóm này sang nhóm khác và hy vọng rằng Eclipse hỏi tôi làm thế nào tôi muốn để xử lý các tài liệu tham khảo chưa được giải quyết. Nó cung cấp không có đề xuất và phá vỡ tất cả các tài liệu tham khảo.

Hoạt động mà tôi đã lặp lại là phân tách kiến ​​thức và hành vi không thực sự thuộc về lớp hiện tại. Tôi đang di chuyển các thuộc tính và hành vi tham chiếu các trường nhất định ra khỏi lớp gốc thành một lớp "helper" mới.

Bước đầu tiên trong việc tái cấu trúc của tôi là di chuyển các trường. Một tham chiếu đến lớp helper tồn tại như một trường trong lớp tôi đang tái cấu trúc từ. Để không phá vỡ C1 trong quá trình tái cấu trúc, tôi nghĩ sẽ tốt hơn nếu Eclipse cung cấp getters và setters trong Helper' và cập nhật các tham chiếu trong C1 để sử dụng getters/setters trong lớp mới.

+1

Để biết thông tin, bạn đang sử dụng phiên bản Eclipse nào? – romaintaz

+0

3.5, nhưng tôi sẽ thử nâng cấp lên 3.6 nếu tính năng này được cải thiện. Tuy nhiên, tôi đọc các ghi chú phát hành và nó xuất hiện ít thay đổi trong 3.6 liên quan đến tái cấu trúc. –

Trả lời

2

Vấn đề là trường của bạn phải ở chế độ riêng tư (tôi thậm chí không biết tại sao khả năng tạo trường không phải là trường công khai tồn tại). Vậy làm thế nào bạn có thể truy cập nó từ một lớp khác?

Nếu bạn không muốn phá vỡ nó trong một refactor tôi có thể cung cấp cho bạn một mẹo nhỏ tôi sử dụng kinda đó giúp đôi khi.

Khi bạn tạo lớp học, hãy đặt lớp đó thành lớp bên trong của lớp hiện tại hoặc lớp thứ hai trong cùng một tệp.

Nếu bạn làm cho nó trở thành lớp bên trong, bạn có thể sao chép các phương thức trước và chúng có thể tham chiếu đến thành viên trong lớp khác. Khi bạn nhận được tất cả chức năng được chuyển qua, bạn có thể di chuyển biến. Tại thời điểm này không có tham chiếu nào đến biến nên được cập nhật kể từ khi bạn truy cập nó theo cùng một cách bất kể lớp đó thuộc loại nào.

Tạo lớp học thứ hai trong cùng một tệp có thể tốt đẹp nếu bạn chia tách cũng như chức năng này - cho phép bạn truy cập mọi thứ cùng một lúc mà không cần di chuyển giữa các cửa sổ. Khi bạn thực hiện xong, chỉ cần kéo lớp mới vào tệp java riêng của nó, tính toán lại nhập khẩu, định dạng lại làm cho nó công khai và lưu nó.

Tôi gần như luôn sử dụng một trong các phương pháp này khi tạo lớp mới tương tác với các lớp hiện có.

0

Đối với một hàm Java, bạn chỉ cần click chuột phải vào tên của nó, sau đó chọn Refactor > Move. Trong trình hướng dẫn, chọn lớp mới sẽ quản lý phương thức này.

Tôi nghĩ rằng đây có thể giúp bạn trong công việc của bạn, ngay cả khi bạn không thể chọn một số yếu tố cùng một lúc mà phải được di chuyển ...

+0

Không, quá trình tái cấu trúc trường di chuyển của Eclipse về cơ bản chỉ cắt và dán trường, điều ngạc nhiên là các phép tái cấu trúc khác của Eclipse mạnh như thế nào. –

+0

Ngoài ra, bạn có thể chọn bao nhiêu tùy thích và Eclipse sẽ di chuyển chúng. Nó không làm gì liên quan đến nó. –

+0

Tôi vừa thử trong Eclipse Helios để di chuyển một phương thức từ lớp này sang lớp khác và Eclipse tự động cập nhật các kiểm tra JUnit của tôi. Vì vậy, đối với tôi, nó không phải là một thao tác sao chép/dán đơn giản ở đây ... – romaintaz

1

Sẽ không right click the field > Refactoring > Move làm gì?

Vâng, nó không cập nhật tài liệu tham khảo, nhưng hãy tưởng tượng những gì nó sẽ phải làm - trong tất cả những nơi mà lĩnh vực của bạn được tham chiếu, nó sẽ phải nhanh chóng lớp mới. Điều đó không thực tế.

+1

Không, quá trình tái cấu trúc trường di chuyển của Eclipse về cơ bản chỉ cắt và dán trường, điều ngạc nhiên là các phép tái cấu trúc khác của Eclipse mạnh như thế nào. –

+0

Hoặc thông minh hơn một chút, nó sẽ nhận thấy tôi đã có một tham chiếu đến đối tượng trong lớp của tôi và đề nghị sử dụng nó thay thế. –

+0

+1 Điều này hoạt động hoàn toàn tốt cho các hằng số. Dễ dàng cập nhật các tài liệu tham khảo quá – Ravisha

1

Thao tác di chuyển trên một trường sẽ không hoạt động phù hợp. Bạn có thể di chuyển một trường nhưng nhật thực sẽ không di chuyển các getters và setters. Đó là một câu hỏi intresting nếu điều này là có thể tôi không nghĩ rằng nó được.

+0

Đây là những gì tôi đã sợ. Tôi sẽ phải gửi yêu cầu nâng cao. Tôi không thể thấy bất kỳ lý do nào tại sao điều này không dễ dàng được tự động hóa. –

0

Nếu lớp đối tượng không tồn tại, bạn có thể sử dụng Refactor > Extract Class. Việc này sẽ tạo một lớp mới chứa các trường bạn chọn và thêm một trường thuộc loại này vào lớp ban đầu của bạn.

Tôi không chắc chắn nếu bạn có thể làm điều đó cho một lớp học mà không tồn tại - nhưng bạn luôn có thể sử dụng Extract Class và sau đó cut'n'paste nội dung của nó vào lớp mới của bạn.

+0

Phải, nhưng sau đó các tham chiếu đến lớp mới tạm thời không được cập nhật để truy cập vào lớp mà tôi vừa dán chúng vào. Điều này sẽ không tốt hơn là chỉ di chuyển chúng trực tiếp đến lớp mong muốn. –

8

Vâng, đơn giản là không có ý nghĩa khi làm việc này nói chung. Về mặt ngữ nghĩa, đó là một hoạt động kỳ lạ.Nếu bạn di chuyển trường đến một lớp mới, phân tách (nói từ String thành Integer), mã tham chiếu nó sẽ không có một cá thể của lớp mới để sử dụng để lấy trường cá thể.

Vì vậy, chỉ có những trường hợp đặc biệt mà nó có ý nghĩa: khi trường là một thành viên tĩnh hoặc bạn di chuyển nó đến một lớp cha.

Đối với thành viên tĩnh, hoạt động tốt khi nhấp chuột phải vào trường bạn muốn di chuyển (tên biến) và nhấp vào Trình chuyển đổi-> Di chuyển. Chọn loại mới. Tài liệu tham khảo sẽ tự động được cập nhật (tự mình thử và xem)

Khi bạn di chuyển nó đến/từ lớp cha, bạn có thể sử dụng Refactor-> Pull Up hoặc Push Down, nhưng điều này sẽ không tự động thay đổi tài liệu tham khảo cho bạn (chỉ có một vấn đề với Push Down; với Pull Up đa hình dictates rằng các tài liệu tham khảo là tất cả vẫn còn tốt).

+0

Tất nhiên điều này có ý nghĩa. Lớp helper không phải là một lớp rời rạc; nó là một lớp * helper * được chứa bởi lớp đầu tiên và có cùng dòng thời gian với lớp tham chiếu 'C1'. Lớp helper là trường 'final', do đó luôn luôn hiện diện và có thể truy cập được. –

+0

@ Jeff Tôi đã trả lời câu hỏi này hai năm trước và trước khi bạn cung cấp các giải thích rõ ràng trong câu hỏi đã thay đổi đáng kể. Quan điểm của tôi vẫn đứng vững; * nói chung * chuyển trường sang lớp khác không phải lúc nào cũng có thể. –

Các vấn đề liên quan