1 ČESKÁ ZEMĚDĚLSKÁ UNIVERZITA FAKULTA PROVOZNĚ EKONOMICKÁ Obor: Informatika - magisterský DIPLOMOVÁ PRÁCE Téma: Aplikační frameworky v objektově orien...
ČESKÁ ZEMĚDĚLSKÁ UNIVERZITA FAKULTA PROVOZNĚ EKONOMICKÁ Obor: Informatika - magisterský
DIPLOMOVÁ PRÁCE
Téma: Aplikační frameworky v objektově orientovaných jazycích
Vypracoval:
Bc. Jan Tauchmann
Vedoucí diplomové práce:
doc. Ing. Vojtěch Merunka Ph.D.
Praha
2009
Aplikační frameworky v objektově orientovaných jazycích
The application frameworks for the object oriented languages
Kapitola 1:
Stránka 1
Kapitola 2:
Stránka 2
Kapitola 3:
Stránka 3
Kapitola 3:
Stránka 4
LD A,2 LD B,3 CALL SOUCET …
# zavolání podprogramu „SOUCET“ # registry A a B zde nahrazují parametry
:SOUCET ADD A,B RET
Kapitola 4:
Stránka 5
Definice knihovny "matice":
Unit Matice; Interface Type TMatice = Array [1..5, 1..5] of Integer; function Diskriminant(var mat: TMatice): Integer;
Implementation function Diskriminant(var mat: TMatice): Integer; begin {... zde je implementace vypočtu diskriminantu } end;
begin End.
Využití knihovny matice v jiném programu:
Program MaticeGui; Uses Crt, Matice; var mat: TMatice; Begin {... zde se nactou hodnoty matice do promenne "mat" z klavesnice} WriteLn('Vysledek je:'); WriteLn(Diskriminant(mat)); End.
Kapitola 4:
Stránka 6
Program Form1; var myForm : TForm; procedure b_OkClick(sender:TObject); begin myForm.Close; end;
begin myForm := TForm.Create(Application) ; //vytvoření formuláře //vytvoření tlačítka na formuláři TButton okButton := TButton.Create(myForm); okButton.Left := 22; okButton.Right := 47; okButton.Label := "OK"; //přiřazení procedury b_OkClick události kliknutí na tlačítko okButton okButton.OnClick := b_OkClick; myForm.Show; //zobrazení formuláře end.
public Connection GetMyDbConnection() { Type t = Type.GetType(Configuration["Type"]); Connection conn = (Connection)Activator.CreateInstance(t); conn.ConnectionString = (string)Configuration["ConnectionString"]; conn.ConnectionTimeout = (int)Configuration["ConnectionTimeout"]; conn.KeepAlive = (bool)Configuration["KeepAlive"]; return conn; }
Kapitola 7:
Stránka 21
void ExecSQL(...)
void SaveUser(User user) Uživatelské rozhraní
User GetUser(int id)
Business logika
DataReader GetSQLResult(...)
Přístup k databázi (DAO)
public void btnSave_Click() { //uložíme informace o uživateli currentUser UserLogic.SaveUser(currentUser); }
Kapitola 7:
Stránka 22
Interface
Interface
void SaveUser(User user) void ExecSQL(...)
Uživatelské rozhraní
Objekt UserLogic GetObject("UserLogic")
Přístup k databázi (DAO)
Business logika
Objekt DAO GetObject("DAO")
Spring framework
public void btnSave_Click() { //uložíme informace o uživateli currentUser IObjectFactory factory = ContextRegistry.GetContext(); IUserLogic userLogic = (IUserLogic) factory.GetObject("userLogic"); userLogic.SaveUser(currentUser); }
public class UserLogic: IUserLogic { private int minUserNameLength; public int MinUserNameLength { get { return minUserNameLength; } set { minUserNameLength = value; } }
Kapitola 7:
Stránka 23
public void Save(User user) { //validace if (user.Name.Length < MinUserNameLength) throw new ValidationException("User name's length must be greater then " + MinUserNameLength); //implementace uložení objektu user //.. //.. } }
Uživatelské rozhraní
začne vyvvíjet za 4 měsíce
Neexistuje žádný použitelný interface
Neexistuje žádný použitelný interface Business logika
Přístup k databázi (DAO)
začně vyvíjet za 2 měsíce
Čeká až bude mít DAO vývojář první funkční verzi
vyvíjí
Čeká až bude mít DAO vývojář první funkční verzi
1) 2) public class UserLogic: IUserLogic { public User GetUser(long id) {
Kapitola 7:
Stránka 24
//Volání DAO vrstvy return DAO.GetObject<User>(id, Record.Current); } } public class UserLogicFake: IUserLogic { public User GetUser(long id) { User user = new User(); user.Id = id; user.Name = "Jan Novák"; //...“ruční“ vyplnění dalších atributů //... return user; } }
[TestFixture] public class UserLogicUnitTest { public void SaveUserTest() { User user = new User(); user.Id = id; user.Name = "Jan Novák"; //...vyplnění dalších povinných položek userLogic.SaveUser(user); Assert.AreEqual(user.LastModified,DateTime.Now); //...další Assert příkazy } }
public void SaveUserTest()
Kapitola 7:
Stránka 25
{ IObjectFactory factory = ContextRegistry.GetContext(); User user = (IUserLogic) factory.GetObject("testUser2"); userLogic.SaveUser(user); //... Assert příkazy }
Kapitola 7:
Stránka 26
Webový server
HTTP požadavek WWW prohlížeč (Firefox, IE...)
HTTP odpověd
HTTP server
index.php picture.jpg style.css
1) 2) o
o
Kapitola 8:
Stránka 27
Dnes je: print date()?> Dnes je: 23.12.2007 13:21
Kapitola 8:
Stránka 28
XML konfigurace
Http požadavek
Webový kontejner
Volá
1. Volání
Servlet
Business logika (získání dat, výpočty)
2. Business objekty 3. Přesměrování na JSP
Http odpověď
JSP stránka
Přístup pomocí URL /register
RegisterServlet
Nový požadavek nebo Validační chyby
register.jsp
Úspěšná registrace
registrationSuccess.jsp
${validationMessage} public class RegisterServlet extends HttpServlet { public void doGet (HttpServletRequest req,HttpServletResponse res) {
Kapitola 8:
Stránka 29
String name = req.Parameters["name"]; String password = req.Parameters["password"]; //validace vstupu if(password==null || password.Length<3) { req.Attributes["validationMessage"] = "Invalid password's length"; req.forward("register.jsp"); //přesměrování zpět na formulář return; } //volání business logiky pro založení uživatele UserLogic logic=new UserLogic(); User user=logic.registerNewUser(name, password, ...); if(user!=null) { //zpřístupnění objektu "user" v JSP stránce req.Attributes["user"] = user; req.forward("registrationSuccess.jsp"); //přesměrování } else { //nastavení validační hlášky req.Attributes["validationMessage"] = "Your name is already used."; req.forward("register.jsp"); //přesměrování zpět na formulář } }
Registration process for registered with ID: ${user.Id}
Přijetí požadavku ActionServletem a vyplnění LoginFormBean
LoginFormBean ____________ User=root Pass=12345
Stránka 31
Konfigurace (struts-config.xml)
Form bean
Vytváří Http požadavek /nejaka_cesta
Web kontejner
Action servlet
Volá
Využívá
Action třída
Volá
Business logika
Přesměruje volání na
Http odpověď
Využívá JSP stránka
Kapitola 8:
Stránka 32
o
o
<struts-config>
public class RegisterAction extends Action { public ActionForward execute(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response)
Kapitola 8:
Stránka 33
throws Exception { //volání business logiky pro založení uživatele UserLogic logic=new UserLogic(); RegisterForm rf=(RegisterForm)form; User user=logic.registerNewUser(rf.getName(), rf.getPass(), ...); if(user!=null) { //zpřístupnění objektu "user" v JSP stránce req.Attributes["user"] = user; //dokončení běhu se stavem "success" return (mapping.findForward("success")); } else { //dokončení běhu se stavem "failure" return (mapping.findForward("failure")); } } }
ArrayList numbers = new ArrayList() { 1, 2, 3, 4, 5 }; ArrayList result = new ArrayList(); foreach (int i in numbers) { if(i<4) result.Add(i); } result.Sort(delegate(int a, int b) { return b.CompareTo(a); });
ArrayList numbers = new ArrayList() { 1, 2, 3, 4, 5 }; var result = numbers .Where(n => n < 4) .OrderByDescending(n => n); numbers Where(),
n
=> n
< 4
OrderByDescending() .
ArrayList numbers = new ArrayList() { 1, 2, 3, 4, 5 }; var result = from int n in numbers where n < 4 orderby n descending select n;
Kapitola 9:
Stránka 45
Kapitola 9:
Stránka 46
Testovaný kód
Kód unit testu Testovací framework
Kapitola 10:
Stránka 47
public class StringUtil { public string Concat(string s1, string s2) { //pro názornost uděláme úmyslnou chybu return s1 + s1; } }
[TestFixture] public class StringUtilTest { [Test] public void ConcatTest() { StringUtil util = new StringUtil(); string result = util.Concat("A", "B"); Assert.AreEqual("AB", result, "Concatenation"); } }
Kapitola 10:
Stránka 48
Kapitola 10:
Stránka 49
Unit tests
U I
Kapitola 10:
A P P L I C A T I O N
B U S I N E S S
D A T A A C C E S S
DATA
Stránka 50
Console.WriteLine("Starting UI test scenario"); Console.WriteLine("Launching WinApp under test"); string exePath = @"..\\..\WinApp\bin\Debug\WinApp.exe"; testForm = LaunchApp(exePath, "WinApp.Form1"); //spuštění aplikace Console.WriteLine("Setting textBox1 to 'yellow'"); SetControlPropertyValue("textBox1", "Text", "yellow"); Console.WriteLine("Setting textBox1 to 'red'"); SetControlPropertyValue("textBox1", "Text", "red"); Console.WriteLine("Selecting comboBox1 to 'blue'"); SetControlPropertyValue("comboBox1", "SelectedItem", "blue"); Console.WriteLine("Clicking button1"); InvokeMethod("button1_Click", new object[]{null, new EventArgs()} ); Console.WriteLine("Checking for state: 'red', 'blue', 'Result is purple'"); bool pass = true; if ( !((ListBox.ObjectCollection)GetControlPropertyValue("listBox1", "Items")).Contains("Result is purple")) pass = false; if (pass) Console.WriteLine("\nUI test scenario result: PASS"); else Console.WriteLine("\nUI test scenario result: *FAIL*");
Kapitola 10:
Stránka 51
WebConversation wc = new WebConversation(); //načtení stránky localhost/index.aspx WebResponse resp = wc.getResponse("http://localhost/search.aspx" ); //použití DOM k získání formuláře na stránce WebForm form = resp.getForms()[0] //nastavení parametru formuláře „Name“ na hodnotu „Novák Jiří“ form.setParameter( "Name", "Novák Jiří") form.submit(); //odeslání formuláře //načtení stránky, na kterou se odkazoval link
Kapitola 10:
Stránka 52
WebResponse resp = wc.getCurrentPage(); //použití DOM k získání první tabulky na stránce WebTable table = resp.getTables()[0]; //kontrola počtu řádků v tabulce Assert.AreEqual( "rows", 4, table.getRowCount() ); //kontrola počtu sloupců v tabulce Assert.AreEqual( "columns", 3, table.getColumnCount() ); //kontrola počtu hypertextových odkazů v buňce s indexem (0,2) Assert.AreEqual( "links", 1, table.getTableCell( 0, 2 ).getLinks().length );
Kapitola 10:
Stránka 53
Kapitola 10:
Stránka 54
Kapitola 10:
Stránka 55
Kapitola 10:
Stránka 56
Kapitola 11:
Stránka 57
public class Calculator { ILog log = LogManager.GetLogger("Calculator"); public void Compute() { try { //... // zápis zprávy se závažností info log.Info("Příprava výpočtu kapitálové přiměřenosti"); //... //zápis zpravy se závažností warn log.Warn("Vstupní soubor je možná poškozen."); //... } catch (Exception e) {
Kapitola 11:
Stránka 58
//zápis informace o selhání log.Fatal("Výpočet kapitálové přiměřenosti selhal",e); //... } }