© Krzysztof Barteczko, PJWSTK 2012 Programowanie, Java i Groovy © Krzysztof Barteczko, PJWSTK 2012
Co robi komputer? - wykonuje programy Program jest zakodowaną sekwencją instrukcji, które ma wykonać procesor (lub za jego pośrednictwem inne elementy sprzętowe). Zapis kodu programu w języku maszynowym jako ciągu liczb w w systemie binarnym: 10001010 10001000 00000001 11001010 ..... Bit - najmniejsza ilość informacji, którą może operować komputer - cyfra 1 lub 0 w binarnej reprezentacji liczby. Bajt = 8 bitów = najmniejsza częścią słowa maszynowego, dostępną bezpośrednio dla procesora. Pół bajta = cyfra w systemie 16-kowym 0-9 A=10, B=11, C=12 D=13, E=14, F=15
Kod maszynowy a assemblery 5830 D252 5A30 D256 5030 D260 Ułatwienie: assembler - język symbolicznego zapisu instrukcji maszynowych danego procesora. Bardziej zrozumiały dla nas zapis, tłumaczony na język maszynowy (ciąg cyfr binarnych) przez translatory. Jednak programowanie w języku assemblera wciąż uciążliwe i obarczone szczególami tecnicznymi.
Potrzeba języków wysokiego poziomu Przecież chodzi o dodanie do siebie dwóch liczb (oznaczonych X i Y) i zapisanie wyniku jako Z. Z = X + Y Tak można pisać w językach wysokiego poziomu, które w swojej składni i semantyce konsolidują wiele prostych instrukcji assemblerowych, ukrywają ich techniczne szczegóły, i - w odróżnieniu od assemblerów - są składniowo niezależne od procesora. Wymagają od programisty znajomości składni i semantyki. Ale samo to nie wsytarcza aby pisać sensowne programy.
Algorytmy Skoro programy służą do rozwiązywania jakichś problemów, realizacji zadań, to punktem wyjścia programowania powinno być sformułowanie algorytmu. ALGORYTM to przepis postępowania prowadzący do rozwiązania określonego zadania; zbiór poleceń dotyczących pewnych obiektów (danych) — ze wskazaniem kolejności, w jakiej mają być wykonane; wykonawcą jest układ, który na sygnały reprezentujące polecenia reaguje ich realizowaniem — może nim być człowiek lub urządzenie automatyczne, np. komputer. Algorytmy możemy wyrazić w różny sposób: w języku naturalnym, graficznie - w postaci schematu blokowego lub też w tzw. pseudo-kodzie (wybranym języku opisu algorytmów, który jest niezależny od konkretnych, dostępnych języków programowania).
Schematy blokowe Przykład wyliczenia podatku:
Algorytmy, programy, języki Podsumujmy: programy piszemy po to, by rozwiązać problem, zanim napiszemy program, musimy opracować algorytm, program jest zapisem algorytmu oraz danych w konkretnym języku programowania, po to by program mógł być wykonany przez komputer jego zapis musi być przetłumaczony na język instrukcji rozumianych przez procesor; takiego tłumaczenia dokonują specjalne programy nazywane translatorami, kompilatorami i interpreterami. PROGRAM - to skonkretyzowane sformułowanie abstrakcyjnego algorytmu na podstawie określonej reprezentacji i struktury danych.
Programowanie PROGRAMOWANIE JEST PRZYJEMNE Programming ... it's the only job I can think of where I get to be both an engineer and an artist. There's an incredible, rigorous, technical element to it, which I like because you have to do very precise thinking. On the other hand, it has a wildly creative side where the boundaries of imagination are the only real limitation. ~Andy Hertzfeld, about programming PROGRAMOWANIE JEST POTRZEBNE (każdemu Efektywna praca na komputerze wymaga automatyzacji rutynowych czynności, inaczej całe godziny spędzamy na mało kocepcyjnych zajęciach, sprowadzających się do klikania myszką. Automatyzacja = programowanie.
Dla informatyków ... PROGRAMOWANIE JEST POTRZEBNE W ZAWODZIE In software, the term architect means many things. (In software any term means many things.) In general, however it conveys a certain gravitas, as in "I'm not just a mere programmer - I'm an architect". This may translate into "I'm an architect now - I'm too important to do any programming". ... .... .... XP calls the leading technical figure the "Coach". The meaning is clear: in XP technical leadership is shown by teaching the programmers and helping them make decisions. It's one that requires good people skills as well as good technical skills. ~Martin Fowler, "Is design dead?"
Języki programowania Tekst programu zapisujemy w wybranym języku programowania. Każdy język programowania posiada swój alfabet, czyli zbiór znaków (liter i cyfr) z których mogą być konstruowane symbole języka (ciągi znaków). Reguły składniowe definiują dopuszczalne sposoby tworzenia symboli oraz dopuszczalne porządki ich występowania w programie, zaś semantyka języka określa znaczenie wybranych symboli. Istnieje wiele (dziesiątki tysięcy) języków programowania.
Języki programowania - klasyfikacja Języki imperatywne wymagają od programisty wyspecyfikowania konkretnej sekwencji kroków realizacji zadania, natomiast języki deklaratywne - opisują relacje pomiędzy danymi w kategoriach funkcji (języki funkcyjne) lub reguł (języki relacyjne, języki programowania logicznego) Podejście obiektowe polega na łącznym rozpatrywaniu danych i możliwych operacji na nich, dając możliwość tworzenia i używania w programie nowych typów danych, odzwierciedlających dziedzinę problemu, programowanie proceduralne rozdziela dane i funkcje i nie dostarcza sposobów prostego odzwierciedlenia dziedziny rozwiązywanego problemu w strukturach danych, używanych w programie.
Języki programowania - przykłady Przykładami języków proceduralnych są: ALGOL, FORTRAN, PL/I, C. Języki obiektowe to np. SmallTalk, Java, C++, C#. Najbardziej znanym językiem funkcyjnym jest Haskell, zaś językiem programowania logicznego - Prolog. Do operowania na bazach danych służy język relacyjny SQL. Języki takie jak Python, Ruby, Groovy czy Scala łączą podejście obiektowe z elementami programowania funkcyjnego,
Języki kompilowane W językach kompilowanych tekst programu (program źródłowy) tłumaczony jest na kod binarny (pośredni) przez specjalny program nazywany kompilatorem. Kompilator jednocześnie sprawdza składniową poprawność programu, sygnalizując wszelkie błędy. Proces kompilacji jest więc nie tylko procesem tłumaczenia, ale również weryfikacji składniowej poprawności programu. Zazwyczaj inny program zwany linkerem - generuje z kodu pośredniego gotowy do działania binarny kod wykonywalny i zapisuje go na dysku w postaci pliku typu wykonywalnego (np. z rozszerzeniem EXE lub z nadanym atrybutem "zdolny do wykonywania"). W ten sposób działają takie języki jak C czy C++. Czasem kompilator produkuje symboliczny kod binarny, który jest wykonywany za pomocą interpretacji przez program zwany interpreterem. Tak właśnie dzieje się w przypadku języka Java.
Języki interpretowane W językach interpretowanych kod programu (źródłowy lub pośredni) jest odczytywany przez specjalny program zwany interpreterem, który na bieżąco - w zależności od przeczytanych fragmentów programu - przesyła odpowiednie polecenia procesorowi i w ten sposób wykonuje program. Przykładami języków interpretowanych są: REXX, ObjectREXX, Perl, PHP. Czasami mówimy też o takich językach jako o językach skryptowych. Zazwyczaj języki skryptowe zapewniają dynamiczne typowanie (typy danych nie muszą być z góry ustalone i mogą zmieniać się w trakcie wykonania programu).
Wprowadzenie do obiektowości (1) Obiekt - coś co można wyodrębnić, nazwać, określić jego właściwości. Na przykład: rower, samochód, pies, człowiek. Obiekty mogą wykonywać jakieś czynności, udostępniają jakieś usługi. Inne obiekty mogą "poprosić" je o wykonanie tych usług. Np. obiekt-kierowca może "zlecić" obiektowi-samochodowi. by ten ruszył lub zatrzymał się Powiemy, że do obiektów posyłane są komunikaty, żądające od nich wykonania określonych usług. Klasa stanowi opis takich cech grupy podobnych obiektów, które są dla nich niezmienne. Np. samochody mają kolor i mogą ruszać i zatrzymywac się.
Wprowadzenie do obiektowości (2) Klasa urządzeń elektrycznych: class ElDev { def width, height <-- atrybuty: szerokość, wysokość, stan def isOn ================= Interfejs komunikatów (metody) def on() { isOn = true <--- usługa on (włącz), inaczej: metoda o nazwie on } def off() { isOn = false <--- usługa off (wyłacz),inaczej: metoda o nazwie off Nowy typ danych w programie: ElDev a = new ElDev() ElDev b = new ElDev() a.on() // komunikat: obiekcie a włącz się b.on() // obiekcie b włącz się a.off() // obiekcie a wyłącz się Utworzenie nowych obiektów w programie Kropka służy do wywołania metod
Wprowadzenie do obiektowości (3) Dziedziczenia klas - klasa dziedzicząca inną przejmuje jej właściwości i ew. dodaje własne, wyspecjalizowane. class Computer extends ElDev { def run(Program p) { if (isOn()) p.execute() } // ... Computer a = new Computer() Program x = new Program() ... a.on(); a.run(x); ... a.off();
Wprowadzenie do obiektowości (4) Interfejsy - "biedniejsze klasy" = deklaracje metod. Klasy mogą implementować interfejsy. interface Runnable { run() } class Dog implements Runnable { def run() { // definicja metody run dla Psa // jak biegnie pies? class Cat implements Runnable { def run() { // definicja metody run dla kota // jak biegnie kot?
Java uniwersalny język programowania, język wieloplatformowy składniowe podobieństwo do C/C++ obiektowość automatyczne odśmiecanie pamięci brak wskaźników ścisła kontrola typów bezpieczne konwersje wymuszanie obsługi błędów za pomocą wyjątków wbudowane elementy współbieżności uniwersalny język programowania, język wieloplatformowy + bogaty zestaw standardowych bibliotek i narzędziowych interfejsów programistycznych (API), które umożliwiają w jednolity, niezależny od platformy sposób programować: graficzne interfejsy użytkownika (GUI) dostęp do baz danych działania w sieci, aplikacje rozproszone, aplikacje WEB, oprogramowanie pośredniczące (middleware), zaawansowana grafikę, gry i multimedia, aplikacje na telefony komórkowe i inne "małe" urządzenia.
Języki JVM JVM wykonuje bytecode. Języki JVM = języki kompilowane do b-kodu. Żródło rys. : Carl Byström blog Żródło rys. : WIKI
JVM a języki dynamiczne Języki dynamiczne (np. Groovy, JRuby) - kontrola typów w fazie wykonania, a nie kompilacji. Zalety: mniejszy = łatwiejszy do pisania i czytelniejszy kod, większa elastyczność od języków ze statycznym typowaniem Wady: mniejsza efektywność działania (ale poprawiająca się), wiele błędów wykrywana w fazie wykonania, a nie kompilacji. W Javie 7 nowa instrukcja b-kodu: invokedynamic, ulatwiająca implementację języków z dynamicznym typowaniem oraz poprawiająca efektywność ich działania zob. Ed Ort. New JDK 7 Feature: Support for Dynamically Typed Languages in the Java Virtual Machine
Groovy * is an agile and dynamic language for the Java Virtual Machine * builds upon the strengths of Java but has additional power features inspired by languages like Python, Ruby and Smalltalk * supports Domain-Specific Languages and other compact syntax so your code becomes easy to read and maintain * makes writing shell and build scripts easy with its powerful processing primitives, OO abilities and an Ant DSL * increases developer productivity by reducing scaffolding code when developing web, GUI, database or console applications * seamlessly integrates with all existing Java objects and libraries * compiles straight to Java bytecode so you can use it anywhere you can use Java Cytat ze strony Groovy 22
Groovy Groovy = Java – "boiler plate code" + dynamiczne typowanie + dynamiczne wykonanie kodu (skryptowanie) + znacznie poszerzona funkcjonalność bibliotek + rozbudowane oraz modyfikowalne instrukcje sterujące + przeciążanie operatorów + przyjemna składnia dla kolekcji + domknięcia i elementy programowania funkcyjnego + latwe w użyciu parsery (XML/HTML, JSON) + rozbudowane rodzaje napisów i "templates" + wbudowane w składnię przetwarzanie wyr. regularnych + buildery (Swing, Ant, Html, Xml, JSON, Graphics ...) + metaprogramowanie fazy kompilacji i wykonania + doskonałe wsparcie do tworzenia DSL 23
Skrypty w języku Groovy kod w jednym pliku źródłowym (lub jako napis w programie), nie ma potrzeby definiowania klas ani metod (ale można), nie ma potrzeby deklarowania zmiennych (ale można). Można łatwo pisać proste programy. Groovy: name = 'World' println "Hello $name" Java: public class Greeting { public static void main(String ... args) { String name = "World"; System.out.println("Hello " + name); } Średnik: w Groovy można pomijać, gdy w jednym wierszu jedna instrukcja. Nawiasy w wywołaniu metody/ funkcji: można pomijać, gdy są argumenty wywołania. 24
Porównanie: Java a Groovy import java.util.*; public class PostfixFilter { public static List<String> getIdsFromListWithPostfix(List<String> list, String postfix) { List<String> result = new ArrayList<>(); for (String name : list) { if (name.endsWith(postfix)) result.add(name); } return result; public static void main(String[] args) { List<String> names = new ArrayList<>(); names.add("AWA Warszawa"); names.add("AKR Kraków"); names.add("AWR Wroclaw"); names.add("\"xxx\" Warszawa"); String loc = "Warszawa"; List<String> waw = getIdsFromListWithPostfix(names, loc); System.out.println("Znalezione dla " + loc + ": " + waw.size()); for (String name : waw) { String[] words = name.split(" +"); System.out.println(words[0]); names = [ 'AWA Warszawa', 'AKR Kraków','AWR Wroclaw', '"xxx" Warszawa'] loc = 'Warszawa' waw = names.findAll { it.endsWith loc } println "Znalezione dla $loc: " + waw.size() waw.each { println it.tokenize()[0] } 25
Przykład praktyczny: kursy euro import groovy.swing.SwingBuilder def url = 'http://www.ecb.europa.eu/stats/eurofxref/eurofxref-daily.xml' def rates = new XmlParser().parse(url) def map = [:] rates.Cube.Cube.Cube.each { map[it.@currency] = it.@rate } new SwingBuilder().edt { frame(title: 'Euro rates', pack: true, visible: true) { panel() { comboBox(id: 'cb', border: titledBorder('Select currency'), prototypeDisplayValue: 'xxxxxxxxxxxxx', items: map.keySet().toList(), actionPerformed: { def cur = it.source.selectedItem lab.text = map[cur] }) label(id: 'lab', preferredSize: cb.preferredSize, border: titledBorder('Rate'))
Instalacja 1. JDK z java.sun.com - program instalacyjny prowadzi za rękę 2. Dokumentacja z java.sun.com - unzip 3. Groovy z groovy.codehaus.org - unzip 4. (opcjonalnie) Wybrane IDE 5. Ustawić zmienne środowiskowe PATH, JAVA_HOME i GROOVY_HOME 6. Test: Zapisać program w pliku Start.groovy: println "I'm Groovy!" Z wiersza poleceń: groovy Start.groovy Na konsoli uzyskamy napis: I’m Groovy! 27
Praca z Eclipse Eclipse pobrać można ze strony eclipse.org. Pobrane archiwum wystarczy rozpakować na dysku. Należy też doinstalować plug-in dla języka Groovy (“Software updates”). Na starcie Eclipse wybieramy Workspace - czyli obszar roboczy. Jest to wybrany przez nas katalog, w którym będą nasze programy. Workspace zawiera projekty. Programy umieszczane są w projektach. Zatem sekwencja działań jest następująca: * uruchomić Eclipse, * wybrać Workspace, * utworzyć nowy projekt (”Groovy project"), * w danym projekcie utworzyć program (”Groovy class"). 28