Miyrasxorlıq boyınsha kompoziciya

Obyektke baǵdarlanǵan programmalastırıwda (OBP) **miyrasxorlıq boyınsha kompoziciya** (yamasa **kompoziciyalıq qayta paydalanıw principi**) ‒ klasslardıń tiykarǵı yamasa ata-analıq klasstan miyras alıwdıń ornına, polimorflıq minez-qulıq hám kodtı qayta paydalanıwdı olardıń kompoziciyası arqalı (qálegen funkcionallıqtı ámelge asıratuǵın basqa klasslardıń mısalların óz ishine alıw arqalı) jaqlawı kerek degen princip. Ideal jaǵdayda barlıq qayta paydalanıw bar bolǵan komponentlerdi jıynaw arqalı ámelge asırılıwı múmkin, biraq ámelde jańaların jaratıw ushın kóbinese miyras alıw kerek boladı. Sonlıqtan, miyras alıw hám obekt kompoziciyası ádette birge isleydi, bul "Dizayn úlgileri" (1994) kitabında talqılanǵan.

## Tiykarlar
Miyrasxorlıq boyınsha kompoziciyanıń ámelge asırılıwı ádette sistemada bolıwı kerek bolǵan minez-qulıqlardı kórsetetuǵın hár qıylı interfeyslerdi jaratıwdan baslanadı. Interfeysler polimorflıq minez-qulıqtı jeńillestire aladı. Anıqlanǵan interfeyslerdi ámelge asıratuǵın klasslar dúziledi hám kerek bolǵanda biznes taraw klasslarına qosıladı. Solay etip, sistema minez-qulıqları miyras alıwsız ámelge asırıladı.

Haqıyqatında, biznes taraw klassları hesh qanday miyras alıwsız tiykarǵı klasslar bolıwı múmkin. Sistema minez-qulıqlarınıń alternativ ámelge asırılıwı qálegen minez-qulıq interfeysin ámelge asıratuǵın basqa klasstı beriw arqalı orınlanadı. Interfeyske silteme saqlaytuǵın klass interfeystiń ámelge asırılıwların qollay aladı - bul tańlaw orınlanıw waqtına shekem keyinge qaldırılıwı múmkin.

## Mısal

### Miyras alıw
C++ tilindegi mısal tómendegishe:
```cpp
class Obekt
{
public:
 virtual void jańala() {
 // hesh nárse islemeydi
 }

 virtual void sızıw() {
 // hesh nárse islemeydi
 }

 virtual void soqlıǵısıw(Obekt obektler[]) {
 // hesh nárse islemeydi
 }
};

class Kórinetuǵın : public Obekt
{
 Model* model;

public:
 virtual void sızıw() override {
 // usı obekttiń ornında modeldi sızıw ushın kod
 }
};

class Qattı : public Obekt
{
public:
 virtual void soqlıǵısıw(Obekt obektler[]) override {
 // basqa obektler menen soqlıǵısıwdı tekseriw hám oǵan juwap beriw ushın kod
 }
};

class Jıljıwshı : public Obekt
{
public:
 virtual void jańala() override {
 // usı obekttiń ornın jańalaw ushın kod
 }
};
```
Keyin, mınaday konkret klasslardıń bar ekenin kóz aldıńızǵa keltiriń:

* class Oyınshı - ol Qattı, Jıljıwshı hám Kórinetuǵın
* class Bult - ol Jıljıwshı hám Kórinetuǵın, biraq Qattı emes
* class Imarat - ol Qattı hám Kórinetuǵın, biraq Jıljıwshı emes
* class Duzaq - ol Qattı, biraq Kórinetuǵın da, Jıljıwshı da emes

Esińizde bolsın, kóp miyrasxorlıq dıqqat penen ámelge asırılmasa qáwipli bolıwı múmkin, sebebi ol romb máselesine alıp keliwi múmkin. Bunıń bir sheshimi - hárbir kerekli kombinaciya ushın KórinetuǵınHámQattı, KórinetuǵınHámJıljıwshı, KórinetuǵınHámQattıHámJıljıwshı hám t.b. sıyaqlı klasslar jaratıw bolıp tabıladı; biraq, bul kóp muǵdarda qaytalanatuǵın kodqa alıp keledi. C++ kóp miyrasxorlıqtıń romb máselesin sheshiw ushın virtual miyrasxorlıqtı qollanadı.

### Kompoziciya hám interfeysler
Bul bólimdegi C++ mısalları kod qayta paydalanıw hám polimorfizmge erisiw ushın kompoziciya hám interfeyslerdi qollanıw principin kórsetedi. C++ tilinde interfeyslerdi járiyalaw ushın arnawlı gilt sóz bolmaǵanlıqtan, tómendegi C++ mısalı taza abstrakt tiykarǵı klasstan miyras alıwdı qollanadı. Kópshilik maqsetler ushın, bul funkcional jaqtan Java: 87  hám C#.: 144  sıyaqlı basqa tillerde berilgen interfeyslerge uqsas.

VisibilityDelegate dep atalatuǵın abstrakt klass kirgiziń, onıń NotVisible hám Visible degen subklassları bar, ol obektti sızıw usılın támiyinleydi:
```cpp
class KórinisligiWákil
{
public:
 virtual void sızıw() = 0;
};

class Kórinbeytuǵın : public KórinisligiWákil
{
public:
 virtual void sızıw() override {
 // hesh nárse islemeydi
 }
};

class Kórinetuǵın : public KórinisligiWákil
{
public:
 virtual void sızıw() override {
 // bul obekttiń poziciyasında modeldi sızıw ushın kod
 }
};
```
JańalawWákil dep atalatuǵın abstrakt klasstı kirgiziń, onıń Qozǵalmaytuǵın hám Qozǵalatuǵın degen subklassları bar, bul obektti jıljıtıw usılın támiyinleydi:
```cpp
class JańalawWákil
{
public:
 virtual void jańalaw() = 0;
};

class Qozǵalmaytuǵın : public JańalawWákil
{
public:
 virtual void jańalaw() override {
 // hesh nárse islemeydi
 }
};

class Qozǵalatuǵın : public JańalawWákil
{
public:
 virtual void jańalaw() override {
 // bul obekttiń poziciyasın jańalaw ushın kod
 }
};
```
SoqlıǵısıwWákil dep atalatuǵın abstrakt klasstı kirgiziń, onıń Qattı emes hám Qattı degen subklassları bar, bul obekt penen soqlıǵısıw usılın támiyinleydi:
```cpp
class SoqlıǵısıwWákil
{
public:
 virtual void soqlıǵısıw(Obekt obektler[]) = 0;
};

class QattıEmes : public SoqlıǵısıwWákil
{
public:
 virtual void soqlıǵısıw(Obekt obektler[]) override {
 // hesh nárse islemeydi
 }
};

class Qattı : public SoqlıǵısıwWákil
{
public:
 virtual void soqlıǵısıw(Obekt obektler[]) override {
 // basqa obektler menen soqlıǵısıwdı tekseriw hám oǵan juwap beriw ushın kod
 }
};
```
Aqırında, Obekt dep atalatuǵın klasstı kirgiziń, onıń kóriniwin basqarıw ushın (KóriniwWákil qollanıp), qozǵalıwshılıǵın basqarıw ushın (JańalawWákil qollanıp) hám qattılıǵın basqarıw ushın (SoqlıǵısıwWákil qollanıp) aǵzaları bar. Bul klassta óz aǵzalarına tapsırma beretuǵın metodlar bar, mısalı, jańalaw() ápiwayı túrde JańalawWákil ústindegi metodtı shaqıradı:
```cpp
class Obekt
{
 KóriniwWákil* _k;
 JańalawWákil* _j;
 SoqlıǵısıwWákil* _s;

public:
 Obekt(KóriniwWákil* k, JańalawWákil* j, SoqlıǵısıwWákil* s)
 : _k(k)
 , _j(j)
 , _s(s)
 {}

 void jańalaw() {
 _j->jańalaw();
 }

 void sızıw() {
 _k->sızıw();
 }

 void soqlıǵısıw(Obekt obektler[]) {
 _s->soqlıǵısıw(obektler);
 }
};
```
Sonnan keyin anıq klaslar tómendegishe boladı:
```cpp
class Oyınshı : public Obekt
{
public:
 Oyınshı()
 : Obekt(new Kórinetuǵın(), new Jıljıtılatuǵın(), new Qattı())
 {}

 // ...
};

class Tútin : public Obekt
{
public:
 Tútin()
 : Obekt(new Kórinetuǵın(), new Jıljıtılatuǵın(), new QattıEmes())
 {}

 // ...
};
```


## Artıqmashılıqları
Miyrasxorlıq boyınsha kompoziciyaǵa artıqmashılıq beriw - bul dizaynǵa joqarı qolaylılıq beretuǵın dizayn principi. Biznes-domen klasların túrli komponentlerden dúziw, olardıń arasındaǵı ulıwmalıqtı tabıwǵa hám shańaraq teregin jaratıwǵa urınıwǵa qaraǵanda tábiyiyirek. Mısalı, akselerator pedalı menen rul dóńgeleginiń ulıwma qásiyetleri júdá az, biraq ekewi de avtomobildiń áhmiyetli komponentleri bolıp tabıladı. Olardıń ne isley alatuǵını hám avtomobilge qanday payda keltire alatuǵını ańsat anıqlanadı. Sonday-aq, kompoziciya shańaraq aǵzalarınıń ózgesheliklerine beyim bolmaǵanlıǵı sebepli, uzaq múddetli perspektivada turaqlıraq biznes-domendi támiyinleydi. Basqasha aytqanda, obekttiń ne ekenligin (is-a) keńeytiwden góre, onıń ne isley alatuǵının (has-a) qurastırıw jaqsıraq.

Dáslepki dizayn, sistema obektleriniń háreketlerin bólek interfeyslerde anıqlaw arqalı ápiwayılastırıladı, biznes-domen klasları arasında háreketlerdi miyrasxorlıq arqalı bólistiriw ushın ierarxiyalıq qatnas jaratıwdıń ornına. Bul kózqaras keleshektegi talaplardıń ózgerislerine ańsat beyimlesedi, al miyrasxorlıq modelinde bunday ózgerisler biznes-domen klaslarınıń tolıq qayta dúziliwin talap eter edi. Bunnan tısqarı, bul kózqaras bir neshe áwlad klasların óz ishine alǵan miyrasxorlıqqa tiykarlanǵan modeldegi salıstırmalı túrde kishi ózgerisler menen baylanıslı máselelerden qashadı. Kompoziciya qatnası kóbirek iykemli, sebebi ol orınlanıw waqtında ózgertiliwi múmkin, al subtiplew qatnasları statikalıq bolıp, kóplegen tillerde qayta kompilyaciyanı talap etedi.

Ayırım tiller, ásirese Go hám Rust, tek tip kompoziciyasın qollanadı.

## Kemshilikleri
Miyrasxorlıqtıń ornına kompoziciyanı qollanıwdıń bir ulıwma kemshiligi - ayırım komponentler tárepinen beriletuǵın metodlar tuwındı tipte ámelge asırılıwı kerek bolıwı múmkin, hátte olar tek jiberiletuǵın metodlar bolsa da (bul kópshilik programmalastırıw tillerinde durıs, biraq hámmesinde emes; § Kemshiliklerden qashıw bólimin qarań). Kerisinshe, miyrasxorlıq tiykarǵı klasstıń barlıq metodların tuwındı klassta qayta ámelge asırıwdı talap etpeydi. Kerisinshe, tuwındı klass tek tiykarǵı klass metodlarınan ózgeshe háreketke iye metodlardı ámelge asırıwı (biykarlawı) kerek. Eger tiykarǵı klass kóp sanlı ádettegi háreketti támiyinleytuǵın metodlardı óz ishine alsa hám olardıń tek bir neshewi tuwındı klassta biykarlanıwı kerek bolsa, bul júdá az programmalastırıw miynetin talap etiwi múmkin.

Mısalı, tómendegi C# kodında, Employee tiykarǵı klassınıń ózgeriwshileri hám metodları HourlyEmployee hám SalariedEmployee tuwındı subklassları tárepinen miyras etip alınadı. Tek Pay() metodı hárbir tuwındı subklass tárepinen ámelge asırılıwı (arnawlı etiliwi) kerek. Basqa metodlar tiykarǵı klasstıń ózi tárepinen ámelge asırıladı hám onıń barlıq tuwındı subklassları tárepinen bólisiledi; olardı subklass anıqlamalarında qayta ámelge asırıw (biykarlaw) yamasa hátte esletiw kerek emes.


```csharp
// Tiykarǵı klass
public abstract class Xızmetker
{
 // Qásiyetler
 protected string Atı { get; set; }
 protected int ID { get; set; }
 protected decimal TólemStavkası { get; set; }
 protected int IslegenSaatlar { get; }

 // Házirgi tólem dáwiri ushın tólemdi alıw
 public abstract decimal Tólem();
}

// Tuwındı subklass
public class SaatlıqXızmetker : Xızmetker
{
 // Házirgi tólem dáwiri ushın tólemdi alıw
 public override decimal Tólem()
 {
 // Islengen waqıt saatlarda
 return IslegenSaatlar * TólemStavkası;
 }
}

// Tuwındı subklass
public class AylıǵıXızmetker : Xızmetker
{
 // Házirgi tólem dáwiri ushın tólemdi alıw
 public override decimal Tólem()
 {
 // Tólem stavkası saatlıq emes, al jıllıq maosh
 return IslegenSaatlar * TólemStavkası / 2087;
 }
}
```


### Kemshiliklerdi boldırmaw
Bul kemshilikten treytler, miksinler, (tip) jaylastırıw yamasa protokol keńeytiwlerin qollanıw arqalı boldırmawǵa boladı.

Ayırım tiller onı jeńilletiw ushın arnawlı qurallar usınadı:

* C# 8.0 versiyasınan baslap interfeys aǵzasına deneni anıqlawǵa múmkinshilik beretuǵın standart interfeys metodların usınadı.: 28–29 : 38 : 466–468 
* D tiptiń ishinde anıq "alias this" deklaraciyasın usınadı, ol basqa jaylastırılǵan tiptiń hárbir metodı hám aǵzasın alǵa jibere aladı.
* Dart bólisiwge bolatuǵın standart ámelge asırıwları bar miksinlerdi usınadı.
* Go tipin jaylastırıw metodlardı alǵa jiberiw zárúrligin saplastıradı.
* Java 8-versiyasınan baslap standart interfeys metodların usınadı. Project Lombok wákillik beriw maydannıń barlıq metodlarınıń atları hám tiplerin kóshirip alıw hám saqlaw ornına, maydanda @Delegate annotaciyasın qollanıw arqalı wákillikti qollaydı.
* Julia makrosları metodlardı alǵa jiberiw ushın qollanılıwı múmkin. Lazy.jl hám TypedDelegation.jl sıyaqlı bir neshe ámelge asırıwlar bar.
* Kotlin til sintaksisine wákillik úlgisin kirgizgen.
* PHP 5.4 versiyasınan baslap treytlerdi qollaydı.
* Raku metodlardı alǵa jiberiwdi ańsatlastırıw ushın handles treytin usınadı.
* Rust standart ámelge asırıwları bar treytlerdi usınadı.
* Scala (3-versiyadan baslap) obekttiń tańlanǵan aǵzaları ushın laqaplardı anıqlaw ushın "export" bólimin usınadı.
* Swift keńeytiwleri ayırım tip ámelge asırıwınıń ishinde emes, al protokoldıń ózinde protokoldıń standart ámelge asırılıwın anıqlaw ushın qollanılıwı múmkin.

## Empirikalıq izertlewler
2013-jılı 93 ashıq kodlı Java baǵdarlamasına (hár qıylı kólemdegi) júrgizilgen izertlew mınalardı anıqladı:

Miyrasxorlıqtı kompoziciya menen almastırıw ushın úlken múmkinshilik joq bolsa da (...), bul múmkinshilik áhmiyetli (miyrasxorlıqtı qollanıwdıń ortasha 2% tek ishki qayta qollanıw ushın, al qosımsha 22% tek sırtqı yamasa ishki qayta qollanıw ushın).

Biziń nátiyjelerimiz miyrasxorlıqtıń qáte qollanılıwına baylanıslı táshiwish etiwge sebep joq ekenin kórsetedi (hesh bolmaǵanda ashıq kodlı Java baǵdarlamalarında), biraq olar kompoziciyaǵa qarsı miyrasxorlıqtı qollanıw máselesin alǵa shıǵaradı. Eger kompoziciyanı qollanıwǵa bolatuǵın jaǵdayda miyrasxorlıqtı qollanıw menen baylanıslı áhmiyetli shıǵınlar bar bolsa, onda biziń nátiyjelerimiz bazı bir táshiwishleniwge sebep bar ekenin kórsetedi.

## Derekler

__BÖLİDİMÖNDEMEW__