Badanie struktury programów obiektowych

Ukończone

Programowanie obiektowe (OOP) używa obiektów do modelowania rzeczywistych jednostek.

W przypadku deweloperów, którzy znają programowanie strukturalne, porównanie programowania strukturalnego i programowania obiektowego może pomóc wyjaśnić różnice między dwoma podejściami. Ponadto rozwijanie wiedzy na temat hermetyzacji i cyklu życia klasy może pomóc w opracowaniu bezpiecznych i niezawodnych rozwiązań.

Porównanie programowania Object-Oriented ze strukturą

Programowanie strukturalne i programowanie obiektowe (OOP) to dwa odrębne podejścia do tworzenia oprogramowania, z których każdy ma własny zestaw zasad i metodologii. Programowanie strukturalne opiera się na podejściu od góry do dołu, w którym program jest podzielony na mniejsze, możliwe do zarządzania funkcje lub procedury. Takie podejście podkreśla jasny i logiczny przepływ kontroli przy użyciu pętli, warunkowych i podroutety. Programowanie obiektowe organizuje projektowanie oprogramowania wokół obiektów, które hermetyzują zarówno dane, jak i zachowanie, promując bardziej modułową i wielokrotnego użytku strukturę kodu. Chociaż programowanie strukturalne koncentruje się na sekwencji akcji do wykonania, programowanie obiektowe podkreśla obiekty zaangażowane w akcje.

Możemy użyć rzeczywistych przykładów projektów budowlanych jako metafor, aby zilustrować różnice między programowaniem strukturalnym a programowaniem obiektowym.

przykład programowania Object-Oriented

Wyobraź sobie programowanie obiektowe jako projektowanie i budowanie miasta. W tej metaforze każdy budynek reprezentuje klasę, a pokoje i obiekty każdego budynku reprezentują właściwości i metody tej klasy. Podobnie jak miasto składa się z różnych budynków, z których każda służy konkretnemu celowi (mieszkalnym, komercyjnym, przemysłowym), program OOP składa się z różnych klas, z których każda ma obsługiwać określone zadania. Budynki (klasy) są konstruowane na podstawie strategii (definicji klas), a każdy budynek może mieć wiele wystąpień (obiektów), które współużytkują tę samą strukturę, ale mogą mieć różne stany (dane).

W tym mieście hermetyzacja przypomina ściany budynku, które chronią jego wewnętrzną strukturę i umożliwiają dostęp tylko przez wyznaczone drzwi i okna (metody). Hermetyzacja gwarantuje, że wewnętrzne prace budynku (klasy) są ukryte przed światem zewnętrznym, a interakcje z budynkiem są kontrolowane i bezpieczne.

Ta metafora budynku miasta podkreśla modułowy i wielokrotnego użytku charakter OOP, w którym każda klasa (budynek) może być opracowywana, testowana i utrzymywana niezależnie, ale wszystkie współpracują ze sobą, aby utworzyć spójną i funkcjonalną miasto (program). Podobnie jak dobrze zaplanowane miasto pozwala na efektywne zarządzanie i skalowalność, dobrze zaprojektowany program OOP promuje utrzymanie, elastyczność i skalowalność.

Przykład programowania strukturalnego

Wyobraź sobie programowanie strukturalne jako kołdry. W tej metaforze każda część tkaniny reprezentuje funkcję lub procedurę w programie. Podobnie jak kołdra składa się z wielu pojedynczych poprawek szytych razem, program ustrukturyzowany składa się z różnych funkcji, które są przeznaczone do wykonywania określonych zadań. Każda funkcja jest jak poprawka, którą można opracowywać, testować i utrzymywać niezależnie. Po szyciu tych poprawek w określonej kolejności tworzysz kompletną kołdę, tak samo jak łączysz funkcje w celu utworzenia kompletnego programu.

W programowaniu ustrukturyzowanym koncentruje się on na logicznym przepływie sterowania, podobnie jak sposób planowania układu i sekwencji poprawek w celu utworzenia spójnych projektów. Kołdra zapewnia, że każda poprawka doskonale pasuje do innych, zachowując jasny i zorganizowany wzorzec. Podobnie programista ze strukturą zapewnia, że każda funkcja bezproblemowo pasuje do ogólnego programu, zachowując przejrzysty i logiczny przepływ sterowania za pomocą pętli, warunkowych i podroutyn.

Ta metafora pikowania podkreśla modułowy charakter programowania strukturalnego, w którym każda funkcja (lub poprawka) może być ponownie wykorzystywana i zmieniana zgodnie z potrzebami. Tak jak quilter może zastąpić lub zmodyfikować poszczególne poprawki bez zakłócania całej kołdry, programista może aktualizować lub udoskonalać poszczególne funkcje bez wpływu na cały program. Ta modułowość sprawia, że programowanie strukturalne jest skutecznym podejściem do tworzenia jasnego, konserwowalnego i wielokrotnego użytku kodu. Jednak wraz ze wzrostem rozmiaru i złożoności programu zarządzanie interakcjami między funkcjami może stać się trudniejsze. Podobnie jak kołdra z zbyt dużą liczbą poprawek może stać się nieporęczna i trudna do zarządzania, ustrukturyzowany program z wieloma funkcjami i procedurami może stać się kłopotliwy i trudny do utrzymania. Wraz ze wzrostem liczby poprawek (funkcji) coraz trudniejsze staje się śledzenie sposobu ich współdziałania i interakcji. Prowadzi to do problemów, takich jak duplikowanie kodu, trudności w debugowaniu i brak spójności. W dużych aplikacjach podejście liniowe i od góry do dołu programowania strukturalnego może spowodować splątanie sieci współzależnych funkcji, co utrudnia zrozumienie i zmodyfikowanie bazy kodu. Ta złożoność może utrudniać skalowalność i łatwość konserwacji, ostatecznie wpływając na ogólną jakość i wydajność oprogramowania.

Badanie użycia klas w programowaniu Object-Oriented

Klasy to bloki konstrukcyjne programowania obiektowego (OOP) i służą do definiowania struktury i zachowania obiektów w programie. Zrozumienie korzyści zapewnianych przez hermetyzację i cykl życia klas pomaga zrozumieć, jak działa programowanie obiektowe.

Hermetyzacja

Hermetyzacja jest jedną z podstawowych zasad programowania obiektowego (OOP). Odnosi się do tworzenia pakietów danych (pól) i metod (zachowań), które działają na danych w ramach jednej jednostki, zazwyczaj klasy. Hermetyzacja ogranicza bezpośredni dostęp do niektórych składników obiektu, co może zapobiec przypadkowej modyfikacji danych.

Hermetyzacja zapewnia następujące korzyści:

Ukrywanie danych: Hermetyzacja umożliwia ukrycie stanu wewnętrznego obiektu na zewnątrz. Oznacza to, że wewnętrzna reprezentacja obiektu może zostać zmieniona bez wpływu na kod zewnętrzny, który używa obiektu. Na przykład przy użyciu pól prywatnych i udostępniania publicznych metod pobierania i ustawiania można kontrolować sposób uzyskiwania dostępu do danych i ich modyfikacji.

Ulepszona obsługa: Hermetyzacja ułatwia konserwację i modyfikowanie kodu. Zmiany w wewnętrznej implementacji klasy nie mają wpływu na kod korzystający z klasy, o ile interfejs publiczny pozostaje taki sam. To rozdzielenie obaw pozwala deweloperom skupić się na określonych częściach kodu bez obaw o niezamierzone skutki uboczne.

Zwiększona elastyczność: Hermetyzacja umożliwia bardziej elastyczny i modułowy kod. Definiując jasne interfejsy, można łatwo zastąpić lub zaktualizować części kodu bez wpływu na inne części. Ta modułowość ułatwia ponowne używanie kodu i kompilowanie złożonych systemów z prostszych składników.

Zwiększone zabezpieczenia: Hermetyzacja pomaga chronić integralność danych obiektu, uniemożliwiając nieautoryzowany dostęp i modyfikację. Kontrolując dostęp do danych za pomocą metod, można wymusić reguły i ograniczenia dotyczące sposobu użycia danych. To wymuszanie pomaga zapobiec usterce i zapewnić, że obiekt pozostaje w prawidłowym stanie.

Abstrakcja: Hermetyzacja obsługuje koncepcję abstrakcji, ujawniając tylko niezbędne szczegóły obiektu na zewnątrz. Upraszcza to interfejs i ułatwia zrozumienie obiektu i korzystanie z niego. Użytkownicy obiektu nie muszą znać wewnętrznej implementacji, co zmniejsza złożoność kodu i zwiększa czytelność.

Nuta

Hermetyzacja polega na ukrywaniu składowych danych, których użytkownicy klasy nie potrzebują. Składowe danych są hermetyzowane lub ukryte przy użyciu słowa kluczowego private dostępu. Dostęp do ukrytych zmiennych pól jest kontrolowany przy użyciu właściwości i metod. Ukryte składowe danych nie są bezpośrednio dostępne.


public class Person
{
    // Private fields
    private string firstName;
    private string lastName;
    private int age;

    // Public properties with getters and setters
    public string FirstName
    {
        get { return firstName; }
        set { firstName = value; }
    }

    public string LastName
    {
        get { return lastName; }
        set { lastName = value; }
    }

    public int Age
    {
        get { return age; }
        set
        {
            if (value >= 0)
            {
                age = value;
            }
            else
            {
                throw new ArgumentException("Age can't be negative");
            }
        }
    }

    // Public method
    public void Introduce()
    {
        Console.WriteLine($"Hi, I'm {FirstName} {LastName}, and I'm {Age} years old.");
    }
}

W tym przykładzie:

  • Pola firstName, lastNamei ageprivate, co oznacza, że nie można uzyskać do nich dostępu bezpośrednio spoza klasy.
  • Właściwości publiczne FirstName, LastNamei Age zapewniają kontrolowany dostęp do pól prywatnych.
  • Właściwość Age zawiera logikę walidacji, aby upewnić się, że wiek nie może być ustawiony na wartość ujemną.
  • Metoda Introduce umożliwia interakcję z danymi obiektu bez ujawniania wewnętrznych szczegółów implementacji.

Cykl życia klas

W aplikacji języka C# cykl życia klasy obejmuje kilka etapów od jej definicji do ewentualnego zniszczenia. Cykl życia klasy obejmuje następujące kroki:

  1. Definicja klasy: zdefiniuj klasę przy użyciu jej składowych.
  2. Kompilacja: skompiluj klasę w kodzie IL.
  3. Ładowanie: załaduj zestaw do pamięci.
  4. Tworzenie wystąpienia: utwórz wystąpienie klasy.
  5. Inicjowanie: zainicjuj pola i właściwości obiektu.
  6. Użycie: użyj obiektu w aplikacji.
  7. Odzyskiwanie pamięci: odzyskiwanie pamięci obiektu, gdy nie jest już potrzebne.
  8. Zniszczenie: Wykonaj logikę oczyszczania i pamięć wydania.

Oto przykład, który zawiera wyjaśnienie każdego kroku w cyklu życia klasy:

  1. Definicja klasy

    Definicja: Klasa jest definiowana w kodzie źródłowym z jego właściwościami, metodami i innymi elementami członkowskimi.

    Na przykład:

    
    public class Person
    {
        // auto-implemented properties for name and age
        public string FirstName { get; set; }
        public string LastName { get; set; }
        public int Age { get; set; }
    
        // method to introduce the person
        public void Introduce()
        {
            Console.WriteLine($"Hi, I'm {FirstName} {LastName}, and I'm {Age} years old.");
        }
    }
    
    
  2. Kompilacja

    Kompilacja: kod źródłowy jest kompilowany w języku pośrednim (IL) przez kompilator języka C#. Kod IL jest przechowywany w zestawie (plik DLL lub EXE).

    Na przykład: klasa Person jest kompilowana w kodzie IL i zawarta w zestawie.

  3. Ładowania

    Ładowanie: po uruchomieniu aplikacji środowisko uruchomieniowe języka wspólnego (CLR) ładuje zestaw do pamięci.

    Na przykład: zestaw zawierający klasę Person jest ładowany do pamięci przez clR.

  4. Wystąpienia

    Tworzenie wystąpienia: wystąpienie klasy jest tworzone przy użyciu słowa kluczowego new. Konstruktor klasy jest wywoływany w celu zainicjowania obiektu.

    Na przykład:

    
    Person person1 = new Person { FirstName = "Tim", LastName = "Shao", Age = 25 };
    
    
  5. Inicjowania

    Inicjowanie: konstruktor inicjuje pola i właściwości obiektu. Wykonywana jest dowolna logika inicjowania zdefiniowana w konstruktorze.

    Przykład: Person obiektu person1 jest inicjowany przy użyciu określonych wartości dla FirstName, LastNamei Age.

  6. Zwyczaj

    Użycie: obiekt jest używany w aplikacji. Metody i właściwości obiektu są dostępne i modyfikowane zgodnie z potrzebami.

    Na przykład:

    
    person1.Introduce();
    
    
  7. Odzyskiwanie pamięci

    Odzyskiwanie pamięci: gdy obiekt nie jest już potrzebny i nie ma do niego odwołań, moduł odśmiecający pamięci (GC) odzyskuje pamięć używaną przez obiekt. Destruktor (finalizator) jest wywoływany, jeśli jest zdefiniowany.

    Przykład: Jeśli person1 nie odwołuje się już do żadnego miejsca w kodzie, GC ostatecznie odzyska pamięć.

  8. Zniszczenie

    Zniszczenie: pamięć obiektu jest zwalniana i jest wykonywana każda logika oczyszczania zdefiniowana w destruktorze (finalizator, jeśli został określony).

    Przykład: obiekt Personperson1 jest niszczony, a jego pamięć jest odzyskiwane przez GC.