2012-02-20 30 views
7

Tôi muốn thêm một tập hợp các đối tượng vào một arrayList, chỉ khi thuộc tính cụ thể không phải là rỗng.Tôi có nên mở rộng ArrayList để thêm các thuộc tính không phải là null không?

Tôi đang nghĩ đến việc mở rộng ArrayList và triển khai kiểm tra bên trong lớp con.

Một cách khác là kiểm tra thuộc tính trước khi đặt nó vào Danh sách, nhưng điều đó có nghĩa là tôi sẽ phải phân tán nếu kiểm tra mọi nơi nếu tôi cần thêm đối tượng vào danh sách theo dựa trên logic .

Tôi muốn biết suy nghĩ của bạn về nó ... trên một ý nghĩ thứ hai là nó là một overkill?

Trả lời

20

mẫu Decorator

tôi sẽ thực sự khuyên bạn nên gói ArrayList sử dụng cũng như các tài liệu Decorator mẫu. Bạn chỉ cần quấn bạn ArrayList với nhau thực hiện List rằng các đại biểu hầu hết các phương pháp nhưng thêm logic xác nhận:

public class ValidatingListDecorator extends AbstractList<MyBusinessObject> 
{ 

    private final List<MyBusinessObject> target; 

    public ValidatingListDecorator(List<MyBusinessObject> target) { 
     this.target = target; 
    } 

    @Override 
    public MyBusinessObject set(int index, MyBusinessObject element) 
    { 
     validate(element); 
     return target.set(index, element); 
    } 

    @Override 
    public boolean add(MyBusinessObject o) 
    { 
     validate(o); 
     return target.add(o); 
    } 

    //few more to implement 

} 

Ưu điểm:

  • Bạn vẫn có thể truy cập danh sách nguyên liệu mà không cần xác nhận nếu bạn muốn (nhưng bạn có thể hạn chế điều này)
  • Dễ dàng hơn để ngăn xếp các xác thực khác nhau, bật và tắt chúng một cách có chọn lọc.
  • Khuyến khích composition over inheritance như ghi nhận của @helios
  • Cải thiện testability
  • Không buộc bạn đến một List thực hiện cụ thể, bạn có thể thêm xác nhận để LinkedList hoặc Hibernate -backed danh sách dai dẳng. Bạn thậm chí có thể nghĩ về trang trí chung của Collection để xác thực bất kỳ bộ sưu tập nào.

Thực hiện ghi nhận

Mặc dù việc thực hiện nhớ có khá nhiều phương pháp bạn phải nhớ về trong khi trọng: (?) add(), addAll(), set(), subList() vv

Ngoài ra bạn đối tượng phải không thay đổi, nếu không người dùng có thể thêm/đặt đối tượng hợp lệ và sửa đổi nó sau đó để vi phạm hợp đồng.

thiết kế OO Tốt

cuối cùng tôi đã viết:

validate(element) 

nhưng xem xét:

element.validate() 

mà là một thiết kế tốt hơn.

kiểm chứng thực Stacking

Như đã đề cập trước nếu bạn muốn ngăn xếp kiểm chứng thực, xác nhận mỗi proprty/apsect trong một duy nhất, lớp riêng biệt, xem xét các thành ngữ sau:

public abstract class ValidatingListDecorator extends AbstractList<MyBusinessObject> 
{ 

    private final List<MyBusinessObject> target; 

    public ValidatingListDecorator(List<MyBusinessObject> target) { 
     this.target = target; 
    } 

    @Override 
    public MyBusinessObject set(int index, MyBusinessObject element) 
    { 
     validate(element); 
     return target.set(index, element); 
    } 

    protected abstract void validate(MyBusinessObject element); 

} 

... và vài hiện thực :

class FooValidatingDecorator extends ValidatingListDecorator { 

    public FooValidatingDecorator(List<MyBusinessObject> target) 
    { 
     super(target); 
    } 

    @Override 
    protected void validate(MyBusinessObject element) 
    { 
     //throw if "foo" not met 
    } 
} 

class BarValidatingDecorator extends ValidatingListDecorator { 

    public BarValidatingDecorator(List<MyBusinessObject> target) 
    { 
     super(target); 
    } 

    @Override 
    protected void validate(MyBusinessObject element) 
    { 
     //throw if "bar" not met 
    } 
} 

Muốn chỉ xác nhận foo?

List<MyBusinessObject> list = new FooValidatingDecorator(rawArrayList); 

Bạn muốn xác nhận cả hai foothanh?

List<MyBusinessObject> list = 
    new BarValidatingDecorator(new FooValidatingDecorator(rawArrayList)); 
+6

+1 cho thành phần thừa kế! – helios

+0

+1 Cảm ơn bạn đã trả lời chi tiết – Sudhakar

1

Nếu bạn muốn thực thi điều này, tôi không thấy lý do tại sao không (mặc dù bạn nên kiểm tra giá trị trả về của phương thức thêm bất cứ khi nào bạn thêm để đảm bảo rằng nó đã thành công).

Đây là một cách hay để loại bỏ logic dư thừa mà có thể hoặc có thể không bám sát trong các lần lặp phần mềm sau này.

+0

Tôi đồng ý với bạn, nhưng IMO có một sự cân nhắc khi mở rộng từ triển khai danh sách nhất định - không thể chuyển sang một chiến lược khác, ví dụ: thay thế ArrayList bằng LinkedList. Phái đoàn sẽ là một lựa chọn khác. – home

+0

@home Sắp xếp, thật dễ dàng để chuyển đổi thứ gì đó mở rộng danh sách mảng thành thứ gì đó mở rộng một cái gì đó khác miễn là giao diện chính xác giống hoặc hơi gần. –

+0

Một lần nữa, đã đồng ý. +1 – home

0

Chỉ có vấn đề là nếu bạn sử dụng lại mã này và bạn không nhớ mình đã overriden lớp ArrayList, hãy đảm bảo nhận xét kỹ lưỡng.

1

Tôi không nghĩ đây là một phương pháp hay. Thay vào đó, hãy xem xét viết Util-Method trong Util-Class để lấy hai tham số: Danh sách mảng và đối tượng bạn muốn thêm vào. Ở đó bạn có thể kiểm tra bất cứ điều gì bạn muốn và có thể tái sử dụng logic trên tất cả các mã của bạn.

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