Review ====== Four principles of class design: * The open-closed Principle (OPC): a module should be closed for use, and open for extension. * The Liskov Substitution Principle (LSP): we can use the subclass in a situation in which we expect the superclass. * The Dependency Inversion Principle (DIP): depend on abstractions, not on implementations. * The Interface Segregation Principle (ISP): give to each client only the interface that the client needs. Principles of Package Architecture ================================== 1) We have seen that we use a class as a unit to group similar concepts. Is there a need for a larger granule of organization? - Namespace - Release - Maintainability - Increase understandability 1.1) How do we call this larger compositions? 2) How to partition classes among packages? 3) What are the relationships between packages? 4) How these packages should be fisically represented? Java packages ------------- 1) What is a java package? 2) How to create a package? $> mkdir test $> cd test $> vim A.java "package test; public class A { public static void main(String args[]) { System.out.println("Hello"); } }" $> javac A.java $> cd .. $> java test.A 3) What are packages good for? 4) Is there a convention to name packages? The prefix of a unique package name is always written in all-lowercase ASCII letters and should be one of the top-level domain names, currently com, edu, gov, mil, net, org, or one of the English two-letter codes identifying countries as specified in ISO Standard 3166, 1981. Subsequent components of the package name vary according to an organization's own internal naming conventions. Such conventions might specify that certain directory name components be division, department, project, machine, or login names. Ex.: com.sun.eng 5) Why are package names like this? 6) How to reuse the classes in a package? public class C{ public static void main(String args[]) { System.out.println(com.B.getOne()); } } 7) The path till B must be visible in the CLASSPATH. What is this CLASSPATH? $> mkdir test $> cp C.java test $> cd test $> javac -cp "../" C.java $> java -cp ".:../" C 8) Ok, it is annoying to write com.B every time I want to use the type B. What can I do? import com.B; public class C{ public static void main(String args[]) { System.out.println(B.getOne()); } } 8.1) What is "import com.*"? 9) Which classes go into the same package? - Place the classes of a framework in the same package. - Classes in the same inheritance hierarchy typically belong in the same package. - Classes related to one another via aggregation or composition often belong in the same package. - Classes that collaborate with each other a lot, information that is reflected by your UML Sequence diagrams and UML Collaboration diagrams, often belong in the same package. 10) How to represent java packages? - UML package diagrams: 10.1) What can I have inside a package symbol? 10.2) Which relation exists between packages? 11) How do I release a java package? $> jar -cf com.jar com/*.class 11.1) What is really a jar file? $> cd test $> javac -cp "../com.jar" C.java $> java -cp ".:../com.jar" C 12) What are jar files good for? - Security - Decreased download time - Compression - Versioning - Portability Principles of Package Architecture ================================== ****************************** REP ****************************** * The Reuse/Release Equivalnce Principle (REP): The granule of reuse should not be smaller than the granule of release. 13) What is reuse? Is copy'n paste reuse? Is file copying reuse? 13.1) What does it mean to treat software as a product? - Use the code, don't maintain it, don't distribute it. 14) Imagine that Java's hash table has changed. HashMap depends on LinkedList. Do I have to download both HashMap and LinkedList? "Software that is designed to be reused should also be designed to be released, and should; thus, be arranged in a packge for release." ****************************** CRP ****************************** * The Common Reuse Principle (CRP): Classes that are reused together should be packaged together. 15) Can you give me examples of classes that should be reused together? - iterator and container. - Buttons, labels and windows. - Socket server and socket connection. 16) Why is it good to package these classes together? ****************************** CCP ****************************** * The Common Closure Principle (CCP) A change that affects a package should affect as many classes in the package as possible. 17) If the code in an application must change, where would you like those changes to occur: all in one package, or distributed through many packages? 18) How to concentrate the changes into single packages? - Group in packages classes that might change for the same reasons. 18.1) Examples? 19) What is the best kind of package, in terms of maintainability? - a package that does not depend on anything, and that nothing depends on; however, giving that this scenario is unrealistic, the classes in the package should depend on the same interfaces and classes. ****************************** ADP ****************************** * The Acyclic Dependencies Principle (ADP) The Dependency structure between packages must be a directed acyclic graph (DAG). That is, there must be no cycles in the dependency structure. 20) What is again, the notation for dependencies between packages? 21) What happens when MyDialog is released? 21.1) In order to change a method of MyTask, which packages must be recompiled? - only MyApplication, which depends on MyTask. 21.2) In order to change a method of Window, which packages must be recompiled? - All of them. 22) What is the process of releasing this kind of software? 23) Now, which problems can we have to maintain the project in slide "Question 3"? 23.1) In order to release MyTask, we have to check compatibility against whom? - Everybody. 24) Now, MyApplication, MyDialogue and MyTask must all be compatible. Why? 25) What is the dependency from MyDialogs to MyApplications? package MyDialogs; public class A { public void m() { MyApplication.B b = new MyApplication.B; b.f(); } } package MyApplication; public class B { public void f() { ... } } 26) How to remove the cyclic dependency? First solution, inverting the dependency: package MyDialogs; public interface MyB { void f(); } public class A { public void m() { MyB b = new MyApplication.BImp(); b.f(); } } package MyApplication; public class B { public void f() { ... } } public class BImp implements MyDialogs.MyB { B b; public void f() { b.f(); } } Second solution: package Dummy; public class B { public void f() { ... } } package MyDialogs; import Dummy.B; public class A { public void m() { Dummy.B b = new Dummy.B; b.f(); } } package MyApplication; // Make MyApplication to use Dummy.B instead of MyApplication.B ****************************** SDP ****************************** 27) We talked about immobility as one of the problems in the design of software. What is it again? - A design is immobile if it is hard to reuse. 28) Can you give an example? public class Control { public void copy(KeyboardInput i, PrinterOutput p) { int d; while ((d = i.readNextKey()) != -1) { p.printData(d); } } } 29) How did we fix this design? 30) Let's enumerate the problems with the Control module above: - It uses very specific objects, so it is hard to reuse. - It depends on objects which can change in the future, so it makes the software rigid. 31) But why then, are the dependencies below not malign? public class Control { public void copy(Input i, Output o) { int d; while ((d = i.read()) != -1) { o.write(d); } } } 32) The class Control is very stable, why? 32.1) Which forces could force changes on Input and Output? Which modules they depend on? 32.2) What are the consequences of changing Input or Output? "Input and Output do not depend on anything, so, they are unlikely to change. It is good to depend on them!" - they are INDEPENDENT. - on the other hand - "Many classes certainly depend on Input and Output, so, the cost to change them is very heavy." - they are RESPONSIBLE. - thus - "A module that does not depend on anything, but that a lot of things depend upon have no reason to change, and lot of reasons not to." * The Stable Dependencies Principle (SDP): A package p should only depend on packages that are more stable than p. Some packages will change a lot. Others will change very little. The ones that change a lot should depend on the ones that don't, but not vice-versa. 33) SDP is very similar to DIP. Why? 34) 10 packages depend on package A, and 100 packages depend on package B. Which one is easier to change? 35) Package A depends on 10 packages, and package B depends on 100. Which one is more stable? Volatility, V(P) = Ce / (Ca + Ce), where Ce = number of packages that P depend upon Ca = number of packages that depend on P 36) What does it mean V(P) = 0 => ce == 1 => P does not depend on anything => responsible and independent V(P) = 1 => ca == 0 => nobody depends on P => irresponsible and dependent "The closer to 0, the more stable the package." 37) According to SDP, how should be the relation between V(P) and V(P'), if P depends on P'? - The metrics should decrease in the direction of dependency. 38) Should we have instable packages in a system? 38.1) What is the ideal configuration for a system with three packages? 1 -> 0 <- 1 ****************************** SAP ****************************** * The stable Abstractions Principle (SAP) The abstractions of a package should be in proportion to its stability. 39) How to measure the degree of "abstractness" of a package? A(P) = # interfaces in P / # total classes of P 40) What would we get if we plot a graph of Abstractions versus Volatility? 40.1) What would be (0, 1) => only abstractions that everybody depends upon. 40.2) What would be (1, 0) => only concretions that nobobyd depends upon. 41) What are the bad places to be on this graph? 41.1) What is (0, 0)? => a package with no interfaces, and a lot of packages depend upon. 41.2) Why is this bad? Because this package is ridig. 41.3) Are there applications that fall close to this point (0, 0)? - String - Math - Databases 42) What is (1, 1)? A package with only interfaces, that depends upon a lot of other packages. 43.1) Any examples?