Енкапсулация (програмиране): Разлика между версии

Изтрито е съдържание Добавено е съдържание
DenisDuev (беседа | приноси)
Създаване чрез превод на страницата "Encapsulation (computer programming)"
 
DenisDuev (беседа | приноси)
Създаване чрез превод на страницата "Encapsulation (computer programming)"
Ред 1:
В [[Език за програмиране|езиците за програмиране]], ен'''капсулиране''' се използва за обозначаване на една от две свързани, но различни понятия, а понякога и в комбинация<ref>Michael Lee Scott, ''Programming language pragmatics'', Edition 2, Morgan Kaufmann, 2006, [//en.wikipedia.org/wiki/Special:BookSources/0126339511 ISBN 0-12-633951-1], p. 481: "Encapsulation mechanisms enable the programmer to group data and the subroutines that operate on them together in one place, and to hide irrelevant details from the users of an abstraction."</ref><ref name="Dale">Nell B. Dale, Chip Weems, ''Programming and problem solving with Java'', Edition 2, Jones & Bartlett Publishers, 2007, [//en.wikipedia.org/wiki/Special:BookSources/0763734020 ISBN 0-7637-3402-0], p. 396</ref> :
* Механизъм за ограничаване на директен достъп до някои от [[Обект (програмиране)|обектите]] на компонентите.<ref>[//en.wikipedia.org/wiki/John_C._Mitchell John C. Mitchell], ''Concepts in programming languages'', Cambridge University Press, 2003, [//en.wikipedia.org/wiki/Special:BookSources/0521780985 ISBN 0-521-78098-5], p.522</ref><ref name="Pierce">{{Citecite book|last=Pierce|first=Benjamin|authorlink=Benjamin C. Pierce|title=[[Types and Programming Languages]]|publisher=MIT Press|year=2002|isbn=0-262-16209-1}}</ref>
* Езикова конструкция, която улеснява комбинирането на данни с [[Метод (програмиране)|методи]] (или други функции), извърващи операции върху тези данни.<ref>Wm. Paul Rogers, [http://www.javaworld.com/javaworld/jw-05-2001/jw-0518-encapsulation.html?page=9 ''Encapsulation is not information hiding''], JavaWorld.com, 05/18/01</ref><ref>Thomas M. Connolly, Carolyn E. Begg, ''Database systems: a practical approach to design, implementation, and management'', Edition 4, Pearson Education, 2005, [//en.wikipedia.org/wiki/Special:BookSources/0321210255 ISBN 0-321-21025-5], Chapter 25, "Introduction to Object DMBS", section "Object-oriented concepts", p. 814</ref>
Някои изследователи и учени на езиците за програмиране използват първото значение на енкапсулация самостоятелно, или в комбинация с второто значение като отличителна характеристика на [[Обектно-ориентирано програмиране|обектно-ориентираното програмиране]], а някои езици за програмиране, които осигуряват [[Затваряне (информатика)|лексическо затваряне]], енкапсулацията изглежда като тяхна характеристика.
Ред 9:
 
== Механизъм за скриване на информацията ==
Енкапсулацията може да се използва за да скрият [[полескрива наполета обект|полетатаи методи на обекта]] (dataдаден members) и методитеклас. Според тази дефиниция, енкапсулиране означава, че вътрешното представяне на [[Обект (програмиране)|обект]] , ене скритоможе отда външнатасе дефициявиди наизвън дадения обектаобект.  Като цялоправило, само собствените методи на даден обект можетмогат директно да виждат или променят поле на обекта(член данна). Някои езици за програмиране, като [[smalltalk]] и [[Ruby|Руби]] позволяват достъп само чрез методите на обекта, но повечето от останалите езици (например, [[C++|С++]], [[C Sharp|С#]], [[Delphi (език за програмиране)|Делфи]] или [[Java]]) предлагат на програмиста степента на контрол над това, което е скрито, обикновено чрез ключови думи, както <code>public</code>  (публични), така и <code>private</code>(лични). Трябва трябва да се отбележи, че ISO стандартастандарт в C++ се отнася до <code>protected</code>(защитени),  <codefont color="#000000" face="monospace, Courier">private </codefont> и <code>public</code>  , като "[[модификатори за достъп]]", и че те не се "крият никаква информация". УкриванетоСкриването на информация се осъществява чрез предоставяне на компилиранакрайната версия на изходния код, който се свързва чрез header([[Заглавен файл|заглавен(header) файлзагла]]<nowiki/>вен файл).
 
Криейки вътрешните данни, обекта защитава своята цялост, чрез предотвратяване на потребителите от променяне на вътрешните данни на обкета на неправилни или на противоречиви състояния. Предполагаемо предимство на енкапсулирането е, че това може да намали сложността на системата, и следователно, да се подобри [[Надеждност на софтуера|надеждността]], като същевременно позволява на разработчика да ограничи взаимозависимостите между софтуерните компоненти{{Източник}}.
 
Почти винаги има начин да се заобиколи тази защита &#x2013; обикновено чрез рефлекшън (отражение) в API ([[Ruby]], [[Java]], [[C Sharp|C#]] и т.н.), понякога чрез механизъм, като изопачаване на името (name mangling) ([[python]]), или специални запазени думи като на <code>friend</code> в C++.
[[Категория:Статии с конкретно поискани източници без посочена дата на поискване]]
 
По-долу е даден пример на [[C Sharp|C#]] , който показва как достъпът до полето с данни може да бъде ограничен, чрез използване на запазената дума <code>private</code>:<source lang="csharp">
class Program {
public class Account {
private decimal accountBalance = 500.00m;
 
public decimal CheckBalance() {
return 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" */
}
}
</source>По-долу е даден пример на Java:<source lang="java">
 
public class Employee {
private BigDecimal salary = new BigDecimal(50000.00);
public BigDecimal getSalary() {
return salary;
}
 
public static void main() {
Employee e = new Employee();
BigDecimal sal = e.getSalary();
}
}
</source><source lang="php">
class Account {
/**
* How much money is currently in the account
* @var float
*/
private $accountBalance;
 
/**
* @param float $currentAccountBalance Initialize account to this dollar amount
*/
public function __construct($currentAccountBalance) {
$this->accountBalance = $currentAccountBalance;
}
 
/**
* Add money to account
* @param float $money Dollars to add to balance
* @return void
*/
public function deposit($money) {
$this->accountBalance += $money;
}
 
/**
* Remove money from account
* @param float $money Dollars to subtract from balance
* @throws Exception
* @return void
*/
public function withdraw($money) {
if ($this->accountBalance < $money) {
throw new Exception('Cannot withdraw $' . $money . ' from account as it contains $' . $this->accountBalance);
}
$this->accountBalance -= $money;
}
 
/**
* Get current account balance, that takes all additions and subtractions into consideration.
* @return float
*/
public function getAccountBalance() {
return $this->accountBalance;
}
}
 
// Create a new object from the Account class with a starting balance of $500.00
$myAccount = new Account(500.00);
 
// We have clearly defined methods for adding and subtracting money from the Account
// If we didn't have a method for withdraw(), nothing would prevent us from withdrawing more money than was available in the account
$myAccount->deposit(10.24);
$myAccount->withdraw(4.45);
 
// Get the current balance
$accountBalance = $myAccount->getAccountBalance();
echo 'My Account Balance: $' . $accountBalance; // 505.79
 
// Our code forbids us from withdrawing more than we have
$myAccount->withdraw(600.00); // Exception Message: Cannot withdraw $600 from account as it contains $505.79
</source>Енкапсулацията също така може да се прилага в езици, които не са объектно-ориентирани. В [[C (език за програмиране)|C]], например, структурата може да бъде обявена в публично API (т.е. заглавен(header) файл) за набор от функции, които оперират върху елемент от данни, съдържащ полета на обекта, които не са достъпни за ползвателите на API:<source lang="csharp">
// 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);
</source>Ползвателите извикват API функции за алокиране, опериране върху тях и освобождаване на обекти от непрозрачен тип данни (opaque data type). Съдържанието на този тип са известни и са на разположение само за имплементацията на функциите на API-то, а ползвателите не могат директно да се обърнат към неговото съдържание. Изходният код за тези функции определя действителното съдържание на структурата:<source lang="csharp">
// Implementation file "api.c"
 
#include "api.h"
 
// Complete definition of the 'Entity' object
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)
{ ... }
</source>
 
== Историческо значение ==
Целта на енкапсулирането може да бъдат сведена до следното: за да се намалят конфликтите между променливи с еднакви имена и  да се групират заедно свързаните методи (функции) и свойства (променливи) за да се състави обект от клас. Тази практика помага изходния код съставен от стотици или хиляди редове код да се направи по-разбираем и работещ.
 
== Обща дефиниция ==
Като цяло, енкапсулирането е''' един от четирите основи на''' ООП ([[Обектно-ориентирано програмиране|обектно ориентирано програмиране]]). Енкапсулиране означава обединяване на данни с методи, които работят върху данните.<ref>{{Цитат уеб|last=Rodgers|first=Wm. Paul|title=Encapsulation is not information hiding|url=http://www.javaworld.com/article/2075271/core-java/encapsulation-is-not-information-hiding.html|publisher=JavaWorld|accessdate=2014-03-15}}</ref> Енкапсулацията '''се използва за скриване на стойността или състоянието на структурирани данни на обекта вътре в класа''', чрез предотвратяване на неоторизираният директен достъп до него. Публично достъпните методи обикновено се предоставят от класа (така наречените ''[[гетър(getter)|гетъри(getter)]]'' и ''[[сетър(setter)|сетъри(setter)]]'') за да се достъпват стойностите, и за да могат други използващи класове да достъпват тези методи за извличане и промяна на стойностите на обекта.
 
Този механизъм не е уникален за обектно-ориентираното програмиране. [[Имплементация|Имплементацията]] на абстрактни типове данни, например, [[Модул (софтуер)|модули]], предлагат подобна форма енкапсулация. Това сходство се дължи на факта, че двете понятия се основават на една и съща математическа основа - [[типизация на данните]].<ref>Pierce (2002), Section 24.2 "Data Abstraction with Existentials"</ref>
 
== Енкапсулация и наследяване ==
Авторите на "Design Patterns"<ref name="GoF">{{Cite book|last=Gamma|first=Erich|last2=Helm|first2=Richard|last3=Johnson|first3=Ralph|title=Design Patterns|publisher=Addison-Wesley|date=1994|isbn=0-201-63361-2}}</ref> обсъждат напрежението между наследяването и енкапсулирането много подробно и заявяват, че спрямо техния опит, дизайнерите на класовете използват прекалено много наследяването. Опасността е формулирана по следния начин:{{Цитат|Поради факта, че наследяването разкрива на подкласа в детайли имлементацията на родителя си, то се казва че "наследяването разбива енкапсулацията"}}
 
== Връзки ==