前言
在面向對象中,類之間的關系有六種,分別是:
- 關聯關系(Association)
- 泛化關系(Generalization)
- 依賴(Dependency)
- 聚合(Aggregation)
- 組合(Composite)
類與類之間關系
關聯(Association)
兩個相對獨立的對象,當一個對象的實例與另一個對象的實例存在固定關系時,這兩個對象之間就存在關聯關系,關聯體現的是一種強關聯關系,關聯關系形式有四種:單向關聯、雙向關聯、自身關聯和多維關聯。
單向關聯
場景:訂單和商品,訂單中包含商品,但是商品並不知道訂單的存在。
UML類圖:
代碼體現:
C#
public class Order
{
public List<Product> products;
public Order()
{
products = new List<Product>();
}
public void AddProduct(Product product)
{
products.Add(product);
}
public void Print()
{
foreach (var product in products)
{
Console.WriteLine(product.Name);
}
}
}
public class Product
{
public string Name { get; set; }
}
JavaScript
var Order = function () {
var products = [];
this.addProduct = function (product) {
products.push(product);
};
this.Print = function () {
for (var i = 0; i < products.length; i++) {
console.log(products[i].Name);
}
}
};
var Product = function (name) {
this.Name = name;
}
雙向關聯
場景:訂單和客戶,訂單屬於客戶,客戶擁有一些訂單
UML類圖: 
代碼體現:
C#
public class Order
{
public User GetUserByOrderId(string orderId)
{
return new User();
}
}
public class User
{
public List<Order> GetOrders()
{
return new List<Order>();
}
}
JavaScript
var User = function (name) {
this.Name = name;
this.getOrder = function () {
console.log("getOrder");
};
};
var Order = function () {
this.getUserByOrderId = function (id) {
console.log("getUserByOrderId:" + id);
};
}
多維關聯
多個對象之間存在聯系
場景:公司雇佣員工,同時公司需要字符工資給員工
依賴(Dependency)
類A要完成某個功能必須引用類B,則A和B存在依賴關系,依賴關系是弱關聯關系。
場景:司機和汽車
UML類圖: 
代碼體現:
public class Driver
{
public void Drive(Car car)
{
car.Run();
}
}
public class Car
{
public void Run()
{
Console.WriteLine("跑起來了");
}
}
JavaScript
var Driver = function () {
this.dirve = function (car) {
if (car instanceof Car) {
car.run();
} else {
throw new Error("參數異常,必須是Car類型");
}
}
};
var Car = function () {
this.run = function () {
console.log("跑起來了");
}
}
泛化(Generalization)
泛化就是類與類的的繼承關系,類與接口的實現關系。
場景:狗是一個動物;鳥會飛
UML類圖: 
代碼體現:
C#
public abstract class Animal
{
}
public class Dog
{
}
JavaScript
function Animal() { }
function Dog() { }
Dog.prototype = new Animal();
Dog.prototype.constructor = Dog;
var dog = new Dog();
console.log(dog.constructor);
console.log(dog instanceof Dog);
聚合(Aggregation)
當對象A被加入到對象B中,稱為對象B的一部分時,對象A和B就存在聚合關系。聚合關系是關聯關系的一種,是較強的關聯關系,強調的是整體與部分之間的關系。
場景:大雁與雁群
UML類圖: 
代碼體現
C#
public class GooseGroup
{
public Goose goose;
public GooseGroup(Goose g)
{
goose = g;
}
}
public class Goose
{
}
JavaScript
var Goose = function() {
};
var GooseGroup = function(goose) {
var _goose = goose;
console.log(_goose);
};
組合(Composition)
對象A包含對象B,對象B離開對象A就沒有存在的意義,是一種更強的關聯關系。
場景:大雁和翅膀
UML類圖: 
代碼體現
C#
public class Goose
{
public Wing wing;
public Goose()
{
wing = new Wing();
}
}
public class Wing
{
}
JavaScript
var Goose = function() {
var wing = new Wing();
};
var Wing = function() {};
區別
關聯和依賴區別:
- 從代碼的角度看,依賴關系中依賴是作為方法的參數或返回值,或者方法的變量形式體現的;關聯關系則是作為一個類的屬性體現的,相比依賴,關聯是更加固定,更為持久的持有的關系。
- 從生命周期來看,依賴關系則是隨着類的方法被調用時而產生,伴隨着方法的結束而結束;關聯關系則是當類實例化的時候即產生,當類的銷毀時而結束,相比依賴,關聯的生命周期更長。
聚合和組合區別:
- 構造函數不同,聚合類的構造函數參數是另一個類的實例;組合類的構造函數包含另一個類的實例化。
- 信息的封裝性不同,聚合關系中,GooseGroup類和Goose類是獨立的,客戶端都可以訪問到;組合關系中,客戶端只能訪問到Goose類,Wing類則訪問不到,因為它被封裝在Goose類中。


