Baixe o app para aproveitar ainda mais
Prévia do material em texto
Projeto de Software / Programação 3 Interfaces e Polimorfismo Márcio Ribeiro marcio@ic.ufal.br twitter.com/marciomribeiro 2 Parallel development § Implement a class to save, remove, and find ShoppingCarts. A ShoppingCart has an ArrayList of Products § Students of Group A • FilePersistence § Students of Group B • JSONPersistence § Me • Client code Probably, there is a mess! Our code do not fit together! There are conflicts! In addiFon, it has no flexibility: how to easily exchange File for JSON? 5 FilePersistence and JSONPersistence § They are certainly different… § For example: different composiFon of objects • FileOutputStream versus JsonWriter • FileInputStream versus JsonReader § So, they do not inherit from a common superclass… § Does it mean they do not have similariFes?! Tamirys Nota Elas fazem a mesma coisa praticamente, que são os métodos de save, remove e find, mas de diferentes formas. So, save remove find Tamirys Nota Existem diferenças em COMO são salvos, mas as capacidades são as mesmas: remove, save e find. They do have similariFes! They share the same capabiliFes! Interfaces Tamirys Nota AGIR COMO -> CONTRATO 9 Interfaces § No default implementaFon: nothing to inherit! § Interfaces are mainly used to factor out responsibiliFes among different classes whose only commonality are specific shared capabiliFes § Much like two objects are related if they inherit from the same superclass, objects can be related if they implement the same interface! § Interfaces model “act as” relaFonships From http://www.cs.brown.edu/courses/cs015/lectures.html Tamirys Realce Tamirys Nota Unmarked definida por Tamirys 10 PersistenceSession interface § Interfaces only declare capabiliFes that the object must have § There are no definiFons with code! public interface PersistenceSession { void save(ShoppingCart shoppingCart); void remove(ShoppingCart shoppingCart); ShoppingCart find(int customerID); } Tamirys Nota Inteface: Comum a todas as classes que AGEM como alguma coisa (classe). 11 Contract § Interfaces define contracts… § … and force implementers to obey it! § Minimizes conflicts Tamirys Nota Implements: Colocar o contrato em prática. 12 Here is one implementaFon of PersistenceSession… public class FilePersistence implements PersistenceSession { @Override public void save(ShoppingCart shoppingCart) { … } @Override public void remove(ShoppingCart shoppingCart) { … } @Override public ShoppingCart find(int customerID) { … } } Tamirys Nota Implements: Age como.nullnullFilePersistence AGE COMO PersistenceSession. 13 … and here is another… public class JSONPersistence implements PersistenceSession { @Override public void save(ShoppingCart shoppingCart) { … } @Override public void remove(ShoppingCart shoppingCart) { … } @Override public ShoppingCart find(int customerID) { … } } <<interface>>! PersistenceSession! + save() : void! + remove() : void! + find() : Product! FilePersistence! + save() : void" + remove() : void" + find() : Product" JSONPersistence! + save() : void" + remove() : void" + find() : Product" Tamirys Nota LINHA PONTILHADA: AGEM COMO. Tamirys Nota ITÁLICO, ASSIM COMO CLASSE ABSTRATA. MAS, PARA DIFERENCIAR DE CLASSE ABSTRATA É UTILIZADO O ESTERIÓTIPO <<interface>>. Now, look how great interfaces are! 16 Parallel development revisited: two developers Okay! I call it and then I manipulate the ShoppingCart data I will provide a createPersistenceSession method § They are talking about how they will implement the ShoppingCart persistence 17 Calling createPersistenceSession ShoppingCart shoppingCart4 = new ShoppingCart(4); PersistenceSession persistence = createPersistenceSession(); persistence.save(shoppingCart4); ShoppingCart sc = persistence.find(4); persistence.remove(shoppingCart4); I’m gonna call createPersistenceSession as we defined… 18 ImplemenFng createPersistenceSession public PersistenceSession createPersistenceSession() { return new FilePersistence(); } I will use the File default implementation 19 Change request: JSON public PersistenceSession createPersistenceSession() { return new JSONPersistence(); } Are you nuts? We need to use JSON! No problem! I hate this guy! Tamirys Nota Vai funcionar porque JSONPersistence AGE COMO PersistenceSession. Change request: JSON public PersistenceSession createPersistenceSession() { return new JSONPersistence(); } Does my change break your code?! ShoppingCart shoppingCart4 = new ShoppingCart(4); PersistenceSession persistence = createPersistenceSession(); persistence.save(shoppingCart4); ShoppingCart sc = persistence.find(4); persistence.remove(shoppingCart4); Of course not! I am using the PersistenceSession interface Now, look the difference... <<interface>>! PersistenceSession! + save() : void! + remove() : void! + find() : Product! FilePersistence! + save() : void" + remove() : void" + find() : Product" JSONPersistence! + save() : void" + remove() : void" + find() : Product" DBPersistence! + save() : void" + remove() : void" + find() : Product" + begin() : void" + commit() : void" + rollback() : void" Here is a problemaFc scenario… ShoppingCart shoppingCart4 = new ShoppingCart(4); DBPersistenceSession persistence = (DBPersistenceSession) createPersistenceSession(); persistence.begin(); persistence.save(shoppingCart4); ShoppingCart sc = persistence.find(4); persistence.remove(shoppingCart4); persistence.commit(); public PersistenceSession createPersistenceSession() { return new JSONPersistence(); } Okay! @#$%*!!! JSON! I coupled my code to one specific implementation Tamirys Nota Errado: Implementa utilizando uma classe, utilizando os métodos dessa classe. Ao implementar JSONPersistence, o erro será: Cast Exception.nullnullErrado: O código está acoplado para uma implementação e não é flexível, não é viável.nullnullCerto: Implementar para interface, tornando tudo mais genérico e mais geral. Tamirys Nota Usar If persistence is InstanceOf DBPersistenceSession ... “Program to an interface, not to an implementaFon” From Gamma et. Al, Design Patterns: Elements of Reusable OO Software Polymorphism 26 Polymorphism § Key OOP concept § Replacement capacity § MulFple forms of response to the same message ShoppingCart shoppingCart4 = new ShoppingCart(4); PersistenceSession persistence = new createPersistenceSession(); persistence.save(shoppingCart4); Tamirys Nota Polimorfismo: Este objeto é capaz de receber múltiplas formas, por conta da programação para a interface. As formas podem ser: JSON, File e DB. 27 Dynamic binding § The appropriate method cannot be determined at compile Fme ShoppingCart shoppingCart4 = new ShoppingCart(4); PersistenceSessionpersistence; if (userInput.equals("file")) { persistence = new FilePersistence(); } else { persistence = new JSONPersistence(); } persistence.save(shoppingCart4); Which save method?! Now imagine an UFlity class... 29 UFlity class Utility! + getCheapest(ArrayList) : Product" + getMostExpensive(ArrayList) : Product" + getAveragePrice(ArrayList): double" § Implement it! 30 Change request § LinkedList seems be[er… § Now, list is a LinkedList § So, please, implement the change request! Product cheapest = getCheapest(list); … Product mostExpensive = getMostExpensive(list); … double average = getAveragePrice(list); Keep this in mind... You changed MANY places! Again, program to an interface, not to an implementaFon 33 Use the List interface! Utility! + getCheapest(List) : Product" + getMostExpensive(List) : Product" + getAveragePrice(List): double" Product cheapest = getCheapest(list); … Product mostExpensive = getMostExpensive(list); … double average = getAveragePrice(list); List list = new ArrayList(); List list = new LinkedList();
Compartilhar