{"id":5523,"date":"2011-01-18T13:10:18","date_gmt":"2011-01-18T12:10:18","guid":{"rendered":"http:\/\/www.devapp.it\/wordpress\/?p=5523"},"modified":"2011-03-01T11:45:52","modified_gmt":"2011-03-01T10:45:52","slug":"l014-un-contratto-tra-la-gli-oggetti-il-protocol","status":"publish","type":"post","link":"https:\/\/www.devapp.it\/wordpress\/l014-un-contratto-tra-la-gli-oggetti-il-protocol\/","title":{"rendered":"L#014 \u2013 Un contratto tra la gli oggetti: il protocol"},"content":{"rendered":"<p>Oggi torniamo a parlare di programmazione ad oggetti ed impareremo un&#8217;aspetto importante di questo paradigma di programmazione che, una volta compreso, pu\u00f2 farci risparmiare righe di codice e render\u00e0 i nostri programmi migliori, perch\u00e8 meno codice equivale ad una minore probabilit\u00e0 di bug nascosti.<\/p>\n<p>Parleremo del costrutto <strong>protocol<\/strong>.<\/p>\n<p>Probabilmente chi ha gi\u00e0 sviluppato qualche programma in questo linguaggio l&#8217;ha gi\u00e0 incontrato, magari in quei fastidiosi &#8220;warning&#8221; che ci avvisano di non aver implementato tutti i metodi del protocollo tal dei tali, ma cos&#8217;\u00e8 in realt\u00e0 il costrutto protocol e a cosa serve?<\/p>\n<p><center><br \/>\n<a href=\"http:\/\/www.devapp.it\/wordpress\/supporto-applicazioni\/parole-vietate-di-ignazio-calo\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter\" src=\"http:\/\/www.devapp.it\/wordpress\/wp-content\/uploads\/2010\/02\/bannerIgnazioc.png\" alt=\"\" width=\"480\" height=\"100\" \/><\/a><br \/>\n<\/center><br \/>\n<!--more--><\/p>\n<h4>Un po&#8217; di storia<\/h4>\n<p>Il protocol (o <em>interface<\/em> in java ) nasce per sopperire alla mancanza dell&#8217;ereditariet\u00e0 multipla, risolvendo il problema del diamante tagliando, di fatto, la gerarchia delle classi.<br \/>\nNon ci avete capito nulla? \u00e8 normale, non spaventatevi, tornate a leggere questa frase dopo aver letto tutto l&#8217;articolo, se allora vi sar\u00e0 pi\u00f9 chiara vorr\u00e0 dire che ho fatto bene il mio lavoro.<\/p>\n<p>I <strong>protocol<\/strong> rientrano in una aspetto della OOP chiamto <em>polimorfismo<\/em>, ovvero la caratteristica che hanno gli oggetti trattati dalla OOP di poter &#8220;avere pi\u00f9 forme&#8221; o meglio di poter essere trattati non come un unico tipo, ma come il suo tipo specifico e tutti i tipi che lo precedono nella gerarchia delle classi, a differenza dei tipi primitivi che invece hanno per definizione un solo tipo.<\/p>\n<p>Ad esempio un eggetto di tipo <em>UILabel<\/em> possiamo vederlo sia come UILabel, ma \u00e8 anche una <em>UIView<\/em>, un <em>UIResponder<\/em> e un <em>NSObject<\/em> e possiamo utilizzare su di lui tutti i metodi previsti da questi oggetti. Una variabile primitiva di tipo <strong>int<\/strong>, invece, \u00e8 solo un &#8220;int&#8221; e posso usarlo solo dove viene richiesto un <em>int<\/em>.<\/p>\n<p><strong>Nota per gli smaliziati<\/strong>: lo so che il C non \u00e8 fortemente tipizzato quindi posso usare un &#8220;int&#8221; anche dove viene richiesto un &#8220;char&#8221;, ma non facciamo troppo i fiscali!<\/p>\n<p>Questa struttra gerarchica \u00e8 molto versatile, ma alle volte il mondo reale non \u00e8 cos\u00ec ordinato come noi programmatori vorremo, quindi potrebbe nascere la necessit\u00e0 di ereditare da due classi differenti. Supponiamo che, dopo aver creato la classe &#8220;automobile&#8221; e la classe &#8220;barca&#8221;, vengano fuori delle auto anfibie come queste:<\/p>\n<p><center><br \/>\n<a href=\"http:\/\/www.devapp.it\/wordpress\/wp-content\/uploads\/2010\/12\/squba.jpg\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-5626\" src=\"http:\/\/www.devapp.it\/wordpress\/wp-content\/uploads\/2010\/12\/squba.jpg\" alt=\"\" width=\"300\" height=\"160\" srcset=\"https:\/\/www.devapp.it\/wordpress\/wp-content\/uploads\/2010\/12\/squba.jpg 300w, https:\/\/www.devapp.it\/wordpress\/wp-content\/uploads\/2010\/12\/squba-150x80.jpg 150w\" sizes=\"auto, (max-width: 300px) 100vw, 300px\" \/><\/a><br \/>\n<\/center><\/p>\n<p>Se volessimo creare una classe per questo mezzo dovremmo esporre dei metodi specifici per l&#8217;automobile (frena) e dei metodi specifici per le barche (getta l&#8217;\u00e0ncora) e probabilmente saremmo tentati di creare una classe che eredita sia da &#8220;automobile&#8221; che da &#8220;barca&#8221; per evitare di riscrivere tutti i metodi e tutte le propriet\u00e0 di questi due mezzi.<\/p>\n<p>Si presenta a questo punto un problema, noto appunto con il nome di &#8220;problema del diamante&#8221;. Supponiamo che le due classi &#8220;automobile&#8221; e &#8220;barca&#8221; abbiano entrambe il metodo &#8220;accelera&#8221;, magari perch\u00e8 entrambe ereditano dalla classe astratta &#8220;veicolo&#8221; dove \u00e8 specificato questo metodo, ma abbiamo due implementazioni diverse: una restituisce la velocit\u00e0 in kilometri e l&#8217;altra in nodi.<br \/>\nSe la nostra vettura anfibia eredita da entrambe le classi, e non effettua l&#8217;override del metodo &#8220;accelera&#8221; quando verr\u00e0 invocato questo metodo quale codice verr\u00e0 eseguito? Quello della classe &#8220;auto&#8221; o della classe &#8220;barca&#8221;?<\/p>\n<p>Questo problema di chiama &#8220;del diamante&#8221; perch\u00e8 una sua schematizzazione potrebbe ricordare un diamante (ma non provate a regalarlo alla vostra donna!).<\/p>\n<p><center><br \/>\n<a href=\"http:\/\/www.devapp.it\/wordpress\/wp-content\/uploads\/2010\/12\/Untitleddrawing.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-5629\" src=\"http:\/\/www.devapp.it\/wordpress\/wp-content\/uploads\/2010\/12\/Untitleddrawing.png\" alt=\"\" width=\"400\" height=\"300\" srcset=\"https:\/\/www.devapp.it\/wordpress\/wp-content\/uploads\/2010\/12\/Untitleddrawing.png 400w, https:\/\/www.devapp.it\/wordpress\/wp-content\/uploads\/2010\/12\/Untitleddrawing-300x225.png 300w, https:\/\/www.devapp.it\/wordpress\/wp-content\/uploads\/2010\/12\/Untitleddrawing-150x112.png 150w\" sizes=\"auto, (max-width: 400px) 100vw, 400px\" \/><\/a><br \/>\n<\/center><\/p>\n<p>Per risolvere questo problema alcuni linguaggi come il java ed il nostro caro obj-c non permettono di implementare l&#8217;ereditariet\u00e0 multipla, eliminando il problema alla radice.<br \/>\nPurtroppo per\u00f2 i casi come la macchina anfibia nella realt\u00e0 sono pi\u00f9 comuni di quanto si pensi e, soprattutto se abbiamo sbagliato a creare la nostra gerarchia delle classi, viene proprio la voglia di fare copia\/incolla di codice con tutti i problemi che conosciamo.<br \/>\nPer venirci incontro \u00e8 stato creato il costrutto &#8220;interface&#8221; in java e &#8220;protocol&#8221; in obj-c che, anche se non risolve appieno il problema, almeno ci offre una mezza soluzione.<\/p>\n<h4>Protocol in pratica<\/h4>\n<p>Un &#8220;protocollo&#8221; \u00e8 in pratica un unico file .h (senza il .m) dove vengono elencati i metodi che lo costituiscono, lo possiamo pensare come una sorta di &#8220;contratto&#8221;.<\/p>\n<pre lang=\"objc\" line=\"1\" escaped=\"true\">\r\n#import \r\n\r\n@protocol NOME_PROTOCOLLO\r\n\r\n- (void)primoMetodo;\r\n- (void)secondoMetodo;\r\n....\r\n@end\r\n<\/pre>\n<p>Una classe pu\u00f2 implementare uno o pi\u00f9 protocolli, cos\u00ec facendo si impegna a fornire una implementazione ai metodi dei protocolli che ha implementato.<br \/>\nQuesto sembrerebbe non aver risolto il nostro problema, perch\u00e8 potremmo trovarci costretti a riscrivere due volte la stessa implementazione di un metodo di un protocollo in due classi separate che lo implementano, ma in compenso ci offre la possibili\u00e0 di definire delle relazioni tra classi che non stanno sullo stesso ramo dell&#8217;albero delle gerarchie, per questo si dice che i protocol &#8220;tagliano l&#8217;albero delle gerarchie&#8221;.<br \/>\nIn questo caso il &#8220;problema del diamante&#8221; non si pu\u00f2 presentare perch\u00e9 nei protocolli non ci sono metodi implementati, ma solo le loro &#8220;signatures&#8221;<\/p>\n<h4>Protocol come tipo di dato<\/h4>\n<p>C&#8217;\u00e8 un secondo aspetto che rende &#8220;protocol&#8221; un costrutto molto versatile ed \u00e8 il seguente.<br \/>\nSupponiate di aver scritto il miglior algoritmo di ordinamento basato su confronti, un algoritmo fantastico che per ordinare <em>n<\/em> interi ci metta meno di <em>nlogn<\/em> tempo e lo vogliate vendere. Che tipi di dati ordinerebbe la vostra funzione? interi? stringhe? automobili?<br \/>\nOvviamente se riusciste a fare una funzione generica che ordina <em>qualsiasi<\/em> tipo di dato sareste sicuri di venderne milioni di copie..ma come fare?<\/p>\n<p>Se ci pensate bene l&#8217;unica cosa che vi interessa \u00e8 che gli oggetti da ordinare espongano un metodo come &#8220;<strong>(int)compareTo:(id)obj<\/strong>&#8221; quindi voi potreste dire al vostro cliente &#8220;se il tuo oggetto ha questo metodo allora puoi usare la mia funzione&#8221;.<\/p>\n<p>Per ottenere questo comodissimo risultato bisogna proprio sfruttare il costrutto procol!<\/p>\n<p>In java il costrutto &#8220;interface&#8221; definisce un tipo di dato,quindi se avete creato un interface di nome &#8220;comparable&#8221; nell&#8217;algoritmo potete lavorare direttamente con oggetti di tipo comparable. Purtroppo in obj-c la cosa non \u00e8 cos\u00ec comoda, il &#8220;protocol&#8221; non definisce un tipo di dato, quindi il massimo che possiamo fare \u00e8 lavorare con oggetti di tipo generico e specificare al compilatore che questi oggetti &#8220;preferiremmo&#8221; che implementassero il protocollo &#8220;comparable&#8221;.<\/p>\n<p>In questo modo:<\/p>\n<pre lang=\"objc\" line=\"1\" escaped=\"true\">\r\nUIView &lt; NOME_PROTOCOLLO &gt; *target;\r\n<\/pre>\n<p>Purtroppo il compilatore si pu\u00f2 rendere conto solo di assegnazioni di tipo statico, quindi evidenzier\u00e0 solo di errori in fase di compilazione. Per essere certi che gli oggetti su cui lavoriamo implementano davvero il protocollo &#8220;comparable&#8221; dobbiamo utilizzare il seguente codice:<\/p>\n<pre lang=\"objc\" line=\"1\" escaped=\"true\">\r\nif ([target conformsToProtocol:@protocol(NOME_PROTOCOLLO)] == YES ) {\r\n  \/\/do something.\r\n}\r\n<\/pre>\n<h4>Implementare un protocollo<\/h4>\n<p>Per aiutare quindi il compilatore a segnalare anomalie nel codice \u00e8 sempre buona norma specificare quali protocolli abbiamo intenzione di implementare nelle nostre classi. La sinstassi per far questo \u00e8 la seguente<\/p>\n<pre lang=\"objc\" line=\"1\" escaped=\"true\">\r\n\/\/nel file .h della dichiarazione della classe\r\n@interface NOME_CLASSE : NOME_SUPERCLASSE  &lt; NOME_PROTOCOLLO &gt; {\r\n\tUIColor *baseColor;\r\n}\r\n<\/pre>\n<p>A questo punto dovrebbe essere chiaro cosa significa<\/p>\n<pre lang=\"objc\" line=\"1\" escaped=\"true\">\r\n&lt; UITableViewDelegate , UITableViewDataSource &gt;\r\n<\/pre>\n<p>in testa ai nostri controller delle tabelle&#8230;<\/p>\n<p>non si tratta altro che di due protocolli, e con questo codice la classe si impegna a fornire una implementazione ai metodi del protocollo.<br \/>\nSe le implementazioni sono parziali il compilatore segnaler\u00e0 l&#8217;errore con un warning.<\/p>\n<p>Alla prossima!<\/p>\n<p><center><br \/>\n<a href=\"http:\/\/www.devapp.it\/wordpress\/supporto-applicazioni\/le-applicazioni-dei-nostri-autori\/parole-vietate-di-ignazio-calo\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter\" src=\"http:\/\/www.devapp.it\/wordpress\/wp-content\/uploads\/2010\/02\/bannerIgnazioc.png\" alt=\"\" width=\"480\" height=\"100\" \/><\/a><br \/>\n<\/center><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Oggi torniamo a parlare di programmazione ad oggetti ed impareremo un&#8217;aspetto importante di questo paradigma di programmazione&#8230;<\/p>\n","protected":false},"author":53,"featured_media":5531,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[9],"tags":[5,549,550,546,547,548],"class_list":["post-5523","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-guide-teoriche","tag-objective-c","tag-polimorfismo","tag-problema-del-diamante","tag-protocol","tag-protocolli-objective-c","tag-teoria-programmazione-iphone"],"acf":[],"aioseo_notices":[],"_links":{"self":[{"href":"https:\/\/www.devapp.it\/wordpress\/wp-json\/wp\/v2\/posts\/5523","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.devapp.it\/wordpress\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.devapp.it\/wordpress\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.devapp.it\/wordpress\/wp-json\/wp\/v2\/users\/53"}],"replies":[{"embeddable":true,"href":"https:\/\/www.devapp.it\/wordpress\/wp-json\/wp\/v2\/comments?post=5523"}],"version-history":[{"count":33,"href":"https:\/\/www.devapp.it\/wordpress\/wp-json\/wp\/v2\/posts\/5523\/revisions"}],"predecessor-version":[{"id":6000,"href":"https:\/\/www.devapp.it\/wordpress\/wp-json\/wp\/v2\/posts\/5523\/revisions\/6000"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.devapp.it\/wordpress\/wp-json\/wp\/v2\/media\/5531"}],"wp:attachment":[{"href":"https:\/\/www.devapp.it\/wordpress\/wp-json\/wp\/v2\/media?parent=5523"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.devapp.it\/wordpress\/wp-json\/wp\/v2\/categories?post=5523"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.devapp.it\/wordpress\/wp-json\/wp\/v2\/tags?post=5523"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}