Salut tout le monde,
J'ai récupéré un projet avec pas mal d'historique de code, dont une grande quantité de structures de ce type :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 | package com.spacefox.tests.com.spacefox.tests.lib; public abstract class AbstractClass { private String data; public AbstractClass(String data) { this.data = data; } public String getData() { return data; } public void doSomethingCommon(String parameter) { System.out.println("Abstract class with parameter " + parameter); } } // - - - - - - - - - - Nouveau fichier - - - - - - - - - - package com.spacefox.tests.com.spacefox.tests.lib; public class ConcreteClass2 extends AbstractClass { public ConcreteClass2(String data) { super(data); } public void doSomethingSpecificToConcreteClass2(int parameter) { System.out.println("Concrete class 2 with data " + getData() + " and parameter " + parameter); } } // - - - - - - - - - - Nouveau fichier - - - - - - - - - - package com.spacefox.tests.com.spacefox.tests.lib; public class ConcreteClass1 extends AbstractClass { public ConcreteClass1(String data) { super(data); } public void doSomethingSpecificToConcreteClass1() { System.out.println("Concrete class 1 with data " + getData()); } } // - - - - - - - - - - Nouveau fichier - - - - - - - - - - package com.spacefox.tests.com.spacefox.tests.lib; public interface ClassUser { void doSomethingWith(AbstractClass something); } |
Ce code est utilisé de cette manière :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | AbstractClass class1a = new ConcreteClass1("Class 1 object A"); AbstractClass class1b = new ConcreteClass1("Class 1 object B"); AbstractClass class2a = new ConcreteClass2("Class 2 object C"); AbstractClass class2b = new ConcreteClass2("Class 2 object D"); System.out.println("Intsanceof implementation"); ClassUser instanceofImplementation = new ClassUser() { @Override public void doSomethingWith(AbstractClass something) { something.doSomethingCommon("Bla"); if (something instanceof ConcreteClass1) { ((ConcreteClass1) something).doSomethingSpecificToConcreteClass1(); } else if (something instanceof ConcreteClass2) { ((ConcreteClass2) something).doSomethingSpecificToConcreteClass2(42); } } }; instanceofImplementation.doSomethingWith(class1a); instanceofImplementation.doSomethingWith(class1b); instanceofImplementation.doSomethingWith(class2a); instanceofImplementation.doSomethingWith(class2b); |
Ce qui me donne :
1 2 3 4 5 6 7 8 9 | Intsanceof implementation Abstract class with parameter Bla Concrete class 1 with data Class 1 object A Abstract class with parameter Bla Concrete class 1 with data Class 1 object B Abstract class with parameter Bla Concrete class 2 with data Class 2 object C and parameter 42 Abstract class with parameter Bla Concrete class 2 with data Class 2 object D and parameter 42 |
Or, les batteries de instanceof
ne me plaisent pas, parce que ça pose des tas de problèmes (comportements incohérents à cause de instanceof
perdus au fond de sous-classes et inconnus de tous, par exemple).
Est-ce que quelqu'un a une solution plus intelligente que la suivante pour supprimer ces instanceof
?
Je modifie l'interface de ClassUser
et assez lourdement l'utilisation. Les classes non réécrites restent les mêmes.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 | package com.spacefox.tests.com.spacefox.tests.lib; public interface ClassUser { void doSomethingWith(ConcreteClass1 something); void doSomethingWith(ConcreteClass2 something); } // - - - - - - - - - - Nouveau fichier - - - - - - - - - - // Utilisation : ConcreteClass1 class1a = new ConcreteClass1("Class 1 object A"); ConcreteClass1 class1b = new ConcreteClass1("Class 1 object B"); ConcreteClass2 class2a = new ConcreteClass2("Class 2 object C"); ConcreteClass2 class2b = new ConcreteClass2("Class 2 object D"); System.out.println("Specified interface implementation"); ClassUser specifiedInterfaceImplementation = new ClassUser() { @Override public void doSomethingWith(ConcreteClass1 something) { commonProcess(something); something.doSomethingSpecificToConcreteClass1(); } @Override public void doSomethingWith(ConcreteClass2 something) { commonProcess(something); something.doSomethingSpecificToConcreteClass2(42); } private void commonProcess(AbstractClass something) { something.doSomethingCommon("Bla"); } }; specifiedInterfaceImplementation.doSomethingWith(class1a); specifiedInterfaceImplementation.doSomethingWith(class1b); specifiedInterfaceImplementation.doSomethingWith(class2a); specifiedInterfaceImplementation.doSomethingWith(class2b); |
+1
-0