“Collection Wrapper” pattern – is this common?

A different question of mine had to do with encapsulating member data structures inside classes. In order to understand this question better please read that question and look at the approach discussed.

One of the guys who answered that question said that the approach is good, but if I understood him correctly – he said that there should be a class existing just for the purpose of wrapping the collection, instead of an ordinary class offering a number of public methods just to access the member collection.

For example, instead of this:

class SomeClass{

    // downright exposing the concrete collection.        

    Things[] someCollection;

   // other stuff omitted

    Thing[] getCollection(){return someCollection;}

}

Or this:

class SomeClass{

    // encapsulating the collection, but inflating the class' public interface.

    Thing[] someCollection;

    // class functionality omitted.

    public Thing getThing(int index){
        return someCollection[index];
    }

    public int getSize(){
        return someCollection.length;
    }

    public void setThing(int index, Thing thing){
        someCollection[index] = thing;
    }

    public void removeThing(int index){
        someCollection[index] = null;
    }

}

We’ll have this:

// encapsulating the collection - in a different class, dedicated to this.

class SomeClass{
    CollectionWrapper someCollection;

    CollectionWrapper  getCollection(){return someCollection;}
}

class CollectionWrapper{

    Thing[] someCollection;

    public Thing getThing(int index){
        return someCollection[index];
    }

    public int getSize(){
        return someCollection.length;
    }

    public void setThing(int index, Thing thing){
        someCollection[index] = thing;
    }

    public void removeThing(int index){
        someCollection[index] = null;
    }

}

This way, the inner data structure in SomeClass can change without affecting client code, and without forcing SomeClass to offer a lot of public methods just to access the inner collection. CollectionWrapper does this instead.

E.g. if the collection changes from an array to a List, the internal implementation of CollectionWrapper changes, but client code stays the same.

Also, the CollectionWrapper can hide certain things from the client code – from example, it can disallow mutation to the collection by not having the methods setThing and removeThing.

This approach to decoupling client code from the concrete data structure seems IMHO pretty good.

Is this approach common? What are it’s downfalls? Is this used in practice?

14

You are implementing a restricted set of the Collection interface, without actually giving it something that you can work with.

E.g. if the collection changes from an array to a List, the internal
implementation of CollectionWrapper changes, but client code stays the same.

This is exactly what the Collection interface is intended to do. If you pass back a Collection, that is all the client can work from.

Also, the CollectionWrapper can hide certain things from the client code – from example, it can disallow mutation to the collection by not having the methods setThing and removeThing.

In Java, this is known as an Unmodifiable Collection, and the Collections utility has just such a method to convert a modifiable collection to an unmodifiable one.

By making the restricted wrapper you are also giving up things such as sort and iterator which come in very handy from time to time. This means code such as:

for(Thing t : someCollection) {
    ....
}

won’t work. Instead, the code would need to be:

for(int i = 0; i < someCollection.size(); i++) {
    Thing t = someCollection.get(i);
    ....
}

While that is perfectly acceptable code, it also means you are failing to take advantage of the language to allow the client to write code faster (programmer time is expensive).

The way you decouple the implementation is to use an interface, preferably one that already exists in the language framework so that other things that use that same interface can use your code without jumping through additional hoops.


Just a note:

What I’m trying to do, is not expose the collection – because I don’t want the client code to break when the collection changes say from a List to a Set. If I just allow the client code to do class.getCollection() it’ll break when the type of the collection changes. So the idea is to make a thin layer around it (“CollectionWrapper”), so when the type of collection changes, only the wrapper has to change, but not the code using the collection (i.e. using the wrapper). Is what I’m saying clear?

If the collection is only given as a Collection interface, it won’t break. However, I must point out that the public methods that you are presenting with this class, namely public Thing getThing(int index), public void setThing(int index, Thing thing), and public void removeThing(int index) would preclude the implementation from changing from a List to a Set, because Sets have no concept of indexes and these methods would need to change.

1

You’re describing the Encapsulated Collection pattern. I like this pattern a lot; it’s especially appropriate to domain-driven design.

The advantage you describe – being able to change the internal representation of the collection – is a good one. But I think the bigger advantage is restricting clients’ ability to modify or break the underlying collection.

For example, consider a “commenting” feature of a social network, with the requirement that you can’t delete comments after they’ve been posted. If you expose the List<Comment> as a property, it’s easy for clients of your class to call the list’s Remove method without realising they weren’t supposed to.

If, instead, you use a Comments class with a private List<Comment> and no Remove method, it’s now impossible to break the invariant.

You also end up with a richer domain model, which is better equipped to deal with new features. (A collection of domain objects is often a new domain concept that your model is missing.) Imagine that the requirement’s changed and now it’s possible to delete comments, but the deletion has to be recorded in an audit trail. It’s easy to implement this behaviour in a new Delete method on your Comments class – it would have been much more complicated to override the pre-existing Remove method on the List.

I think you are right.

I have developed several custom collections in diferent programming languages, and, sometimes, I applied the pattern. I also check that other developers also applied.

It seems that it depends on what the developer wants to achieve, sometimes, the collection is access directly, sometimes, using the pattern.

Visual controls with several items like “Treeview”, “Listview”, “Gridview” use a lot of this technique.

You said,

What I’m trying to do, is not expose the collection – because I don’t want the client code to break when the collection changes say from a List to a Set.

I have concerns about that requirement — whether perceived or real.

The abstractions represented by those standard containers are so distinct and different, I find it hard that you will be able to substitute one for another in your interface. If SomeClass provides an interface that is more appropriate for a Set, you have to honor that interface regardless of how you implement the Set. The same logic applies for List too. In that sense, you don’t have to expose ContainerWrapper or Container at all. They are implementation details of SomeClass. You could use pimpl pattern to completely hide the container.

Perhaps SomeClass is a container of objects with additional meaning.

For example, in a CAD program, an Assembly consists of sub-components that can be Parts or sub-Assemblies. However, that is not sufficient to capture the relationship between an Assembly and one of its sub-components. The location and orientation of the sub-component in the Assembly is the key piece of data that makes this particular container-contained relationship work. For this case, whether you store the collection of Pair<sub-component, transform> as a List or a Set is of very little importance in the interface of Assembly. You need to be able to query the Assembly for its sub-components and given a sub-component, you need to be able to query the Assembly for the transform of the sub-component in the Assembly.

Another example: A Canvas and its contained objects in a 2D painting program or an SVG program. Here again, the container-contained relationship has to be created using the 2D position of the contained objects plus a depth to
in order to arrange them in layers. Here also, you can use a Set or a List to hold the contained objects.

In conclusion, I am asking you to dig deeper to determine the kind of relationship SomeClass has with its contained objects. Is it a matter of simple containment or is there more to the relationship? If there is more to the relationship, how would you expose the relationship that is divorced from a List or a Set.

In both the examples I presented, a List makes more sense to me. I can’t say what makes more sense for SomeClass.

Trang chủ Giới thiệu Sinh nhật bé trai Sinh nhật bé gái Tổ chức sự kiện Biểu diễn giải trí Dịch vụ khác Trang trí tiệc cưới Tổ chức khai trương Tư vấn dịch vụ Thư viện ảnh Tin tức - sự kiện Liên hệ Chú hề sinh nhật Trang trí YEAR END PARTY công ty Trang trí tất niên cuối năm Trang trí tất niên xu hướng mới nhất Trang trí sinh nhật bé trai Hải Đăng Trang trí sinh nhật bé Khánh Vân Trang trí sinh nhật Bích Ngân Trang trí sinh nhật bé Thanh Trang Thuê ông già Noel phát quà Biểu diễn xiếc khỉ Xiếc quay đĩa Dịch vụ tổ chức sự kiện 5 sao Thông tin về chúng tôi Dịch vụ sinh nhật bé trai Dịch vụ sinh nhật bé gái Sự kiện trọn gói Các tiết mục giải trí Dịch vụ bổ trợ Tiệc cưới sang trọng Dịch vụ khai trương Tư vấn tổ chức sự kiện Hình ảnh sự kiện Cập nhật tin tức Liên hệ ngay Thuê chú hề chuyên nghiệp Tiệc tất niên cho công ty Trang trí tiệc cuối năm Tiệc tất niên độc đáo Sinh nhật bé Hải Đăng Sinh nhật đáng yêu bé Khánh Vân Sinh nhật sang trọng Bích Ngân Tiệc sinh nhật bé Thanh Trang Dịch vụ ông già Noel Xiếc thú vui nhộn Biểu diễn xiếc quay đĩa Dịch vụ tổ chức tiệc uy tín Khám phá dịch vụ của chúng tôi Tiệc sinh nhật cho bé trai Trang trí tiệc cho bé gái Gói sự kiện chuyên nghiệp Chương trình giải trí hấp dẫn Dịch vụ hỗ trợ sự kiện Trang trí tiệc cưới đẹp Khởi đầu thành công với khai trương Chuyên gia tư vấn sự kiện Xem ảnh các sự kiện đẹp Tin mới về sự kiện Kết nối với đội ngũ chuyên gia Chú hề vui nhộn cho tiệc sinh nhật Ý tưởng tiệc cuối năm Tất niên độc đáo Trang trí tiệc hiện đại Tổ chức sinh nhật cho Hải Đăng Sinh nhật độc quyền Khánh Vân Phong cách tiệc Bích Ngân Trang trí tiệc bé Thanh Trang Thuê dịch vụ ông già Noel chuyên nghiệp Xem xiếc khỉ đặc sắc Xiếc quay đĩa thú vị
Trang chủ Giới thiệu Sinh nhật bé trai Sinh nhật bé gái Tổ chức sự kiện Biểu diễn giải trí Dịch vụ khác Trang trí tiệc cưới Tổ chức khai trương Tư vấn dịch vụ Thư viện ảnh Tin tức - sự kiện Liên hệ Chú hề sinh nhật Trang trí YEAR END PARTY công ty Trang trí tất niên cuối năm Trang trí tất niên xu hướng mới nhất Trang trí sinh nhật bé trai Hải Đăng Trang trí sinh nhật bé Khánh Vân Trang trí sinh nhật Bích Ngân Trang trí sinh nhật bé Thanh Trang Thuê ông già Noel phát quà Biểu diễn xiếc khỉ Xiếc quay đĩa

“Collection Wrapper” pattern – is this common?

A different question of mine had to do with encapsulating member data structures inside classes. In order to understand this question better please read that question and look at the approach discussed.

One of the guys who answered that question said that the approach is good, but if I understood him correctly – he said that there should be a class existing just for the purpose of wrapping the collection, instead of an ordinary class offering a number of public methods just to access the member collection.

For example, instead of this:

class SomeClass{

    // downright exposing the concrete collection.        

    Things[] someCollection;

   // other stuff omitted

    Thing[] getCollection(){return someCollection;}

}

Or this:

class SomeClass{

    // encapsulating the collection, but inflating the class' public interface.

    Thing[] someCollection;

    // class functionality omitted.

    public Thing getThing(int index){
        return someCollection[index];
    }

    public int getSize(){
        return someCollection.length;
    }

    public void setThing(int index, Thing thing){
        someCollection[index] = thing;
    }

    public void removeThing(int index){
        someCollection[index] = null;
    }

}

We’ll have this:

// encapsulating the collection - in a different class, dedicated to this.

class SomeClass{
    CollectionWrapper someCollection;

    CollectionWrapper  getCollection(){return someCollection;}
}

class CollectionWrapper{

    Thing[] someCollection;

    public Thing getThing(int index){
        return someCollection[index];
    }

    public int getSize(){
        return someCollection.length;
    }

    public void setThing(int index, Thing thing){
        someCollection[index] = thing;
    }

    public void removeThing(int index){
        someCollection[index] = null;
    }

}

This way, the inner data structure in SomeClass can change without affecting client code, and without forcing SomeClass to offer a lot of public methods just to access the inner collection. CollectionWrapper does this instead.

E.g. if the collection changes from an array to a List, the internal implementation of CollectionWrapper changes, but client code stays the same.

Also, the CollectionWrapper can hide certain things from the client code – from example, it can disallow mutation to the collection by not having the methods setThing and removeThing.

This approach to decoupling client code from the concrete data structure seems IMHO pretty good.

Is this approach common? What are it’s downfalls? Is this used in practice?

14

You are implementing a restricted set of the Collection interface, without actually giving it something that you can work with.

E.g. if the collection changes from an array to a List, the internal
implementation of CollectionWrapper changes, but client code stays the same.

This is exactly what the Collection interface is intended to do. If you pass back a Collection, that is all the client can work from.

Also, the CollectionWrapper can hide certain things from the client code – from example, it can disallow mutation to the collection by not having the methods setThing and removeThing.

In Java, this is known as an Unmodifiable Collection, and the Collections utility has just such a method to convert a modifiable collection to an unmodifiable one.

By making the restricted wrapper you are also giving up things such as sort and iterator which come in very handy from time to time. This means code such as:

for(Thing t : someCollection) {
    ....
}

won’t work. Instead, the code would need to be:

for(int i = 0; i < someCollection.size(); i++) {
    Thing t = someCollection.get(i);
    ....
}

While that is perfectly acceptable code, it also means you are failing to take advantage of the language to allow the client to write code faster (programmer time is expensive).

The way you decouple the implementation is to use an interface, preferably one that already exists in the language framework so that other things that use that same interface can use your code without jumping through additional hoops.


Just a note:

What I’m trying to do, is not expose the collection – because I don’t want the client code to break when the collection changes say from a List to a Set. If I just allow the client code to do class.getCollection() it’ll break when the type of the collection changes. So the idea is to make a thin layer around it (“CollectionWrapper”), so when the type of collection changes, only the wrapper has to change, but not the code using the collection (i.e. using the wrapper). Is what I’m saying clear?

If the collection is only given as a Collection interface, it won’t break. However, I must point out that the public methods that you are presenting with this class, namely public Thing getThing(int index), public void setThing(int index, Thing thing), and public void removeThing(int index) would preclude the implementation from changing from a List to a Set, because Sets have no concept of indexes and these methods would need to change.

1

You’re describing the Encapsulated Collection pattern. I like this pattern a lot; it’s especially appropriate to domain-driven design.

The advantage you describe – being able to change the internal representation of the collection – is a good one. But I think the bigger advantage is restricting clients’ ability to modify or break the underlying collection.

For example, consider a “commenting” feature of a social network, with the requirement that you can’t delete comments after they’ve been posted. If you expose the List<Comment> as a property, it’s easy for clients of your class to call the list’s Remove method without realising they weren’t supposed to.

If, instead, you use a Comments class with a private List<Comment> and no Remove method, it’s now impossible to break the invariant.

You also end up with a richer domain model, which is better equipped to deal with new features. (A collection of domain objects is often a new domain concept that your model is missing.) Imagine that the requirement’s changed and now it’s possible to delete comments, but the deletion has to be recorded in an audit trail. It’s easy to implement this behaviour in a new Delete method on your Comments class – it would have been much more complicated to override the pre-existing Remove method on the List.

I think you are right.

I have developed several custom collections in diferent programming languages, and, sometimes, I applied the pattern. I also check that other developers also applied.

It seems that it depends on what the developer wants to achieve, sometimes, the collection is access directly, sometimes, using the pattern.

Visual controls with several items like “Treeview”, “Listview”, “Gridview” use a lot of this technique.

You said,

What I’m trying to do, is not expose the collection – because I don’t want the client code to break when the collection changes say from a List to a Set.

I have concerns about that requirement — whether perceived or real.

The abstractions represented by those standard containers are so distinct and different, I find it hard that you will be able to substitute one for another in your interface. If SomeClass provides an interface that is more appropriate for a Set, you have to honor that interface regardless of how you implement the Set. The same logic applies for List too. In that sense, you don’t have to expose ContainerWrapper or Container at all. They are implementation details of SomeClass. You could use pimpl pattern to completely hide the container.

Perhaps SomeClass is a container of objects with additional meaning.

For example, in a CAD program, an Assembly consists of sub-components that can be Parts or sub-Assemblies. However, that is not sufficient to capture the relationship between an Assembly and one of its sub-components. The location and orientation of the sub-component in the Assembly is the key piece of data that makes this particular container-contained relationship work. For this case, whether you store the collection of Pair<sub-component, transform> as a List or a Set is of very little importance in the interface of Assembly. You need to be able to query the Assembly for its sub-components and given a sub-component, you need to be able to query the Assembly for the transform of the sub-component in the Assembly.

Another example: A Canvas and its contained objects in a 2D painting program or an SVG program. Here again, the container-contained relationship has to be created using the 2D position of the contained objects plus a depth to
in order to arrange them in layers. Here also, you can use a Set or a List to hold the contained objects.

In conclusion, I am asking you to dig deeper to determine the kind of relationship SomeClass has with its contained objects. Is it a matter of simple containment or is there more to the relationship? If there is more to the relationship, how would you expose the relationship that is divorced from a List or a Set.

In both the examples I presented, a List makes more sense to me. I can’t say what makes more sense for SomeClass.

Trang chủ Giới thiệu Sinh nhật bé trai Sinh nhật bé gái Tổ chức sự kiện Biểu diễn giải trí Dịch vụ khác Trang trí tiệc cưới Tổ chức khai trương Tư vấn dịch vụ Thư viện ảnh Tin tức - sự kiện Liên hệ Chú hề sinh nhật Trang trí YEAR END PARTY công ty Trang trí tất niên cuối năm Trang trí tất niên xu hướng mới nhất Trang trí sinh nhật bé trai Hải Đăng Trang trí sinh nhật bé Khánh Vân Trang trí sinh nhật Bích Ngân Trang trí sinh nhật bé Thanh Trang Thuê ông già Noel phát quà Biểu diễn xiếc khỉ Xiếc quay đĩa Dịch vụ tổ chức sự kiện 5 sao Thông tin về chúng tôi Dịch vụ sinh nhật bé trai Dịch vụ sinh nhật bé gái Sự kiện trọn gói Các tiết mục giải trí Dịch vụ bổ trợ Tiệc cưới sang trọng Dịch vụ khai trương Tư vấn tổ chức sự kiện Hình ảnh sự kiện Cập nhật tin tức Liên hệ ngay Thuê chú hề chuyên nghiệp Tiệc tất niên cho công ty Trang trí tiệc cuối năm Tiệc tất niên độc đáo Sinh nhật bé Hải Đăng Sinh nhật đáng yêu bé Khánh Vân Sinh nhật sang trọng Bích Ngân Tiệc sinh nhật bé Thanh Trang Dịch vụ ông già Noel Xiếc thú vui nhộn Biểu diễn xiếc quay đĩa Dịch vụ tổ chức tiệc uy tín Khám phá dịch vụ của chúng tôi Tiệc sinh nhật cho bé trai Trang trí tiệc cho bé gái Gói sự kiện chuyên nghiệp Chương trình giải trí hấp dẫn Dịch vụ hỗ trợ sự kiện Trang trí tiệc cưới đẹp Khởi đầu thành công với khai trương Chuyên gia tư vấn sự kiện Xem ảnh các sự kiện đẹp Tin mới về sự kiện Kết nối với đội ngũ chuyên gia Chú hề vui nhộn cho tiệc sinh nhật Ý tưởng tiệc cuối năm Tất niên độc đáo Trang trí tiệc hiện đại Tổ chức sinh nhật cho Hải Đăng Sinh nhật độc quyền Khánh Vân Phong cách tiệc Bích Ngân Trang trí tiệc bé Thanh Trang Thuê dịch vụ ông già Noel chuyên nghiệp Xem xiếc khỉ đặc sắc Xiếc quay đĩa thú vị
Trang chủ Giới thiệu Sinh nhật bé trai Sinh nhật bé gái Tổ chức sự kiện Biểu diễn giải trí Dịch vụ khác Trang trí tiệc cưới Tổ chức khai trương Tư vấn dịch vụ Thư viện ảnh Tin tức - sự kiện Liên hệ Chú hề sinh nhật Trang trí YEAR END PARTY công ty Trang trí tất niên cuối năm Trang trí tất niên xu hướng mới nhất Trang trí sinh nhật bé trai Hải Đăng Trang trí sinh nhật bé Khánh Vân Trang trí sinh nhật Bích Ngân Trang trí sinh nhật bé Thanh Trang Thuê ông già Noel phát quà Biểu diễn xiếc khỉ Xiếc quay đĩa
Thiết kế website Thiết kế website Thiết kế website Cách kháng tài khoản quảng cáo Mua bán Fanpage Facebook Dịch vụ SEO Tổ chức sinh nhật