2013-02-25 36 views
6

Tôi hiện đang làm việc trên một codebase, nơi có một vài lớp biến, giống như các đường dẫn cơ sở dữ liệu, được biểu diễn đơn giản dưới dạng Strings. Hầu hết các thao tác trên các kiểu (không phải) này được định nghĩa trong một lớp tiện ích.Làm thế nào để refactor "stringly-typed" code?

Tôi đã tạo một lớp mới để biểu diễn một cơ sở dữ liệu, với các hoạt động được định nghĩa là các phương thức thể hiện, theo kiểu OOP truyền thống. Tuy nhiên, nó khá mất thời gian để đi qua các codebase lớn và tái cấu trúc nó để sử dụng các kiểu mới. Có ai có lời khuyên nào về cách làm điều này một cách nhanh chóng và hiệu quả không?

+1

không lưu trữ đường dẫn cơ sở dữ liệu trong các biến hoặc tạo ra một lớp học để đại diện cho một databasae với hoạt động được xác định trong phương pháp, âm thanh tốt. – NimChimpsky

Trả lời

1

Đường dẫn cơ sở dữ liệu giống như chúng phải là Chuỗi với tôi. Điều gì khác có ý nghĩa? Và chúng nên được bên ngoài, trong tệp cấu hình hoặc cơ sở dữ liệu. Đó là ít nhất của các vấn đề của bạn.

Tính kiên trì đã nhiều lần hơn (ví dụ: Hibernate, Spring JDBC, iBatis, v.v.) mà tôi tự hỏi làm thế nào bạn có thể cải thiện chúng. Nếu bạn phải đi đến những rắc rối của refactoring - và bạn phải - Tôi khuyên bạn nên sử dụng bất cứ điều gì khác với những gì bạn đã làm.

Nếu bạn phải viết điều gì đó, Google cho "chung DAO". Bạn sẽ nhận được những thứ như thế này:

http://www.ibm.com/developerworks/java/library/j-genericdao/index.html

Nếu công việc của bạn không khuôn mẫu sau khi một cái gì đó như thế, vứt nó đi và lại nghĩ rằng mọi thứ.

+0

Cách thẳng để sử dụng ngủ đông, mùa xuân, v.v. có thể không phải là tốt nhất, vì vậy có thể có lý do hợp lệ cho một bước giữa dựa trên mã riêng. Bản thân tôi đã thấy điều này một vài lần. Dạy ngủ đông và mùa xuân cũng rất nhiều nỗ lực. – SpaceTrucker

+0

Tôi đồng ý với Hibernate - Tôi sẽ không giới thiệu nó cho bất kỳ ai. Nhưng tôi không thể không đồng ý nhiều hơn với Spring JDBC. Nó chết đơn giản và được thiết kế tốt. Bạn có thể sử dụng các phần của Spring mà không cần phải nắm vững tất cả. – duffymo

3

Di chuyển lớp tiện ích để sử dụng lớp học mới của bạn. Sau đó, các phương thức lớp tiện ích chỉ nên chứa hai câu lệnh. Một để tạo lớp của bạn và lớp kia đang gọi lớp của bạn. Sau đó, bạn có thể nội tuyến các phương thức lớp tiện ích do đó loại bỏ sự cần thiết cho nó.

Khi bạn kết thúc việc đó, bạn cần tìm cách không khởi tạo lại lớp mới của mình. Điều này nên được thực hiện bằng cách tái cấu trúc biến cục bộ thành một trường thể hiện được khởi tạo vào thời gian xây dựng.

0

Tôi thường cố gắng cách ly các chuỗi tại giới hạn ranh giới ứng dụng/quy trình, chẳng hạn như khi chúng được lấy từ cơ sở dữ liệu hoặc nhận được thông qua thao tác trên web.

Tại ranh giới ứng dụng/quy trình đó thường là nơi lý tưởng để ánh xạ/chuyển đổi/deserialize các chuỗi thành mô hình đối tượng thích hợp hơn, được hỗ trợ bởi bất kỳ ngôn ngữ nào bạn đang sử dụng.

Tương tự, mô hình đối tượng có thể được ánh xạ/chuyển đổi/tuần tự trở lại thành dạng chuỗi khi nó thoát khỏi ranh giới ứng dụng/quy trình của bạn.

Điều đáng chú ý là việc nhập chuỗi này có thể hơi phức tạp. Tôi thường thấy xml xâm nhập vào các lớp ứng dụng và miền. Một ví dụ tương tự từ không gian .NET sẽ thất bại trong việc ánh xạ ADO.NET DataTables (với các tên cột chuỗi của chúng và các giá trị trường chưa được nhập) vào các lớp/đối tượng khá nhiều ngay khi chúng được nhận. Tôi không có nghi ngờ rằng có nhiều tương đương tương tự trong thế giới Java. Stringly Typing không chỉ giới hạn ở các giá trị ngày tháng, khi trò đùa diễn ra.

1

Một kỹ thuật tôi đã sử dụng trong C# (và chỉ được chuyển đến Java - xin lỗi nếu tôi đã mắc lỗi, tôi mới sử dụng Java) là tạo các lớp StringlyTyped, ví dụ:một lớp cơ sở

public abstract class StringlyTyped { 
    private String value; 

    public StringlyTyped (String value){ 

     if (value == null){ 
      throw new IllegalArgumentException("value must not be null"); 
     } 
     this.value = value; 
    } 

    public String getValue() { return value; } 

    @Override 
    public boolean equals(Object other){ 
     if (other == this) { 
      return true; 
     } 

     if (other == null || !this.getClass().equals(other.getClass())){ 
      return false; 
     } 

     StringlyTyped o = (StringlyTyped)other; 
     return o.getValue().equals(this.getValue()); 
    } 

    @Override 
    public int hashCode(){ return this.getValue().hashCode(); } 

    @Override 
    public String toString() { return this.getValue(); } 
} 

Sau đó, có nguồn gốc lớp

public class ProviderName extends StringlyTyped { 

    public ProviderName(String value) { 
     super(value); 
    } 
} 

Và sử dụng

public void Foo(ProviderName provider) { 
} 

Nó có ý nghĩa khi bạn có phương pháp với nhiều parametrers String, ví dụ bạn có thể tránh

public void Foo(String username, String password, String db, String table, String constraint) 

và thay vào đó có mã số đó là mạnh mẽ gõ như thế này:

public void Foo(UserName username, Password password, DatabasePath db, TableName table...) 

vv ...

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