Kapszulázás (számítógépes programozás) - Encapsulation (computer programming)

Az objektumorientált programozás (OOP) esetében a beágyazás az adatok kötegelésére utal az adatokkal működő módszerekkel, vagy az objektum egyes összetevőihez való közvetlen hozzáférés korlátozására. A beágyazást arra használják, hogy elrejtsék egy strukturált adatobjektum értékeit vagy állapotát egy osztályon belül , megakadályozva, hogy az ügyfelek közvetlenül hozzájuk férjenek, oly módon, hogy felfedjék a rejtett megvalósítási részleteket vagy megsértik a módszerek által fenntartott állapotinvarianciát.

Nyilvánosan hozzáférhető módszerek állnak rendelkezésre az osztályban az állapot absztraktabb eléréséhez vagy módosításához. A gyakorlatban néha módszereket (úgynevezett "gettereket" és "settereket" ) biztosítanak az értékek közvetett eléréséhez, de bár nem feltétlenül sértik az absztrakt beágyazást, gyakran a potenciálisan rossz objektumorientált programozás jelzőpontjának tekintik őket (OOP) tervezési gyakorlat ( Anti-pattern ).

Ez a mechanizmus nem csak az OOP -ra jellemző. Az elvont adattípusok , például a modulok megvalósításai hasonló formátumú beágyazást kínálnak. A hasonlóságot a programozási nyelv elméletei az egzisztenciális típusok alapján magyarázták .

Jelentése

Az objektum-orientált programozási nyelveken és más kapcsolódó területeken a beágyazás a két kapcsolódó, de különálló fogalom egyikére utal, és néha ezek kombinációjára:

  • Nyelvi mechanizmus az objektum egyes összetevőihez való közvetlen hozzáférés korlátozására .
  • Nyelvi konstrukció, amely megkönnyíti az adatok összekapcsolását az adatokkal működő módszerekkel (vagy más funkciókkal).

Egyes programozási nyelvek kutatói és akadémikusai az első jelentést önmagukban vagy a másodikkal kombinálva használják az objektum-orientált programozás megkülönböztető jellemzőjeként , míg egyes lexikai lezárásokat biztosító programozási nyelvek a beágyazást a tárgyra orientációtól függő nyelv sajátosságának tekintik .

A második definíciót az motiválja, hogy sok objektum-orientált nyelven és más kapcsolódó területeken az összetevők nem rejtőznek el automatikusan, és ez felülbírálható; így az információk elrejtését külön fogalomként határozzák meg azok, akik a második definíciót részesítik előnyben.

A beágyazás jellemzőit a legtöbb objektumorientált nyelv osztályai támogatják , bár más alternatívák is léteznek.

Kapszulázás és öröklődés

A Design Patterns szerzői hosszasan tárgyalják az öröklődés és a beágyazás közötti feszültséget, és kijelentik, hogy tapasztalataik szerint a tervezők túlzott mértékben használják fel az öröklést. Azt állítják, hogy az öröklés gyakran megszakítja a beágyazódást, tekintettel arra, hogy az öröklés egy alosztályt tesz ki a szülő végrehajtásának részleteinek. Amint azt a jojó probléma leírta, az öröklés túlzott használata és ezért a beágyazódás túl bonyolultá és nehezen hibakereshetővé válhat.

Az információ elrejtése

Az a meghatározás szerint, hogy a beágyazás "adattagok és tagfüggvények elrejtésére használható", az objektum belső ábrázolása általában rejtve van az objektum definícióján kívül. Általában csak az objektum saját módszerei képesek közvetlenül ellenőrizni vagy manipulálni a mezőit. Az objektum belsejének elrejtése védi annak integritását, mivel megakadályozza, hogy a felhasználók érvénytelen vagy következetlen állapotba állítsák az összetevő belső adatait. A kapszulázás feltételezett előnye, hogy csökkentheti a rendszer összetettségét, és ezáltal növelheti a robusztusságot , mivel lehetővé teszi a fejlesztő számára, hogy korlátozza a szoftverkomponensek közötti kölcsönös függőségeket.

Egyes nyelvek, például a Smalltalk és a Ruby, csak az objektummódszereken keresztül teszik lehetővé a hozzáférést, de a legtöbb más (pl. C ++ , C# , Delphi vagy Java ) a programozó számára bizonyos mértékű ellenőrzést biztosít a rejtett dolgok felett, általában az olyan kulcsszavak segítségével, mint publicés private. Az ISO C ++ szabvány " hozzáférés -specifikátorok " -ra utal protected, privateés public" nem rejt el semmilyen információt". Az információ elrejtése a forráskód fordított változatának biztosításával valósul meg, amely fejlécfájllal kapcsolódik.

Szinte mindig van mód az ilyen védelem felülbírálására - általában reflexió API -n (Ruby, Java, C#stb.) Keresztül , néha olyan mechanizmusok révén, mint a név manipulálása ( Python ), vagy speciális kulcsszóhasználat, például frienda C ++ nyelven. Az objektumszintű képesség-alapú biztonságot nyújtó rendszerek (az objektumképesség-modellhez ragaszkodva ) kivételt képeznek, és garantálják az erős beágyazást.

Példák

Az adatmezők korlátozása

Az olyan nyelvek, mint a C ++ , a C# , a Java , a PHP , a Swift és a Delphi lehetőséget kínálnak az adatmezőkhöz való hozzáférés korlátozására.

Az alábbiakban egy példa található a C# -ban, amely bemutatja, hogyan lehet korlátozni egy adatmezőhöz való hozzáférést egy privatekulcsszó használatával:

class Program
{
    public class Account
    {
        private decimal accountBalance = 500.00m;

        public decimal CheckBalance()
        {
            return this.accountBalance;
        }
    }

    static void Main()
    {
        Account myAccount = new Account();
        decimal myBalance = myAccount.CheckBalance();

        /* This Main method can check the balance via the public
         * "CheckBalance" method provided by the "Account" class 
         * but it cannot manipulate the value of "accountBalance" */
    }
}

Az alábbiakban egy példa a Java -ban :

public class Employee {
    private BigDecimal salary = new BigDecimal(50000.00);
    
    public BigDecimal getSalary() {
        return this.salary;
    }

    public static void main() {
        Employee e = new Employee();
        BigDecimal sal = e.getSalary();
    }
}

A beágyazás nem objektum-orientált nyelvekben is lehetséges. A C -ben például egy struktúra deklarálható a nyilvános API -ban a fejlécfájl segítségével egy olyan funkciókészlethez, amely olyan adatelemen működik, amely olyan adattagokat tartalmaz, amelyek nem érhetők el az API ügyfelei számára a externkulcsszóval.

// Header file "api.h"

struct Entity;          // Opaque structure with hidden members

// API functions that operate on 'Entity' objects
extern struct Entity *  open_entity(int id);
extern int              process_entity(struct Entity *info);
extern void             close_entity(struct Entity *info);
// extern keywords here are redundant, but don't hurt.
// extern defines functions that can be called outside the current file, the default behavior even without the keyword

Az ügyfelek az API függvényeket hívják átláthatatlan adattípusú objektumok kiosztására, működtetésére és elhelyezésére . Az ilyen típusú tartalmak csak az API funkciók megvalósítása számára ismertek és hozzáférhetők; az ügyfelek nem férhetnek hozzá közvetlenül a tartalmához. Ezen funkciók forráskódja határozza meg a szerkezet tényleges tartalmát:

// Implementation file "api.c"

#include "api.h"

struct Entity {
    int     ent_id;         // ID number
    char    ent_name[20];   // Name
    ... and other members ...
};

// API function implementations
struct Entity * open_entity(int id)
{ ... }

int process_entity(struct Entity *info)
{ ... }

void close_entity(struct Entity *info)
{ ... }

Névcsalás

Az alábbiakban bemutatunk egy példát a Pythonra , amely nem támogatja a változó hozzáférési korlátozásokat. Azonban az egyezmény szerint privátnak kell tekinteni azt a változót, amelynek nevét aláhúzás jelzi.

class Car: 
    def __init__(self) -> None:
        self._maxspeed = 200
 
    def drive(self) -> None:
        print(f"Maximum speed is {self._maxspeed}.")
 
redcar = Car()
redcar.drive()  # This will print 'Maximum speed is 200.'

redcar._maxspeed = 10
redcar.drive()  # This will print 'Maximum speed is 10.'

Lásd még

Hivatkozások