天天看點

Effective C++: Item 38 -- Model “has-a” or “is-implemented-in-terms- of” through compositionDefinitionComposition means “has-a” relationshipComposition means “is-implemented-in-terms- of” relationshipThings to Remember

注: 此為英文資料整理,如需翻譯請私信或留評論

Definition

Composition is the relationship between types that arises when objects of one type contain objects of another type. Composition is also known as layering, containment, aggrega- tion, and embedding.

class Flight {
public:
...
private:
	int id;
	Model model;
	Factory factory;
}
           

Composition means “has-a” relationship

Application Domain: objects in your programs correspond to things in the world you are modeling, e.g., people, vehicles, video frames, etc.

When objects occurred between objects in Application Domain, it express a “has-a” relationship. The Flight class above is an example of “has-a” relationship

Composition means “is-implemented-in-terms- of” relationship

Implementation Domain: objects are purely implementation artifacts, e.g., buffers, mutexes, search trees, etc

When objects occurred between objects in Implementation Domain, it express a “is-implemented-in-terms- of” relationship.

Example: Implement set in terms of list.

Set is implemented in std as a balanced search tree. This design is reasonable when speed is the primary factor of consideration but it is not a good design when we consider space as a more important factor. We can reimplement set by list, however, set is not a list since list allow duplicate item but set doesn’t. Thus, we can implement set in terms of list.

template<class T> 
class Set {
public:
	bool member(const T& item) const;
	void insert(const T& item); void remove(const T& item);
	std::size_t size() const;
private:
	std::list<T> rep;
};
           

Set’s member functions can lean heavily on functionality already offered by list.

template<typename T>
bool Set<T>::member(const T& item) const {
	return std::find(rep.begin(), rep.end(), item) != rep.end(); 
}

template<typename T>
void Set<T>::insert(const T& item) {
	if (!member(item)) rep.push_back(item); 
}

template<typename T>
void Set<T>::remove(const T& item) {
	typename std::list<T>::iterator it = std::find(rep.begin(), rep.end(), item);
	if (it != rep.end()) rep.erase(it); 
}

template<typename T> 
std::size_t Set<T>::size() const {
	return rep.size(); 
}
           

Things to Remember

  • Composition has meanings completely different from that of public inheritance.
  • In the application domain, composition means has-a. In the imple- mentation domain, it means is-implemented-in-terms-of.