DZWON

Są tacy, którzy czytają tę wiadomość przed tobą.
Zapisz się, aby otrzymywać najnowsze artykuły.
E-mail
Imię
Nazwisko
Jak chcesz przeczytać The Bell
Bez spamu

Wysyłanie dobrej pracy do bazy wiedzy jest proste. Skorzystaj z poniższego formularza

Studenci, doktoranci, młodzi naukowcy korzystający z bazy wiedzy w swoich studiach i pracy będą Ci bardzo wdzięczni.

Wysłany dnia http://www.allbest.ru/

MINISTERSTWO ODDZIAŁUROSJA

abstrakcyjny

„Programowanie modułowe”

Wprowadzenie

Sercem języka programowania jest pewna myśl przewodnia spowodowana potrzebami lub częściej kryzysem w dziedzinie programowania i wytwarzania oprogramowania, która ma istotny wpływ na styl programowania i pomaga przezwyciężyć ten kryzys.

Programowanie zorientowane na maszynę pojawił się równocześnie z tworzeniem komputerów elektronicznych. Początkowo były to programy w kodach maszynowych, potem pojawił się język programowania Assembler (Autocode), który trochę „zhumanizował” pisanie programu w kodzie maszynowym.

Programowanie proceduralne. Główną ideą tego stylu jest algorytmizacja procesu rozwiązywania problemu i wybór najlepszego algorytmu (pod względem zużycia pamięci lub szybkości.

Programowanie strukturalne. Tutaj główną ideę doskonale wyraża N. Wirth w swojej książce „Algorytmy + struktury danych \u003d programy”. Była to odpowiedź na kryzys programowania, który rozpoczął się w połowie lat sześćdziesiątych, kiedy kod źródłowy przekroczył 1000 linii. W 1971 roku algorytmika język pascal a nieco później, w 1972 roku, język C.

Programowanie modułowe. Głównym zamysłem było „ukrycie” danych i procedur w niezależnych jednostkach programu - modułach . Pomysł ten został po raz pierwszy zrealizowany przez N. Wirtha w algorytmicznym języku Modula (1975–1979), a następnie „wychwycono” pozostałe języki programowania rozpowszechnione w tamtym czasie. Na przykład dobrze znane systemy programowania Turbo pascal i Turbo C.

Programowanie obiektowe. Od połowy lat osiemdziesiątych ilość kodu źródłowego przekroczyła granicę 100 000 linii. Konieczne było utworzenie nie przypadkowej kombinacji danych i algorytmów ich przetwarzania w jedną całość, ale semantyczną. Oznacza to, że konieczne było stworzenie nowego poziomu programowania modułowego, kiedy główny nacisk kładzie się na semantyczną relację struktur danych i algorytmów ich przetwarzania

dekompozycja projektu programowania modułu

1. cel, powódprogramowanie modułowe

Przy opracowywaniu dużych programów wskazane jest zebranie części podprogramów i innych zasobów, takich jak zmienne, stałe, deklaracje typów i kompilacja oddzielnie od programu głównego w postaci bibliotek zasobów lub modułów.

Przystępując do opracowywania każdego programu, należy mieć na uwadze, że z reguły tak jest duży systemw związku z tym należy podjąć środki w celu jego uproszczenia. Aby to zrobić, taki program jest rozwijany w częściach, które nazywane są modułami oprogramowania. Sama metoda tworzenia oprogramowania nazywa się programowaniem modułowym. Moduł oprogramowania to dowolny fragment opisu procesu, który został zaprojektowany jako niezależny produkt oprogramowania nadający się do wykorzystania w opisach procesów. Oznacza to, że każdy moduł programu jest programowany, kompilowany i debugowany oddzielnie od innych modułów programu, a tym samym fizycznie oddzielony od innych modułów programu. Ponadto każdy opracowany moduł oprogramowania może być włączony do różnych programów, jeśli spełnione są warunki jego stosowania zadeklarowane w dokumentacji tego modułu. Zatem moduł oprogramowania można traktować zarówno jako sposób radzenia sobie ze złożonością programów, jak i jako sposób radzenia sobie z powielaniem w programowaniu (tj. Jako sposób gromadzenia i ponownego wykorzystywania wiedzy programisty).

Programowanie modułowe obejmuje zarówno ogólne metody radzenia sobie ze złożonością procesu tworzenia programu: zapewnienie niezależności komponentów systemu, jak i wykorzystanie struktur hierarchicznych. Aby zaimplementować pierwszą metodę, formułuje się określone wymagania, które musi spełniać moduł oprogramowania, tj. ujawnia główne cechy „dobrego” modułu oprogramowania. Aby zaimplementować drugą metodę, stosuje się drzewiaste, modułowe struktury programu (w tym drzewa z połączonymi gałęziami).

2. Głównycharakterystyka modułu oprogramowania

Rozmiar moduł jest mierzony liczbą instrukcji lub wierszy, które zawiera. Moduł nie powinien być za mały ani za duży. Małe moduły prowadzą do kłopotliwej modułowej struktury programu i mogą nie pokrywać kosztów ogólnych związanych z ich projektem. Duże moduły są niewygodne do studiowania i zmieniania; mogą znacznie wydłużyć całkowity czas ponownych tłumaczeń programu podczas debugowania programu. Zwykle zalecane są moduły oprogramowania o wielkości od kilkudziesięciu do kilkuset operatorów.

Siła modułu jest miarą jego wewnętrznych powiązań. Im większa moc modułu, tym więcej połączeń może ukryć przed zewnętrzną częścią programu, a tym samym tym bardziej może przyczynić się do uproszczenia programu. Aby ocenić siłę modułu, Myers oferuje zestaw siedmiu klas modułów uporządkowanych według siły. Moduł ma najsłabszy stopień wytrzymałości, trwałe przez przypadek... To moduł, który nie ma znaczących połączeń między swoimi elementami. Taki moduł można wybrać na przykład wtedy, gdy powtórzenie tej samej sekwencji instrukcji znajduje się w różnych miejscach programu, który następnie jest formowany w osobny moduł. Konieczność zmiany tej kolejności w jednym z kontekstów może prowadzić do zmiany w tym module, co może sprawić, że użycie go w innych kontekstach będzie błędne. Ta klasa modułów oprogramowania nie jest zalecana do użytku.

Trwałe funkcjonalnie moduł to moduł, który wykonuje (realizuje) jedną określoną funkcję. Realizując tę \u200b\u200bfunkcję, taki moduł może korzystać z innych modułów. Zaleca się stosowanie tej klasy modułów oprogramowania.

Informacje trwałe moduł to moduł, który wykonuje (implementuje) kilka operacji (funkcji) na tej samej strukturze danych (obiekt informacyjny), która jest uważana za nieznaną poza tym modułem. Dla każdej z tych operacji taki moduł ma swoje własne wejście z własną formą adresowania go. Taką klasę należy traktować jako klasę modułów oprogramowania o najwyższym stopniu wytrzymałości. Moduł informacyjny może na przykład implementować abstrakcyjny typ danych.

Moduł sprzęgła jest miarą jego zależności od danych z innych modułów. Charakteryzuje się sposobem transmisji danych. Im słabsza przyczepność modułu do innych modułów, tym większa jego niezależność od innych modułów. Aby ocenić stopień przyczepności, Myers oferuje uporządkowany zestaw sześciu rodzajów przyczepności modułów. Najgorszym rodzajem łączenia modułów jest łańcuch uchwyt zawartości... Jest to konkatenacja dwóch modułów, gdy jeden z nich ma bezpośrednie linki do zawartości drugiego modułu (na przykład do stałej zawartej w innym module). Takie połączenie modułów jest niedopuszczalne. Nie zaleca się używania również uchwyt w obszarze wspólnym - to taki łańcuch modułów, gdy kilka modułów korzysta z tego samego obszaru pamięci. Jedyny typ złącza modułu, który jest zalecany do użycia nowoczesna technologia programowanie jest sprzężenie parametryczne (Konkatenacja danych Myersa) to przypadek, w którym dane są przesyłane do modułu poprzez dostęp do nich jako wartości jego parametrów lub w wyniku wywołania innego modułu w celu obliczenia jakiejś funkcji. Ten rodzaj łączenia modułów jest zaimplementowany w językach programowania przy użyciu wywołań procedur (funkcji).

Rutyna moduł - to jego niezależność od historii odwołań do niego. Moduł nosi nazwę rutyna, jeśli wynik (efekt) dostępu do niego zależy tylko od wartości jego parametrów (i nie zależy od historii wywołań do niego). Moduł nosi nazwę zależne od historiiczy wynik (skutek) dostępu do niego zależy od stanu wewnętrznego tego modułu, który ulega zmianie w wyniku poprzednich wywołań do niego. Myers nie zaleca używania modułów zależnych od historii (nieprzewidywalnych), ponieważ powodują one trudne (nieuchwytne) błędy w programach. Taka rekomendacja nie jest jednak konstruktywna, gdyż w wielu przypadkach to moduł zależny od historii jest najlepszą implementacją modułu informacyjnego. Dlatego następujące (ostrożniejsze) zalecenie jest bardziej akceptowalne:

o zawsze należy używać rutynowego modułu, jeśli nie prowadzi to do słabego (niezalecanego) sprzężenia modułu;

o moduły zależne od historii powinny być używane tylko wtedy, gdy jest to konieczne do zapewnienia sprzężenia parametrycznego;

o w specyfikacji modułu zależnego od historii zależność ta musi być jasno sformułowana w taki sposób, aby można było przewidzieć zachowanie (efekt wykonania) danego modułu przy różnych kolejnych jego wywołaniach.

W związku z tym ostatnim zaleceniem przydatne może być zdefiniowanie zewnętrznej reprezentacji (ukierunkowanej na informowanie osoby) stanów zależnych od historii modułu. W takim przypadku efekt wykonania każdej funkcji (operacji) realizowanej przez ten moduł należy opisać w kategoriach tej zewnętrznej reprezentacji, co znacznie uprości przewidywanie zachowania tego modułu.

3. Projektmoduł

Modułowa konstrukcja odnosi się do procesu dzielenia większych problemów na mniejsze, łatwiejsze do zarządzania podproblemy. Pierwszym krokiem projektowania jest podjęcie decyzji, gdzie powinna przebiegać granica między tymi podproblemami.

Aby uzyskać jak najwięcej z programowania modułowego, każdy podproblem lub moduł powinien mieć jedno wejście i jedno wyjście. W takim przypadku możesz łatwo monitorować przepływ sterowania w programie.

3. 1 Rozkład funkcjonalny

Podczas rozwiązywania problemu na etapie projektowania, pierwszym wyborem powinien być rozkład funkcjonalny, tj. rozbicie problemu na mniejsze, łatwe w zarządzaniu jednostki funkcjonalne, w których każda jednostka wykonuje ukończone, łatwe do zidentyfikowania zadanie. Istnieje wiele sposobów definiowania treści problemu. Oto kilka przykładów takich jednostek, które wykonują określone funkcje: uzyskiwanie pierwiastka kwadratowego z liczby; wykonywanie wszystkich operacji w odniesieniu do określonego urządzenia, takich jak operacje we / wy dysku, operacje we / wy klawiatury; wykonywanie wspólnej grupy działań w określonym czasie, takich jak inicjowanie obszarów danych; oraz jednostki, które oddziałują sekwencyjnie lub mają wspólne elementy danych, takie jak odczytywanie danych z klawiatury i konwertowanie ich na wartości całkowite.

Obecnie w programowaniu wysokopoziomowym najczęściej podejmowane decyzje to te, które przedstawiają najlepszy sposób wykorzystania segmentacji programów. Często okazuje się, że niektóre moduły są połączone za pomocą jednego zestawu kryteriów, a inne za pomocą innego. Każdy moduł powinien zawierać łatwe do zrozumienia sekcje programu.

3.2 Minimalizacja liczby przesyłanych parametrów

Czasami okazuje się, że po zdefiniowaniu modułów programu utworzyłeś coś nieporęcznego i niezręcznego. Dzieje się tak często, gdy moduły, aby wykonać przypisane im zadania, wymagają dostępu do dużej ilości danych. Najczęściej może się to łatwo zdarzyć, jeśli moduł jest przypisany do wykonywania kilku opcji. Aby poznać stan programu w danym momencie, moduł musi akceptować wiele różnych zmiennych. Jeśli tak jest i okaże się, że moduł przyjmuje dużą liczbę parametrów, należy odpowiedzieć na dwie grupy pytań:

o Czy ten moduł próbuje wykonać więcej niż jedną funkcję? Czy moduł wymaga parametrów używanych w sekcjach nie modułowych? Jeśli odpowiedzi na te pytania są pozytywne, należy ponownie przejść do dalszej segmentacji tego modułu.

o Czy moduł jest widokiem funkcjonalnym? Czy osoba dzwoniąca i odbiorca faktycznie należą do tej samej funkcji? Jeśli tak, złóż je w jednym module, nawet jeśli wynikowy moduł jest zbyt duży. Następnie spróbuj ponownie podzielić moduł na różne sposoby.

Segmentacja modułów w widoku funkcjonalnym często występuje, gdy programista odkrywa, że \u200b\u200bdwie sekcje programu są identyczne lub bardzo do siebie podobne. Programista następnie próbuje stworzyć z nich jeden moduł. Nie jest to programowanie modułowe, ponieważ wynikowy moduł ma niefunkcjonalne połączenie.

Jeśli w trakcie projektowania okaże się, że nie da się nic zrobić, aby uniknąć stosowania dużej liczby odniesień do danych lub przekazywania etykiet parametrów, należy cofnąć się do początku projektowania i sprawdzić poprawność postawionego problemu.

3.3 Minimalizacja liczby potrzebnych połączeń

Jedną z istotnych zalet programowania modułowego jest to, że program na poziomie podstawowym można bardzo często zaprojektować tak, aby był czytany jako sekwencja wywoływanych procedur. Fakt ten znacznie zwiększa „zrozumiałość” programu, gdyż czytelnik może zapoznać się z jego głównym przepływem i działaniem po przeczytaniu zaledwie jednej lub dwóch stron kodu programu. Jednak ta funkcja może mieć również wady. Jedna z wielu czołowych statystyk dotyczących programowania mówi, że 90% czasu wykonywania typowych programów zajmuje 10% kodu programu. Oznacza to, że jeśli te 10% zawiera dużą liczbę połączonych wywołań procedur, to całkowity czas spędzony na zarządzaniu wykonywaniem programu może stać się przeszkodą nie do pokonania w stosowaniu tego podejścia.

Dodatkowy czas spędzony na obliczeniu prawidłowego adresu w treści modułu może spowolnić wykonanie określonego modułu niż w przypadku wąsko zakodowanego określonego programu.

Wniosek

Duże programy są zwykle tworzone i debugowane w częściach. W tym przypadku celowe jest, aby każda taka część, zwana podprogramem, została zaprojektowana tak, aby mogła być użyta przy rozwiązywaniu podobnego podzadania w tym samym programie lub nawet przy rozwiązywaniu innych problemów. Borland Pascal implementuje dwa rodzaje procedur: procedury i funkcje.

Moduł to samodzielny, skompilowany zbiór zasobów oprogramowania do użytku przez inne moduły i programy.

Wszystkie zasoby modułu są podzielone na dwie grupy: zewnętrzne - przeznaczone do użytku przez inne jednostki oprogramowania oraz wewnętrzne - zasoby robocze tego modułu.

Nowoczesna technologia tworzenia oprogramowania, w tym obsługi systemy Windows, opiera się na koncepcji programowania zorientowanego obiektowo, która zachowuje ujednolicone podejście do danych i programów. U podstaw wszystkiego leży koncepcja obiektu, który łączy zarówno algorytmy, jak i dane przetwarzane przez te algorytmy. W rezultacie upraszcza się nie tylko tworzenie programów, ale także technologię użytkownika, który ma możliwość korzystania z wizualnych narzędzi graficznych i różnych wskazówek podczas pracy w trybie interaktywnym (dialog).

Wysłany na Allbest.ru

Podobne dokumenty

    Główne zalety programowania modułowego. Wyodrębnienie procedury: wprowadzenie tablicy z konsoli, wyświetlenie tablicy na ekranie, informacje o autorze i stanie rozwiązanego problemu przed i po przetworzeniu. Hierarchia procedur, charakterystyka przeznaczenia modułów.

    streszczenie dodane 29.01.2016

    Charakterystyka programowania modułowego: procedury i funkcje, moduły i ich struktura, otwarte tablice i łańcuchy, nietypowe parametry. Metody przekazywania parametrów do podprogramów w Borland Pascal. Programowanie obiektowe.

    test, dodano 28.04.2009

    Istota programowania w środowisku Delphi 7 i jego podstawowe możliwości graficzne. Struktura autonomicznie skompilowanego modułu programu i jego zasady. Podstawowe techniki pracy z procedurami graficznymi, budowanie łuku, koła i elipsy.

    praca semestralna, dodano 16.12.2011

    Pojawienie się pierwszych komputerów i pojawienie się programowania „spontanicznego”. Strukturalne podejście do dekompozycji złożonych systemów. Rozwój programowania modułowego i obiektowego. Cechy podejścia komponentowego i technologie CASE.

    prezentacja dodana 14.10.2013

    Historia powstania tradycyjnej technologii programowania. Cele i przedmiot programowanie strukturalnejako jeden z największych postępów w technologii programowania. Podprogram, rodzaje struktur sterujących. Modułowa koncepcja programowania.

    prezentacja dodana 11.05.2016

    Przedmiotem badań są nowoczesne metody wytwarzania oprogramowania, takie jak programowanie obiektowe i projektowanie wizualne, a także programowanie strukturalne i modułowe. C ++ to uniwersalny język programowania. Kluczowe idee.

    praca semestralna, dodano 01.10.2009

    Dlaczego C ++. Pojawienie się i ewolucja języka C ++. Porównanie języków C ++ i C. Wydajność i struktura. Programowanie proceduralne. Programowanie modułowe. Abstrakcja danych. Programowanie obiektowe. Ulepszony S.

    streszczenie, dodano 06.03.2004

    Przegląd technologii i systemów systemów informacji geograficznej. Projekt systemowy i funkcjonalny modułu oprogramowania, jego wykonanie w środowiskach programistycznych Visual C ++ 6.0, Qt 3.3.3. Studium wykonalności tego procesu.

    praca dyplomowa, dodano 13.03.2011

    Projektowanie modułu oprogramowania w środowisku programistycznym Borland Delphi 7.0. Schematy algorytmów rozwiązywania problemów z tematów „Zmienne i ciągi symboliczne”, „Tablice”, „Praca z plikami”, „Tworzenie animacji”. Wykonanie modułu programu, kodu programu.

    raport z ćwiczeń, dodano 21.04.2012

    Projekt system informacyjny... Analiza języków programowania i istniejące rozwiązania do administrowania systemem zarządzania bazą danych. Opracowanie modułu interakcji i struktury programu. Moduły autoryzacyjne i połączenia z bazami danych.

W każdym zawodzie, nie tylko programistycznym, w trakcie projektu doświadczasz różnych stanów emocjonalnych:

  • Po pierwsze, jest entuzjazm dla perspektyw i możliwości.
  • Potem przychodzi dreszczyk emocji. Pierwsze błędy i trudności tylko cię prowokują, zmuszając mózg i wyobraźnię do pracy na maksa.
  • Następnie koncentracja spada. W pewnym momencie przestajesz zwracać uwagę na ostrzeżenia i drobne błędy, odkładając rozwiązanie tych problemów na później.
  • W rezultacie tracisz motywację. Naprawiasz jeden błąd - pojawiają się trzy. Próbujesz dodać nową funkcję, ale wyrzucasz pomysł do kosza, ponieważ nie chcesz spędzać nad nim dużo czasu.

Niektórzy uważają, że to normalne: warto zaakceptować i przeżyć ten cykl za każdym razem. Tak naprawdę wszystko jest trochę prostsze, a rozwiązanie nie leży w dziedzinie psychologii, ale w podejściu do tworzenia kodu.

Klasyczny problem programistyczny

W literaturze zachodniej istnieje termin „wielka kula błota” na określenie architektury programu. Przetłumaczmy to dosłownie. Graficznie „dużą kulę brudu” można przedstawić w postaci punktów na okręgu, symbolizujących elementy funkcjonalne, oraz linii prostych - połączeń między nimi:

Brzmi jak twoje oczy przed przesłaniem projektu, prawda?

Jest to ilustracja trudności, z jaką musisz pracować, ile linków należy wziąć pod uwagę, jeśli wystąpi błąd.

Programowanie nie jest wyjątkową dyscypliną: tutaj możesz i powinieneś zastosować doświadczenie z innych dziedzin. Weźmy na przykład komputer. Ich producenci nie myślą o różnorodności zadań, które rozwiązuje użytkownik, a tym bardziej, że nie alokują dla każdego małego procesora i pamięci. Komputer to po prostu zbiór niezależnych, złożonych obiektów, które są połączone w jednej obudowie za pomocą złączy i przewodów. Obiekty nie są unikalne, nie są zoptymalizowane specjalnie dla Ciebie, a mimo to znakomicie wykonują swoją pracę.

W programowaniu są dokładnie takie same rozwiązania. Na przykład biblioteki. Pomagają uniknąć marnowania cennego czasu na odkrywanie koła na nowo. Biblioteki nie sprawdzają się jednak w przypadku zadań prywatnych - ich tworzenie zajmie dużo czasu, a przy pojedynczej powtarzalności wydajność dąży do zera.

W takim przypadku bardziej przydatne jest odwołanie się do modułów. Moduł to logicznie kompletny fragment kodu, który ma określony cel funkcjonalny. Do interakcji modułów stosuje się metody, które nie pozwalają na zmianę parametrów i funkcjonalności. Zalety programowania modułowego są oczywiste:

  • Przyspiesz rozwój.
  • Zwiększona niezawodność.
  • Uproszczenie testowania.
  • Wymienność.

Programowanie modułowe jest niezwykle efektywne w rozwoju grupy, gdzie każdy pracownik może skoncentrować się tylko na swoim froncie pracy i nie patrzeć wstecz na decyzje współpracowników. Jednak w indywidualnym podejściu uzyskuje się co najmniej opisane powyżej zalety.

Ale to nie jest takie proste.

Modułowe problemy programistyczne

Sama idea wykorzystania modułów nie upraszcza znacznie kodu, ważne jest, aby zminimalizować liczbę bezpośrednich połączeń między nimi. I tu dochodzimy do koncepcji odwrócenia kontroli (IoC). Uproszczony - jest to zasada programowania, w której poszczególne elementy kodu są maksymalnie odizolowane od siebie. Oznacza to, że szczegóły jednego modułu nie powinny wpływać na implementację innego. Osiąga się to za pomocą interfejsów lub innych widoków, które nie zapewniają bezpośredniego dostępu do kodu modułowego.

W Życie codzienne jest wiele takich przykładów. Nie musisz dzwonić do pilota, aby kupić bilet lotniczy lub dowiedzieć się o godzinie odlotu. Aby pić mleko, nie musisz iść do wioski ani do fabryki i stanąć nad swoją duszą przy krowie. Zawsze są w tym pośrednicy.

Istnieją trzy główne implementacje w programowaniu modułowym:

  • Wstrzyknięcie zależności. Sposób, w jaki każdy element ma własny interfejs, interakcja modułów odbywa się za pośrednictwem interfejsów.
  • Metoda fabryczna. Opiera się na istnieniu określonego przedmiotu przeznaczonego do tworzenia innych obiektów. Innymi słowy, wprowadzenie do programu prototypu, który łączy cechy wspólne dla większości obiektów. Nie ma bezpośredniej interakcji między modułami, wszystkie parametry są dziedziczone z „fabryki”.
  • Sposób obsługi. Tworzony jest jeden wspólny interfejs, który jest buforem do interakcji z obiektami. Podobną funkcję w prawdziwym życiu pełnią call center, sklepy, platformy reklamowe itp.

Chociaż pierwsza implementacja IoC jest najczęściej używana, pozostałe dwie są lepsze dla pierwszych kroków w programowaniu modułowym. Powodem jest to, że proste tworzenie interfejsów ogranicza tylko dostęp do modułów, a aby zmniejszyć złożoność kodu, należy również zmniejszyć liczbę łączy. Interfejsy, które losowo odwołują się do innych interfejsów, tylko komplikują kod.

Aby rozwiązać ten problem, musisz opracować architekturę kodu. Z reguły jest podobna do struktury plików dowolnej aplikacji:

Zatem wsparcie dla zasad programowania modułowego, odwrócenia sterowania i przejrzystej architektury aplikacji pomoże upiec trzy pieczenie na jednym ogniu:

  1. Zapewnij wyraźną separację kodu funkcjonalnego. Gdy wystąpią błędy, możesz szybko zidentyfikować źródło, a poprawki nie doprowadzą do nowych błędów.
  2. Zminimalizuj liczbę linków. Uprości to rozwój dzięki outsourcingu różnych modułów kilku programistom. Lub możesz niezależnie zaprojektować każdy blok bez względu na inne, co również oszczędza czas i wysiłek.
  3. Utwórz hierarchię z jasną linią dziedziczenia. Zwiększa to niezawodność kodu, ponieważ testowanie jest łatwiejsze, a wyniki zawierają więcej informacji.

Przestrzeganie zasady modułowości w dużych projektach pozwoli zaoszczędzić czas i nie rozleje początkowego entuzjazmu. Co więcej, w końcu będziesz mógł skupić się na tym, co najciekawsze - implementacji oryginalnych pomysłów w kodzie. Ale właśnie tego każdy z nas szuka w programowaniu.

Podstawową zasadą programowania modułowego jest zasada dziel i rządź. Programowanie modułowe to organizacja programu jako zbioru małych, niezależnych jednostek zwanych modułami, których struktura i zachowanie podlega pewnym regułom.

Zwróć uwagę, że konieczne jest rozróżnienie pomiędzy użyciem słowa „moduł”, gdy mamy na myśli konstrukcję syntaktyczną języków programowania (jednostka w Object Pascal), a gdy mamy na myśli jednostkę podziału dużego programu na osobne bloki (które można zaimplementować zarówno w postaci procedur, jak i Funkcje).

Zastosowanie programowania modułowego ułatwia testowanie programu i znajdowanie błędów. Podzadania zależne od sprzętu można ściśle oddzielić od innych podzadań, co poprawia przenośność tworzonych programów.

Proces zwiększania wydajności programów jest uproszczony, ponieważ krytyczne czasowo moduły mogą być wielokrotnie przerabiane niezależnie od innych. Ponadto programy modułowe są znacznie łatwiejsze do zrozumienia, a moduły mogą być używane jako bloki konstrukcyjne w innych programach.

Termin „moduł” w programowaniu zaczął być używany w związku z wprowadzeniem modułowych zasad w tworzeniu programów. W latach 70. przez moduł rozumiano dowolną procedurę lub funkcję napisaną zgodnie z określonymi zasadami. Na przykład „Moduł powinien być prosty, zamknięty (niezależny), obserwowalny (od 50 do 100 linii), realizujący tylko jedną funkcję problemu, mający tylko jedno wejście i tylko jeden punkt wyjściowy”. Nie było jednak ogólnie przyjętych wymagań, a moduł był bardzo często nazywany dowolną procedurą do rozmiaru 50 linii.

Parnas jako pierwszy sformułował w mniej lub bardziej klarowny sposób główne właściwości modułu programu: „Aby napisać jeden moduł, wiedza o tekście drugiego powinna być minimalna”. A zatem! Parnas był pionierem koncepcji informacji! Ukrywanie się w programowaniu.

Zgodnie z definicją Parnassusa, modułem może być dowolna odrębna procedura (funkcja), zarówno na najniższym poziomie hierarchii (poziom implementacji), jak i na najwyższym poziomie, na którym występują tylko wywołania innych procedur modułu.

Jednak tylko takie konstrukcje składniowe, jak procedura i funkcja istniejące w językach lat 70., nie były w stanie zapewnić wiarygodnego ukrywania informacji, ponieważ wpływają na nie zmienne globalne, których zachowanie w złożonych programach jest często trudne do przewidzenia. Ten problem można rozwiązać jedynie poprzez opracowanie nowej składni, na którą nie mają wpływu zmienne globalne. Ten projekt został utworzony i nazwany modułem.

Po raz pierwszy wyspecjalizowana struktura składniowa modułu została zaproponowana przez N. Wirtha w 1975 roku i włączona do jego nowego języka Modula. W tym samym roku dokonano eksperymentalnej implementacji języka Modula. Po kilku zmianach, ten nowy język został ostatecznie zaimplementowany w 1977 roku i nazwany Modula-2. Następnie podobne konstrukcje, z pewnymi różnicami, zostały włączone do innych języków programowania: Pascal Plus (Welch and Bastard, 1979), Ada (1980), Turbo Pascal wersja 4.0 i inne.

Początkowo założono, że przy wdrażaniu złożonych systemów oprogramowania moduł powinien być używany wraz z procedurami i funkcjami jako struktura, która jednoczy i niezawodnie ukrywa szczegóły realizacji określonego podzadania. Jednak w języku Borland (Turbo) Pascal nie wszystkie teoretyczne możliwości modułu zostały zaimplementowane. W szczególności język ten nie obsługuje jednostek wewnętrznych (podobnie jak wewnętrzne procedury i funkcje), import nie jest wystarczająco elastyczny (klauzula używa), co nie pozwala na selektywne importowanie obiektów z innych jednostek. Ta okoliczność, a także fakt, że wraz z wyglądem komputery osobiste grono programistów dramatycznie się rozszerzyło (a to znacznie obniżyło średni poziom szkolenia teoretycznego programistów), doprowadziło do tego, że przy tworzeniu aplikacji na tym języku, poprzednie moduły Object Pascal, wersja języka, były wykorzystywane głównie jako środek do tworzenia problematycznych bibliotek procedur i funkcji. I tylko najbardziej utalentowani programiści wykorzystali pełną moc tej konstrukcji językowej do tworzenia struktury swoich projektów. W języku Object Pascal odnotowane ograniczenia dotyczące implementacji modułów pozostały jednak ze względu na to, że w środowisku Delphi każda forma z konieczności odpowiada własnemu modułowi, a pozawizualne działania algorytmiczne są również z reguły wykonywane w postaci oddzielnych modułów, konstrukcja „modułu” zaczęła być stosowana zgodnie z jej pierwotnym przeznaczeniem wszyscy programiści, niezależnie od ich kwalifikacji.

Delphi ma wbudowane wsparcie dla koncepcji programowania modułowego w języku Object Pascal, co zachęca do progresywnego i solidnego stylu programowania z szerokim wykorzystaniem modułów, a tym samym odróżnia Delphi i Object Pascal od innych nowoczesnych narzędzi do tworzenia aplikacji.

W związku z tym liczbę modułów w projekcie należy określić poprzez dekompozycję przydzielonego zadania na niezależne podzadania. W skrajnym przypadku moduł może być użyty nawet do umieszczenia w nim tylko jednej procedury, jeśli konieczne jest zagwarantowanie, że wykonywana przez niego akcja lokalna będzie niezależna od wpływu innych części programu na jakiekolwiek zmiany w kodzie projektu. W szczególności takie wykorzystanie modułu jest typowe dla klasy problemów czasu rzeczywistego, w której kryterium rzetelności i przewidywalności zachowania programu jest kluczowe.

Rozważmy inne teoretyczne pytanie związane z wykorzystaniem programowania modułowego. To pytanie dotyczy kształtu projektu modułowego.

Nadanie hierarchicznej strukturze projektu modułowego dobrej formy usprawnia proces jego rozwoju. Liczba modułów, które są łączone przez moduł oraz liczba modułów, które go łączą, mają wpływ na złożoność projektu. Jordan (Yourdon) nazwał liczbę podłączonych modułów z danego modułu, zakres lub szerokość modułu sterującego. Wraz z duży rozmiar bardzo mała lub bardzo duża szerokość sterowania jest oznaką słabej modułowości. Ogólnie szerokość kontrolna modułu nie powinna przekraczać 10. Liczba ta jest związana z „magiczną” liczbą 7, która opiera się na przepisach psychologii, w szczególności na teorii „kawałków” („kawałków”) informacji. Ludzka pamięć krótkotrwała ma ograniczone możliwości przechowywania „fragmentów” informacji. Eksperymenty psychologiczne wykazały, że zdolność naszej pamięci krótkotrwałej mieści się w granicach 5-11 „kawałków” (średnio - 7). Potrafi jednocześnie obsługiwać około 7 „informacji”. Kiedy osoba przekracza ten limit, jest bardziej podatna na błędy. Porządkowanie informacji z podziałem na odpowiednie części jest ważnym działaniem dla efektywnego wykorzystania pamięci krótkotrwałej danej osoby i dla lepszego zrozumienia materiału. Ludzie w wielu sytuacjach życiowych dokonują takiej reorganizacji nieświadomie. Jednak programista może sobie pomóc celowo nie dopuszczając szerokości sterowania modułem, która znacznie przekracza liczbę 7.

Jeśli chodzi o programowanie w środowisku Delphi, to rozważane rekomendacje co do formy projektu modułowego należy przypisać głównie modułom tworzonym przez użytkownika, ponieważ Delphi automatycznie generuje główną część kodu związaną z przetwarzaniem formularzy, a programista aplikacji nie musi tak naprawdę myśleć o standardowych wtyczkach.

Ponadto te same zasady należy stosować przy projektowaniu hierarchii klas. Na przykład w hierarchii predefiniowanych klas Object Pascal, tylko dwie klasy, TObject i Exception, mają znacznie bardziej bezpośrednie klasy potomne niż 7. Można to wyjaśnić globalną podstawową rolą TObject i „wyliczalną” naturą klasy Exception. W przypadku trzech innych klas liczba ta mieści się w przedziale 8–9, a pozostałe klasy mają mniej niż 7 bezpośrednich potomków.

Aby zmniejszyć złożoność system oprogramowania jest podzielony na wiele małych, wysoce niezależnych modułów. Moduł to zamknięty program, który można wywołać z dowolnego innego modułu w systemie. Jest to fragment kodu programu, który jest elementem składowym fizycznej struktury systemu. Zazwyczaj moduł składa się z części interfejsu i części implementacyjnej. Moduły można tworzyć w różnych językach programowania i kompilować oddzielnie. Wysoki stopień niezależności modułów systemu oprogramowania można osiągnąć za pomocą dwóch metod optymalizacji: wzmacniania połączeń wewnętrznych w każdym module i osłabiania relacji między nimi. Programowanie modułowe pojawiło się na początku lat 60. XX wiek ... Podczas tworzenia systemów oprogramowania zapewnia następujące korzyści:

  • opracowywanie i wdrażanie systemów oprogramowania są uproszczone;
  • istnieje możliwość jednoczesnej (równoległej) pracy wykonawców, co pozwala na skrócenie czasu tworzenia systemu oprogramowania;
  • konfiguracja i modyfikacja PS jest uproszczona;
  • istnieje wiele naturalnych punktów kontrolnych służących do monitorowania postępów w realizacji projektu;
  • możesz tworzyć biblioteki najpopularniejszych programów;
  • ułatwia czytanie i zrozumienie programu;
  • dostępne są bardziej kompleksowe testy;
  • procedura załadunku w baran duży PS (wydajność dystrybucji programu na stronach podczas pracy w pamięci wirtualnej zależy od sposobu jej podziału na moduły).

Oprócz tych zalet istnieją pewne wady, które mogą prowadzić do wzrostu kosztów systemu oprogramowania:

  • czas realizacji programu może się wydłużyć;
  • rozmiar wymaganej pamięci może się zwiększyć;
  • czas kompilacji i ładowania może się wydłużyć;
  • problemy związane z organizacją interakcji intermodularnych mogą być dość złożone.

Wymieńmy główne właściwości i wymagania dotyczące modułów.

  • 1. W rezultacie powstaje moduł oddzielna kompilacja lub jest częścią wspólnego wyniku kompilacji. Może się aktywować system operacyjny lub być podprogramem wywoływanym przez inny moduł.
  • 2. Zawartość modułu może być odnosić się używając jego imienia.
  • 3. Moduł powinien zwrócić kontrolę do tego, który go zawołał.
  • 4. Moduł może adres do innych modułów.
  • 5. Moduł musi mieć jedno wejście i jedno wyjście. Czasami program z wieloma wejściami może być krótszy i zajmować mniej miejsca w pamięci. Jednak doświadczenie z programowaniem modułowym pokazało, że programiści wolą mieć kilka podobnych modułów, ale nie używać wielu wejść i wyjść w jednym module. Wynika to z faktu, że unikalność wejścia i wyjścia gwarantuje zamknięcie modułu i upraszcza obsługę systemu oprogramowania.
  • 6. Moduł relatywnie mały. Wielkość modułu wpływa na stopień niezależności elementów programu, łatwość czytania i testowania. Stwierdzono, że małe moduły umożliwiają budowanie programów, które są łatwiejsze do modyfikacji. Takie moduły są częściej używane, ułatwiają ocenę i zarządzanie rozwojem i mogą być polecane zarówno doświadczonym, jak i niedoświadczonym programistom. Kryteria wysokiej wytrzymałości i minimalnej przyczepności mogłyby zostać spełnione poprzez zaprojektowanie programu jako kilku dużych modułów, ale jest mało prawdopodobne, aby w ten sposób osiągnięto wysoki stopień niezależności. Z reguły moduł powinien zawierać od 10 do 100 operatorów języków wysokiego poziomu (do 200 w niektórych publikacjach).

Z drugiej strony projektowanie małych modułów trwa dłużej i wolniej działają. Wszystkie składają się z większej liczby zdań źródłowych, wymagają więcej dokumentacji i mogą być mniej przyjemne dla programisty.

  • 7. Moduł nie powinien przechowywać historii swoich wywołań w celu kontrolowania jego działania. Taki moduł nosi nazwę możliwy do przewidzenia. Moduł, który śledzi swoje stany podczas kolejnych wywołań, nie jest przewidywalny. Wszystkie moduły PS muszą być przewidywalne, tj. nie powinien przechowywać żadnych informacji o poprzednim wywołaniu. Podstępne, subtelne, zależne od czasu błędy występują w programach, które próbują wielokrotnie wywoływać nieprzewidywalny moduł.
  • 8. Struktura podejmowania decyzji w module muszą być zorganizowane w taki sposób, aby te moduły, na które podjęta decyzja miała bezpośredni wpływ, były podporządkowane (wywoływalne) w stosunku do modułu podejmującego decyzję. W związku z tym zwykle można wykluczyć przekazywanie specjalnych parametrów wskaźnikowych reprezentujących decyzje, które należy podjąć, a także podejmować decyzje wpływające na sterowanie programem na wysokim poziomie w hierarchii programów.
  • 9. Minimalizowanie dostępu do danych. Ilość danych, do których może odwoływać się moduł, należy ograniczyć do minimum. Eliminacja łączenia według obszaru wspólnego, danych zewnętrznych i formatu jest dobrym krokiem w tym kierunku. Projektant powinien spróbować wyodrębnić informacje o określonej strukturze danych lub rekordzie bazy danych w pojedynczym module (lub niewielkim podzbiorze modułów) - być może przy użyciu modułów odpornych na informacje.
  • 10. Procedury wewnętrzne. Wewnętrzna procedura lub podprogram jest zamkniętym podprogramem, który jest fizycznie umieszczony w module wywołującym. Tych procedur należy unikać z kilku powodów. Procedury wewnętrzne są trudne do wyodrębnienia na potrzeby testowania i nie można ich wywołać z modułów innych niż te, które je zawierają. To nie pasuje do idei ponownego wykorzystania. Oczywiście istnieje opcja alternatywna - dołączenie kopii procedury wewnętrznej do wszystkich modułów, które tego potrzebują. Jednak często prowadzi to do błędów (kopie często stają się „nie do końca dokładne”) i komplikuje obsługę programu, ponieważ w przypadku zmiany procedury wszystkie moduły muszą zostać ponownie skompilowane.

Po tym, jak początkujący embedder mrugnie diodą LED, z pewnością zdecyduje się napisać coś poważniejszego i jak każdy początkujący będzie miał tylko jedno pragnienie „aby wszystko działało szybciej !!!”. Próbując się w taki sposób przekonać, zapisze wszystko do jednego pliku, nie myśląc o strukturze programu, ale po chwili, gdy część planu zostanie zrealizowana, okaże się, że im większy program, tym trudniej coś w nim znaleźć. To doprowadzi go do przekonania, że \u200b\u200bprogram musi mieć strukturę i przejdzie do Internetu, aby zobaczyć, jak inne programy osadzające rozwiązują ten problem. Po przyjrzeniu się, jak wyglądają programy napisane przez innych ludzi, doszedł do wniosku, że program jest podzielony na pliki, które reprezentują kompletne jednostki logiczne, część funkcji i zmienne są przenoszone do nagłówka, i wiele więcej. Wszystko powyższe jest moim doświadczeniem, ale wszyscy początkujący idą tą samą drogą, więc opiszę tutaj, z czym sam się spotkałem.

Załóżmy, że mamy program, który wyświetla temperaturę do wyświetlacz LCD a co do wyświetlacza lcd, co do czujnika temperatury ( ds18b20), potrzebna jest inicjalizacja, a także funkcje do pracy z nimi. Dlatego logiczne byłoby utworzenie dwóch oddzielne pliki lcd.c i ds18b20.c, który będzie zawierał funkcje niezbędne do pracy. Takie pliki zwane modułami, Chciałbym zaznaczyć, że każdy moduł jest niezależnym, jednostka logiczna, którą można skompilować niezależnie od reszty programu... Podczas kompilowania modułu kompilator utworzy z niego plik obiektowy.

Następne pytanie, które się pojawia, ponieważ moduł jest niezależną strukturą, możemy powiedzieć „ rzecz sama w sobie”, Wtedy ona nie ma połączenia ze światem zewnętrznym i nie jesteśmy z tego zadowoleni. Aby połączyć moduły ze światem zewnętrznym, użyj pliki nagłówkowe, zwane także nagłówkami / nagłówkami i mają rozszerzenie .h... Możesz nazwać nagłówek dowolnie, ale jest to wygodniejsze, aby jego nazwa pokrywała się z nazwą modułu, lcd.h i ds18b20.h, Muszę też powiedzieć, że wszystkie pliki dołączane ( #zawierać) wygodnie jest umieścić go w nagłówku i podłączyć tylko na początku modułu.
Gdy nie było nagłówka, początek lcd.c wyglądał tak
# zdefiniować F_CPU 8000000UL #include #zawierać
a po utworzeniu nagłówka wyglądało to tak
#zawierać

Ale wtedy pojawia się kolejne pytanie, co powinno być zawarte w nagłówku?
W nagłówku należy umieścić prototypy funkcji, które mogą być potrzebne w innych modułach programu. Prototyp funkcji tylko deklaruje funkcję i nie zawiera treści funkcji, ale patrząc na niego, możesz znaleźć nazwę funkcji, liczbę, typ argumentów i typ danych zwracanych.
W pliku lcd.h
void lcd_init (void); void lcd_write_symbol (symbol znaku); void lcd_write_string (char * str); void lcd_clear (void);
W pliku ds18b20.h zostaną ogłoszone następujące prototypy:
void ds18b20_init (void); uint8_t ds18b20_get_temperature (void);

Jeśli chodzi o makra, możesz wyjąć makra odpowiedzialne za wykonywanie kompilacji warunkowej
#define MAKE_CALIBRATION // odkomentuj dla kalibracji
Gdzieś w kodzie znajduje się konstrukcja, która jest wykonywana, jeśli poprzednia linia nie jest komentowana
#ifdef MAKE_CALIBRATION touch_x - \u003d 300; touch_x \u003d 240 - touch_x / ((Xmax-Xmin) / 240); touch_y - \u003d 350; touch_y \u003d 320 - touch_y / ((Ymax-Ymin) / 320); #endif
Możesz także ustawić makra odpowiedzialne za dobór pinów, do których będą podłączone peryferia
#define D0 PORTA // więc dane są przesyłane przez 16-bitową szynę, #define D7 PORTD // do tego używamy dwóch portów

Ale jednocześnie nie jest konieczne umieszczanie w nagłówku tego, co nie jest potrzebne w innych modułach:

  • makra takie jak
    # zdefiniować (LCD_PIN i 0X80) check_busy_flag
  • zmienne, które mają być używane tylko wewnątrz modułu z słowo kluczowe statyczny
  • zmienne z kwalifikatorem zewnętrzny
  • prototypy funkcji, które są potrzebne do niektórych działań pośrednich, na przykład funkcja, która tłumaczy liczbę na Format BCD

Teraz kilka słów o podłączaniu nagłówków przy programowaniu mikrokontrolerów AVR prawie wszystkie moduły zawierają nagłówek do pracy z portami I / O.
#include avr / io.h
Oznacza to, że łączy się z lcd.h i w ds18b20.h, jeśli teraz włączymy te dwa nagłówki do głównego pliku programu, to avr / io.h połączy się dwa razy, chociaż jeden wystarczył... Aby uniknąć takiej sytuacji i nie podłączamy nagłówka dwukrotnie użyj # uwzględnij strażnikówktóry wygląda tak.
#ifndef _ENCODER_H_ #define _ENCODER_H_ // udekoruj jak normalny nagłówek #endif
Ta konstrukcja pozwala preprocesorowi określić, że dany nagłówek jest już zawarty w programie i nie włączać go ponownie. Możesz przeczytać więcej na ten temat.
Możesz również ograniczyć liczbę połączeń plików do jednego za pomocą konstrukcji
#pragma Once // udekoruj jak zwykły nagłówek
Korzyści użytkowania #pragma raz zamiast # uwzględnij strażników można przeczytać.
Nawiasem mówiąc, możesz łączyć nie tylko nagłówki, ale także pliki z rozszerzeniem .zJeśli to konieczne
#include „font.c”
W tym przypadku plik czcionek jest podłączony do wyświetlania liter na wyświetlaczu TFT.
To wszystko, myślę, że to minimum, które każdy początkujący programista mikrokontrolerów musi wiedzieć.

DZWON

Są tacy, którzy czytają tę wiadomość przed tobą.
Zapisz się, aby otrzymywać najnowsze artykuły.
E-mail
Imię
Nazwisko
Jak chcesz przeczytać The Bell
Bez spamu