Що таке держава, змінна держава та незмінна держава?


32

Це питання для новачків, але я не зміг знайти в Google достатньо стійкої відповіді.

Що означають люди, коли вони говорять «держава» - взагалі в програмуванні та конкретно в програмуванні ОО?

Крім того, що таке незмінний і незмінний стан - знову ж таки, як правило, в програмуванні, а також конкретно в OOP?


4
Обмін дослідженнями допомагає всім . Розкажіть, що ви пробували і чому це не відповідало вашим потребам. Це свідчить про те, що ви знайшли час, щоб спробувати допомогти собі, це позбавляє нас від повторення очевидних відповідей, а найбільше це допомагає вам отримати більш конкретну та релевантну відповідь. Також дивіться Як запитувати
gnat

Відповіді:


46

Ви маєте стан, коли асоціюєте значення (числа, рядки, складні структури даних) до ідентичності та моменту часу.

Наприклад, число 10 саме по собі не представляє жодного стану: це просто чітко визначене число і завжди буде собою: натуральне число 10. Як ще один приклад, рядок "HELLO" - це послідовність з п'яти символів, і вона повністю описана символами, які вона містить, і послідовністю, в якій вони з'являються. Через п’ять мільйонів років відтепер рядок "HELLO" все ще буде рядком "HELLO": чисте значення.

Для того, щоб мати державу, ви повинні розглядати світ, в якому ці чисті цінності асоціюються з деякими сутностями, що володіють ідентичністю . Ідентичність - це примітивна ідея: це означає, що ви можете розрізнити дві речі незалежно від будь-яких інших властивостей, які вони можуть мати. Наприклад, дві машини однієї моделі, одного кольору, ... це дві різні машини.

Враховуючи ці речі з ідентичністю, ви можете прикріпити до них властивості, описані чистими значеннями. Наприклад, моя машина має властивість бути блакитним. Ви можете описати цей факт, об'єднавши пару

("colour", "blue")

до моєї машини. Пара ("колір", "синій") - це чисте значення, що описує стан саме цього автомобіля.

Держава пов'язана не тільки з конкретною сутністю, але і з певним моментом часу. Отже, ви можете сказати, що сьогодні моя машина має стан

("colour", "blue")

Завтра я його перефарбую в чорний колір, і буде новий стан

("colour", "black")

Зауважте, що стан суб'єкта може змінюватися, але його особа не змінюється за визначенням. Ну, доки сутність існує, звичайно: автомобіль може бути створений і знищений, але він зберігатиме свою ідентичність протягом усього життя. Немає сенсу говорити про тотожність того, чого ще не існує / вже не існує.

Якщо значення властивостей, приєднаних до даної сутності, змінюються з часом, ви говорите, що стан цієї сутності може змінюватися . Інакше ви кажете, що стан незмінний .

Найпоширеніша реалізація - це зберігання стану сутності в якихось змінних (глобальних змінних, змінних членів об'єкта), тобто для зберігання поточного знімка стану. Потім стан змінних реалізується за допомогою призначення: кожна операція призначення замінює попередній знімок на новий. Це рішення зазвичай використовує місця пам'яті для зберігання поточного знімка. Перезапис місця на пам'ять - це руйнівна операція, яка замінює знімок новою. ( Тут ви можете знайти цікаву бесіду про цей підхід до програмування, орієнтований на місце .)

Альтернативою є перегляд подальших станів (історії) сутності як потоку (можливо, нескінченна послідовність) значень, див., Наприклад, Розділ 3 SICP . У цьому випадку кожен знімок зберігається в іншому місці пам'яті, і програма може одночасно досліджувати різні знімки. Невикористані знімки можна збирати сміття, коли вони більше не потрібні.

Переваги / недоліки двох підходів

  • Підхід 1 споживає менше пам’яті і дозволяє більш ефективно сконструювати новий знімок, оскільки він не передбачає копіювання.
  • Підхід 1 неявно підштовхує новий стан до всіх частин програми, на які посилається на нього, підхід 2 потребує певного механізму, щоб надіслати знімок своїм спостерігачам, наприклад, у формі події.
  • Підхід 2 може допомогти запобігти непослідовні помилки стану (наприклад, часткові оновлення стану): шляхом визначення явної функції, яка створює новий стан від старого, простіше розрізнити знімки, створені в різні моменти часу.
  • Підхід 2 більш модульний тим, що дозволяє легко створювати погляди на стан, незалежний від самого стану, наприклад, використовуючи функції вищого порядку, такі як mapі filter.

1
Зауважте, що об'єкти - не єдині речі зі станом. Якщо програма використовує (змінні) глобальні змінні, сама програма має статус. Так само, якщо функція має змінну, яка запам’ятовує значення для викликів функції, функція є стаціонарною.
Doval

2
@Doval: Ви можете думати про глобальну державу як про стан глобального світового об'єкта. Наскільки мені відомо, ця думка використовується, наприклад, у Ruby. Функція, яка запам'ятовує стан, є ізоморфною для об'єкта лише одним методом. Поширена основна ідея полягає в тому, що ви пов'язуєте значення з тотожностями або місцями, тобто певні речі можуть містити значення (можливо, значення, що змінюється), але зберігати свою ідентичність.
Джорджіо

3
Звичайно, я згоден у принципі. Я просто переконуюсь, що Прог розуміє, що державність не є винятковою для OOP. Я не думаю, що думка "все є об'єктом" приходить природно.
Doval

@Doval: Ви згадали про стан функцій, які запам'ятовують значення для різних дзвінків. Одним із прикладів, про які я можу придумати, є статичні локальні змінні у C. Іншим прикладом є закриття (функції, що фіксують змінні, визначені в їх контексті). Закриття дещо подвійні по відношенню до об'єктів: закриття - це об'єкт точно одним методом, тоді як об'єкт - це сукупність закриттів, визначених одними і тими ж змінними. Ви, напевно, все це знаєте, але я хотів тут це підсумувати. Як правило, ви можете зберігати стан у деякому місці пам'яті та отримувати доступ до нього за допомогою різних механізмів, як ви вказували.
Джорджіо

11

Держава - це просто інформація про щось, що зберігається в пам'яті.

Як просту вправу в орієнтації на об'єкти, розгляньте клас як вирізання файлів cookie, а cookie - як об’єкти. Ви можете створити файл cookie (інстанціювати об’єкт) за допомогою вирізання файлів cookie (класу). Скажімо, однією з властивостей печива є його колір (який можна змінити, використовуючи харчовий барвник). Колір цього печива є частиною його стану, як і інші властивості.

Стан, що змінюється - це стан, який можна змінити після створення об'єкта (cookie). Незмінний стан - це стан, який неможливо змінити.

Незмінні об’єкти (для яких жодна держава не може бути змінена) стають важливими, коли ви маєте справу з одночасністю, здатністю більш ніж одного процесора на вашому комп’ютері працювати над цим об’єктом. Незмінність гарантує, що ви можете розраховувати на стан, щоб він був стабільним і дійсним протягом життя об'єкта.

Взагалі, стан об'єкта зберігається у "приватних змінних або членських змінних", а доступ до них здійснюється за допомогою "властивостей" або методів getter / setter.


3
На користь Prog важливий і той факт, що значення ніколи не змінюється, тому що набагато простіше міркувати. Її можна використовувати в будь-якій кількості функцій / методів, як ви хочете, і ви знаєте, що вони не можуть її змінити. Зі змінним станом ви повинні відслідковувати історію того, як цей об’єкт використовувався для з'ясування того, яке його значення має зараз . Це непотрібне психічне накладне покриття, якщо зробити його непорушним не ускладнює програму.
Doval

Дякую за відповідь. Отже, в ООП, коли хтось каже "стан", вони зазвичай мають на увазі "змінні елементи об'єкта"? Якщо так, то "мутаційний стан" - це загальнодоступні змінні, або більш поширені в OOP, приватні змінні, які можна змінити методами сеттера, а "незмінний стан" - це просто змінні приватні члени?
Авів Кон

1
Незмінність може бути симульована просто ніколи не записуючи приватних членів об'єкта, коли вони заповнені початковими значеннями. Незмінність може бути застосована за допомогою декількох методів: не надання методу встановлення, вимагає встановлення початкового значення за допомогою параметра конструктора, написання у функціональному стилі, використання констант тощо.
Роберт Харві

1
Я вважаю державу цінністю якоїсь властивості якоїсь сутності. "Відправлений" - це держава. Так само "Ставка податку". Вага чогось - це стан. Незалежно від того, ви зараз не спите чи спите - це стан. Колір чогось - це стан. Змістовна інформація про щось, що зберігається в якійсь пам’яті комп’ютера.
Роберт Харві

1
У багатьох мовах незмінність може бути забезпечена шляхом оголошення змінних членів як "const" або "final". Такі змінні може ініціалізувати лише конструктор. Не вважайте, що приватні змінні незмінні - вони все ще можуть бути змінені функціями (методами) власних членів класу.
Саймон Б

7

Я думаю, що термін "стан" (на відміну від конкретного типу стану, такого як "змінна члена") є найбільш корисним при порівнянні API стану стану з статусом без громадянства. Спроба визначити "стан", не згадуючи API, схожа на спробу визначити "змінну" або "функцію", не згадуючи мови програмування; більшість правильних відповідей мають сенс лише для людей, які вже знають, що означають слова.

Державний vs Без громадянства

  • Відстеження стану API є той , який «пам'ятає» , які функції ви назвали до сих пір і з якими аргументами, тому наступного разу при виконанні функції він збирається використовувати цю інформацію. Частина "запам'ятовування" часто реалізується за допомогою змінних членів, але це не єдиний спосіб.
  • Без громадянства API є один , де кожен виклик функції не залежить тільки від аргументів , переданих йому, і нічого іншого.

Наприклад, OpenGL - це, мабуть, найпопулярніший API, про який я знаю. Якщо я можу на мить нерозумно спростити це, ми можемо сказати, що це виглядає приблизно так:

glSetCurrentVertexBufferArray(vba1);
glSetCurrentVertexBufferObject(vbo1);
glSetCurrentVertexShader(vert1);
glSetCurrentFragmentShader(frag1);
// a dozen other things
glActuallyDrawStuffWithCurrentState(GL_TRIANGLES);

Практично кожну функцію просто використовують для передачі в якомусь стані OpenGL потрібно запам'ятати, тоді в кінці ви викликаєте одну антикліматично просту функцію, щоб виконати весь малюнок.

Версія без громадянства (спрощена) OpenGL, мабуть, виглядатиме приблизно так:

glActuallyDrawStuff(vba1, vbo1, vert1, frag1, /* a dozen other things */, GL_TRIANGLES);

Ви часто чуєте, як люди говорять, що API з меншим станом простіше пояснити. Якщо ви можете тримати під контролем підрахунок аргументів, я, як правило, з цим згоден.

Зміна проти змінних

Наскільки я знаю, це відмінність має сенс лише тоді, коли можна вказати початковий стан . Наприклад, використовуючи конструктори C ++:

// immutable state
ImmutableWindow windowA = new ImmutableWindow(600, 400);
windowA = new ImmutableWindow(800, 600); // to change the size, I need a whole new window

// mutable state
MutableWindow windowB = new MutableWindow(600, 400);
windowB.width = 800; // to change the size, I just alter the existing object
windowB.height = 600;

Важко реалізувати клас вікон, який не «пам’ятає», який він розмір, але ви можете вирішити, чи повинен користувач мати змогу змінити розмір вікна після його створення.

PS В OOP це правда, що "state" зазвичай означає "змінні члена", але це може бути набагато більше, ніж це. Наприклад, у C ++ метод може мати статичну змінну, а лямбдаси можуть стати закриттями шляхом захоплення змінних. В обох випадках ці змінні зберігаються в декількох викликах до функції і, отже, ймовірно, кваліфікуються як стан. Локальні змінні у звичайній функції також можуть вважатися станом залежно від того, як вони використовуються (ті, які я маю в основному () часто рахуються).


ДУМОВА відповідь. Дякую вам дуже, ви дійсно допомогли мені швидко підібрати це. Мало що я знав, я довго працював з цим і не знав, як це називається.
the_endian

2

Простамими словами

У словнику зазначено:

а. Стан або спосіб існування, як і стосовно обставин.

  1. держава - те, як щось відбувається щодо його основних ознак;

Стан чогось - це набір значень, які мають його атрибути в будь-який момент.

У OOP стан об’єкта - це короткий знімок того, якими є значення його атрибутів у будь-який момент.

Thing t = new Thing();
t.setColor("blue");
t.setPrice(100)
t.setSize("small");

Стан його полягає в тому, що його колір синій, його ціна 100, а розмір невеликий.

Якщо ви пізніше зробите:

t.setColor("red");

Ви змінюєте один з його атрибутів, але ви також змінили стан цілого, оскільки об'єкт вже не такий, як був.

Іноді класи створені таким чином, що значення їх властивостей не можуть бути змінені після їх створення. Усі значення їх властивостей або передаються конструктору, або читаються з якогось джерела, як-от база даних або файл, але немає можливості змінити ці значення після цього моменту, оскільки не існує методів "встановлення" чи будь-якого іншого способу зміна значень всередині об’єкта.

Thing t = new Thing("red",100,"small");
t.setColor("blue") -->> ERROR, the programmer didn't provide a setter or any other way to change the properties values after initialization.

Це називається стан, який неможливо змінити мутованим. Все, що ви можете зробити, це знищити об’єкт, створити новий і привласнити його до тієї ж посилання або змінної.

Thing t = new Thing("red",100,"small");
t = new Thing("blue",100,"small");
// I had to create a new Thing with another color since this thing is inmutable.
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.