2015-06-20 20 views
7

Tôi đang tạo một ứng dụng có chứa một lớp mà tôi đang viết là Người. Một trong các trường của Person là 'aliases' là một số ArrayList<String>. Cuối cùng, các bí danh sẽ được hiển thị cho người dùng theo logic sau: Nếu Người có bí danh thì họ sẽ được hiển thị là [Finch, Wren, Admin, etc...], nếu không UNKNOWN sẽ được hiển thị. Cho đến nay tôi đã cố gắng thực hiện điều này theo một trong ba cách sau:Cách xử lý giá trị mặc định của ArrayList

  1. Person chứa các phương pháp getAliases() mà chỉ đơn giản trả về một bản sao của ArrayList như vậy. Người gọi sẽ kiểm tra một mảng trống để thực hiện hành vi mong muốn.

  2. Person chứa các phương pháp aliasesToString() mà có thể được gọi để tạo ra chuỗi mong muốn.

  3. Thay vì sử dụng ArrayList<String>, bí danh là triển khai DefaultableArrayList<T>. Lớp này mở rộng ArrayList và giữ một giá trị mặc định với kiểu T. Phương thức toString() được ghi đè để tạo chuỗi mong muốn. Ứng dụng gọi some_person.getAliases().toString() để tạo ra hành vi mong muốn.

Dưới đây là thực hiện của tôi lựa chọn 3:

public class DefaultableArrayList<T> extends ArrayList<T> { 

    private static final long serialVersionUID = -6735356930885363889L; // Auto-generated 
    private final T defaultElement; 


    public DefaultableArrayList(T defaultElement) { 
     super(); 
     this.defaultElement = defaultElement; 
    } 


    public DefaultableArrayList(Collection<? extends T> c, T defaultElement) { 
     super(c); 
     this.defaultElement = defaultElement; 
    } 


    public DefaultableArrayList(int initialCapacity, T defaultElement) { 
     super(initialCapacity); 
     this.defaultElement = defaultElement; 
    } 


    public T getDefaultElement() { 
     return defaultElement; 
    } 


    @Override 
    public String toString() { 
     if (!isEmpty()) { 
      return super.toString(); 

     } else { 
      return defaultElement.toString(); 
     } 
    } 
} 

gì tôi quan tâm về các lựa chọn 2 và 3 là tôi có thể thêm phức tạp không cần thiết trong khi vi phạm nguyên tắc OOP. Người nên thực sự quan tâm đến những gì sẽ xảy ra nếu không có bí danh và có ý nghĩa đối với các bí danh để xác định cách nó được triển khai cuối cùng trong ứng dụng không? Tôi nghĩ rằng tôi nên để người gọi xử lý trường hợp trống. Tôi nên chọn tuỳ chọn nào phù hợp nhất với hướng dẫn thiết kế OOP tiêu chuẩn? Hoặc là có một lựa chọn thứ tư mà tôi đã không xem xét?

Trả lời

6

Tùy chọn đầu tiên là tùy chọn phù hợp. Mô hình không nên quan tâm đến cách nó được hiển thị.

Bạn sẽ không đại diện cho người và/aliases mình theo cùng một cách trong một ứng dụng phong phú, một ứng dụng web hoặc một ứng dụng console.

Ngay cả trong một ứng dụng nào đó, bạn sẽ có thể đại diện cho cùng một mô hình theo những cách khác nhau.

Nếu bạn quốc tế hóa đơn của bạn, bạn sẽ phải thay đổi "UNKNOWN" để cái gì khác.

Vì vậy, chỉ cần trả lại danh sách như là (hoặc một vew unmodifiable danh sách), và để cho các thỏa thuận lớp trình bày với logic trình bày. BTW, toString() là một trợ giúp gỡ lỗi nhiều hơn một phương pháp chức năng được sử dụng để đại diện cho một đối tượng trong một ứng dụng.

2

Hãy đi bộ qua các tùy chọn của bạn:

Person chứa getAliases() phương pháp mà chỉ đơn giản trả về ArrayList như vậy. Người gọi sẽ kiểm tra một mảng trống để thực hiện hành vi mong muốn .

Mã người gọi sẽ trông như thế nào?

if (!person.getAliases().isEmpty()) { //Print aliases } 

Điều này có vẻ hơi xấu và không đọc được.Nếu bạn muốn đi với tùy chọn này, ít nhất bạn có thể làm là thêm một phương pháp hasAliases trong Person trong đó chủ yếu thực hiện việc kiểm tra cho bạn và làm cho mã khách hàng dễ đọc hơn:

if (person.hasAliases()) { //Print aliases } 

Đó là rất nhiều bụi và nhiều hơn nữa mã có thể đọc được.

Người chứa bí danh phương thứcToString() có thể được gọi để tạo chuỗi mong muốn.

Mặc dù Person là tự đủ không phải là xấu. Tất cả những gì các mã khách hàng phải làm là gọi person.aliasesToString() chứ không phải thực hiện:

if (person.hasAliases()) { 
    List<String> aliases = person.getAliases(); 
    StringBuilder aliaseString = new StringBuilder(""); 
    for (String alias : aliases) { 
     aliasString.append(aliases); 
    } 
} 

Thay vì sử dụng ArrayList, bí danh là một thực hiện DefaultableArrayList

Đó là một quá mức cần thiết cho một nhiệm vụ đơn giản như vậy.

Bạn tiếp cận với phương pháp nào? Nó phụ thuộc vào yêu cầu tổng thể của bạn. Nếu bạn có các khách hàng khác nhau/UI muốn làm những việc khác với bí danh, tùy chọn 1 sẽ là tốt nhất. Nếu bạn có một khách hàng duy nhất luôn muốn in các bí danh theo một cách nhất định, tùy chọn 2 sẽ là lựa chọn tốt hơn.

2

Tôi tìm thấy cách đơn giản nhất thường là phong cách tốt. Đó là, các mã xấu hơn có được khi làm một cái gì đó đơn giản thường có nghĩa là phong cách là đi lạc lối. Do đó, Option 1 trông giống như một cách chắc chắn để thực hiện điều này. Sử dụng getAliases() để trả lại hoặc in trường là khá chuẩn. Ngoài ra, bạn có thể thực hiện kiểm tra cho một mảng trống và trả về hoặc in UNKNOWN trong trường hợp đó. Nếu không, và ArrayList toString() sẽ xử lý nội dung.

2

Tùy chọn 3 là quá mức cần thiết. Tôi sẽ không mở rộng ArrayList cho một giá trị gia tăng nhỏ như vậy.

Chọn giữa tùy chọn 1 và tùy chọn 2 tùy thuộc vào việc có sử dụng dự kiến ​​nào khác cho List được trả về bởi getAliases() ngoài việc hiển thị biểu diễn chuỗi của nó hay không.

Nhược điểm duy nhất tôi thấy với phương thức aliasesToString(), là nó giả định rằng tất cả người dùng của lớp Người sẽ hiển thị bí danh theo cùng một cách.

Nếu bạn sử dụng phương thức getAliases(), tôi muốn phương thức đó trả lại bản sao của Danh sách đó hoặc đại diện mảng của Danh sách đó. Lý do cho điều đó là bạn ngăn chặn người dùng lớp Person của bạn khỏi việc đột biến cá thể Person bằng cách thay đổi List được trả về bởi getAliases().

+2

Tôi muốn quay lại chế độ xem không thể thay đổi: 'Collections.unmodifiableList (bí danh)'. –

+0

@JBNizet 'Collections.unmodifiableList (bí danh)' là một lựa chọn tốt. Nó bảo vệ thành viên ban đầu của cá thể khỏi bị sửa đổi và làm cho nó rõ ràng với người gọi phương thức mà họ không thể thay đổi cá thể Person bằng cách thay đổi danh sách các bí danh. – Eran

+0

Có tất nhiên, xin lỗi tôi không có ý ám chỉ tôi sẽ trả lại một tài liệu tham khảo trực tiếp. Đó là một sự giám sát. – Helios

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