Sunday, October 27, 2013

JUnit, Maven - Unit testing Java Code



Ok I got my app up and running ready to fire and forget.. or am I?

You should clarify your question to define what is meant with "start testing".
Take a look on this diagram :
BR vs. UC

There are various aspects of tests.

They are defined and run at all phases across Software Development Life Cycle (SDLC):
  • Acceptance Tests are defined just at the same time with Business Requirements - e.g. they are defined at the very beginning of an SDLC and run at the very end;
  • System Tests are defined along with SRS and are usually run for each alpha/local release;
  • Integration Tests are "mid-range" tests for components; They are defined and run pretty often, e.g. on weekly scrums;
  • and so on, till the very low-level Unit Tests that are defined and run on practically the same time;
Moreover there are tests like
  • behavioral tests (BDD)
  • mutation tests - made to test if existing tests are picking the improper states of a tested software. IE. check if tests are correct and sufficiently cover the requirements that have originated the implementation.
    So the answer to the question is:

    You should define and run different types of your tests at all phases of entire SDLC.
    Actually there is a whole technique of software development based on tests that are used to specify the requirements that should be met by the developed app code. It is called Test Driven Development (TDD) and will be covered in following articles.

    Here is a brief teaser of TDD from Marcin 

    What are the unit tests? 

    Every software that is being developed can be divided into many small bricks that builds it. Each brick i.e. a simple piece of code has its input and its output values. Regarding Java the code is divided into classes with methods. Thus it is reasonable to consider a method as a code unit that has its IN/OUT results. Even in case of void class it has its programmed behavior changing a state, that we can consider as a result.
    As we consider the unit tests the smallest unit of code that each unit test target is a method (or a class).
    The tests are extra classes end methods to ensure that actual code works as intended.
    The more part of the application has tests the bigger test coverage it gets and more stable it gets.
    The tests however, are not part of the source code and therefore they reside in their own directory or even project. While developing the app with maven archetypes most of them cover the following directory/package structure:

    my-app 
    |-- pom.xml
    `-- src
        |-- main
        |   `-- java
        |       `-- com
        |           `-- mycompany
        |               `-- app
        |                   `-- App.java
        `-- test
            `-- java
                `-- com
                    `-- mycompany
                        `-- app
                            `-- AppTest.java

    JUnit - framework for unit testing

    The JUnit is one of the most popular frameworks that makes unit testing simple and robust.

    Along the use of JUnit we will be basing on two major concepts i.e. annotations and static methods in form of assertions. Both are part of JDK and are widely used along Java environment.
    JUnit is provides us with its own set of annotations and assertions.

    Adding JUnit to our Maven Project.

    Installation of JUnit is as simple as adding the maven dependency regardless of IDE :

    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>4.11</version>
      <scope>test</scope>
    </dependency> 

    Now running the potential tests using plain console maven syntax is straightforward.
     
    mvn test

    JUnit testing basics

    To create a simple test first let us explain how to point what part of code do we want to test and what are expected conditions to be fulfilled by the tested code.
    1. Annotations: How to establish the tested code?
      We now know that test as a code has separate folder. Now let us mark each testing method. JUnit uses annotations to identify methods that specify a test. In general these test methods are contained in a class which is only used for testing, also known a Test class. The testing method will be pointed with the @org.junit.Test annotation and must be a public method.
      Below we present the basic annotations:
      Annotation Description
      @Test
      public void method()
      The @Test annotation identifies a method as a test method.
      @Test (expected = Exception.class) Fails, if the method does not throw the named exception.
      @Test(timeout=100) Fails, if the method takes longer than 100 milliseconds.
      @Before
      public void method()
      This method is executed before each test. It is used to can prepare the test environment (e.g. read input data, initialize the class).
      @After
      public void method()
      This method is executed after each test. It is used to cleanup the test environment (e.g. delete temporary data, restore defaults). It can also save memory by cleaning up expensive memory structures.
      @BeforeClass
      public static void method()
      This method is executed once, before the start of all tests. It is used to perform time intensive activities, for example to connect to a database. Methods annotated with this annotation need to be defined as static to work with JUnit.
      @AfterClass
      public static void method()
      This method is executed once, after all tests have been finished. It is used to perform clean-up activities, for example to disconnect from a database. Methods annotated with this annotation need to be defined as static to work with JUnit.
      @Ignore Ignores the test method. This is useful when the underlying code has been changed and the test case has not yet been adapted. Or if the execution time of this test is too long to be included.


    2. Assertions: How to setup test expectations and conditions?

      Now that we know which method will be the testing method we have to check the expected result of the code execution versus the actual result. For this we will utilize a method provided by JUnit in for of assertion methods. The assertion methods provided by JUnit allows to specify an expected result, the actual outcome of the tested method and an error message. The assertion is used here to compare the actual returned value to the expected one and to produce an error in case this comparison fails.
      This is important to remember that assertion should NOT be left in production code. It is made for tests and thus should be present only in this stage of development.

      Here is a brief explanation of some of the assertion methods:

      Statement Description
      fail(String) Let the method fail. Might be used to check that a certain part of the code is not reached. Or to have a failing test before the test code is implemented. The String parameter is optional.
      assertTrue([message], boolean condition) Checks that the boolean condition is true.
      assertFalse([message], boolean condition) Checks that the boolean condition is false.
      assertEquals([String message], expected, actual) Tests that two values are the same. Note: for arrays the reference is checked not the content of the arrays.
      assertEquals([String message], expected, actual, tolerance) Test that float or double values match. The tolerance is the number of decimals which must be the same.
      assertNull([message], object) Checks that the object is null.
      assertNotNull([message], object) Checks that the object is not null.
      assertSame([String], expected, actual) Checks that both variables refer to the same object.
      assertNotSame([String], expected, actual)

    At this moment we know that each method in application code can have a test methods that can check tested method behavior for given input conditions. However there is one important rule:
    Each method can be called in arbitrary order so tests must NOT depend on each other's result.

     JUnit basic examples


    • Simple Test annotation:

      @Test
      public void testIndexOutOfBoundsException() {
        try {
          List list = new ArrayList();
          list.get(1);
          fail("Expected exception throw IndexOutOfBoundsException");
        } catch (IndexOutOfBoundsException e) {
          assertEquals(e.getMessage(),  "Index: 1, Size: 0");
        }
      }

      Here we can see that the tests relates to a get() method from the List interface. So for now, we only test one specific usage of a standard Java collection. As we try to get second element (indexed from 0) from an empty ArrayList  this will get us an IndexOutOfBoundsException. At least we expect it to act this way because line with the fail assertion is always assumed not to be reached.
      Moreover we use the asserEquals  checks if the error is as expected.

    • Expected exception:

      @Test(expected = IndexOutOfBoundsException.class)
        public void testIndexOutOfBoundsException() {
          List list =  new ArrayList();
          list.get(1);
      }


      Here the example is similar but the annotation is informative enough to tell that the IndexOutOfBoundsException test method will fail if test is not going to be rised during the method call.

    • Expected time of execution

      @Test(timeout = 1000L)
      public void searchPersonByName(){
        Person person = dao.search("John");
        assertEquals(person.getName(), "John");
      }

      This annotation states that the test is going to fail if the method execution will last longer that 1000 ms. As we can see the dao object is probably going take some time to access the data store, so we assure that any drawbacks e.g. with connection will not slow down the testing procedure longer than 1000 ms. Moreover, we check if the return value is actually "John".

    • Parametrized:

      @RunWith(Parameterized.class)
       public class FibonacciTest {
              private int fInput;
              private int fExpected;
       
              public FibonacciTest(int input, int expected) {
                      fInput= input;
                      fExpected= expected;
              }
      
              @Parameters
              public static Collection<Object[]> data() {
                      return Arrays.asList(new Object[][] {
                                      Fibonacci,
                                      { { 0, 0 }, { 1, 1 }, { 2, 1 }, { 3, 2 }, { 4, 3 }, { 5, 5 },
                                                      { 6, 8 } } });
              }
       
              @Test
              public void test(@HeresHowYouGetValue Type value) {
                      assertAnswerKey(new Object[][] {
                                      Fibonacci,
                                      { { 0, 0 }, { 1, 1 }, { 2, 1 }, { 3, 2 }, { 4, 3 }, { 5, 5 },
                                                      { 6, 8 } } });
                      assertEquals(fExpected, Fibonacci.compute(fInput));
              }
       }

      Here we have a parameterized test example that allows developer to run the same test over and over again using different values. In this test we got  a public static method annotated with @Parameters that returns a Collection of Objects (as Array) as test data set. A public constructor can take in what is equivalent to one "row" of test data. The JUnit then asserEquals if the @Parameters values passed to an object and processed with the compute method are the same as  the expected value.

    • Expected time of execution:

      public static class HasExpectedException {
              @Rule // test would work same without this rule
              public ExpectedException thrown= ExpectedException.none();
       
              @Test
              public void throwsNothing() {
          			// we don't expect exception and there is none, so: PASS.
              }
       
              @Test
              public void throwsNullPointerException() {
                      thrown.expect(NullPointerException.class);
                      throw new NullPointerException();
              }
       
              @Test
              public void throwsNullPointerExceptionWithMessage() {
                      thrown.expect(NullPointerException.class);
                      thrown.expectMessage("has happened?");
                      thrown.expectMessage(startsWith("what"));
      
                      throw new NullPointerException("what has happened?");
              }
       }

      Here all tests will pass. In this case we define a test behavior based on what exception is going to be thrown in each method and match the @Rule. In each method first we setup the expected exception then the expected exception is thrown. Therefore all tests pass. Additionally in last test method we also check if the thrown exception's message consists of a specific string. 

    Wednesday, September 11, 2013

    Composition with Interfaces - The best of the two worlds.


    It is essential in Java to understand the sense of interfaces. It is straightforward that Java API is designed not give the access to specific capabilities but to define abstract interface through which your programs talks to the underlying source. For example this is how SWING works giving you the interface GUI same on any machine running JVM.
    Java encourage separation of interface from implementation with use of java interface construct.
    Dividing code to functional parts and defining communication using interfaces is the most general rule of software design. In Java interface is a 100% abstract interface for interaction with the code implementing it. Other words there is common interface for communication of different implementations.

    We have already talked about the other aspect - composition in articles [see1][see2]. We have talked about some advantages of flexibility concerning composition.
    We need to elaborate more on one “disadvantage” of composition regarding inheritance. That is that it is easier to add new subclass in inheritance (because of polymorphism) that to add new front-end class in composition unless composition comes with interfaces.

    Let us present example to express the polymorphism of composition with interfaces.

    interface CanTurn {
        void turn();
    }
    
    class Vehicle {
        public void turn() {
            System.out.println("Turnning Car.");
        }
    }
    
    class Car implements CanTurn {
    
         private Vehicle vehicle = new Vehicle();
         public void turn() {
             return vehicle.turn();
         }
    }
    
    
    class Driver{
         static void turnMachine(CanTurn item) {
             item.turn();
         }
    }
    
    class MainClass{
    
           public static void main(String[] args) {
                  Car car = new Car();
                   Driver.turnMachine(car);
            }
    }
    


    But now we have an interface that lets us create a new class:

    class Bike implements CanTurn {
    
           private Vehicle vehicle = new Vehicle();
    
           public void turn() {
                    return vehicle.turn();
            }
    }
    

    Car and Bike both has a composition relationship with Vehicle. We reuse a Vehicle’s implementation of turn() method using explicit delegation i.e. invoking turn() on it own Vehicle object. On the other hand Bike can also be passed to turnMachine() method from Driver class because Bike also implements interface CanTurn.
    As we have mentioned composition is more flexible but inheritance is easier to understand.


    The considerations about composition and inheritance are in the other article but the general rule that holds is that:
    if  (relationship is a permanent IS-A relationship along the application){
         use inheritance
    }else{
          use composition
    }

    Summary


    Interface is a tool for achieving flexibility in Java. Any class can provide  an implementation of an interface. Not changing the interface is crucial. Apart from changing interface all changes to implementation classes or adding new classes does not impact the code that is based only on the interface.
    In any subsystem that may have many implementations with a common abstraction interface there needs to be a Java interface on top of it. By dint of this approach any client wanting to use this subsystem can easily utilize any of the implementations without need to take care of their mechanisms. Just as it is in case of JVM and operating systems. This assures low or none coupling between parts of your system. What is more the code is more easily changed, extended and customized. The flexibility of code is something that comes with interfaces and brings all of the goodies of composition to the land of polymorphism. The best of the two worlds.

    Composition vs Inheritance choice - the true story.


    As an inexperienced developer keeps diving into new ideas of software design, a time will come when the contradiction between composition and inheritance became the question.
    Composition over Inheritance is a popular principle in Object Oriented design. Below we will try to make things clear about the choice from between those two along the development process.


    Before we even move forward we assume that the terms of a basic software engineering terms such as aggregation, association and the UML basics are clear to the reader [see our article].
    In object oriented design it is a fundamental activity to establish class relations. The functionality two discussed methods - composition and inheritance - are

    Let us first consider the nature of both terms.
    One of the fundamental activities of an object-oriented design is establishing relationships between classes. Two fundamental ways to relate classes are inheritance and composition. It is worth mentioning that you can get at the functionality of inheritance when you use composition. This article will compare these two approaches to relating classes and will provide guidelines on their use.

    Composition

    As the name itself tell the composition is about  building something out of smaller parts. The key to understand composition in a right way is to understand aggregation and association. In this article we will focus around composition as a instance variables referencing to other objects.

    public class A{
        private B b = new B();
    }

    Inheritance

    Along this article inheritance would mean a single inheritance through class extension.
    public class A{...}
    public class B extends A{...}
    

    Benefits of inheritance:
    • advantage of dynamic binding.
      Dynamic binding is a JVM mechanism that is responsible for choosing which method
      implementation will be invoked at runtime based on the class of the object.
    • Polymorphism -
      In general means to use a variable of a superclass type to hold a reference to an object whose class is the superclass or any of its subclasses
    Both of the above can help make code easier to change. This is nice as long as you want to add a new type of a subclass.
    However, this is not the case when the change involves class structure.

    Composition vs Inheritance


    The superclass in inheritance is often referred to as a fragile. It is because one change in superclass structure will force changes in many subclasses. The fragile part of superclass is its interface. In case of a well-designed superclass with a clean separation of interface and implementation in the object-oriented style, any changes to the superclass's implementation shouldn't cause problems at all. However, if we try to change the interface even the best design will not help breaking subclasses code.

    Example:

    public class A {
        //interface method:
        public int m1(){...} // change int to Integer return value 
    }
    

    The change of the type from int to Integer can cause errors in subclasses that invokes that method on any reference of type A. What is more even if subclasses override this method this would also cause braking code. The only way to solve this problem is to move along the entire A class inheritance hierarchy and modify every interface part that need to conform the new look of the superclass.
    What is more, if you have code directly using subclass of a A class that the code will also suffer from superclass interface modification. That is the reason to state the inheritance provide “weak encapsulation”.
    Inheritance allows subclass to reuse code from superclass if it is not overriding it. However, the subclass of A only “weakly encapsulates” the A class code it is reusing, as the changes to A’s interface can break code that directly uses such subclass.


    In such situation let us move to alternate solution provided by composition. In terms of code reuse, composition turns out to be more code changing friendly.

    • Inherited code reuse

    Let  us consider some code using
    inheritance:

    class A {
         // Return int value  resulted from the method activity.
        public int method1() {
          System.out.println("Method 1. from class A");
          return 1;
        }
    }
    
    class B extends A {}
    
    class MainClass {
    
      public static void main(String[] args) {
        B b = new B();
        int v = B.method1();
      }
    }
    

    The application would result in printout of: “Method 1. from class A”, because B inherits (therefore, reuses) A’s implementation of method1(). However, if in the future one would want to change the construction of method1() in A class, then the entire application would broke. This would happen even if the use of A class is indirect through the B class.
    • Composed code reuse
    The same example can be handled with composition.

    class A {
        // Return int value  resulted from the method activity.
       public int method1() {
          System.out.println("Method 1. from class A.");
          return 1;
       }
    }
    
    
    class B {
    
        private A aVar = new A();
    
       public int method1() {
          return aVar.method1();
       }
    }
    
    class MainClass2 {
    
    public static void main(String[] args) {
    
        B b = new B();
        int v = b.method1();
      }
    }
    

    In this approach the B class due to composition construct, becomes front-end class while the superclass A plays a role of back-end class. In contrast to inherited version we have an overridden implementation or pure code reuse from superclass in other case. With composition we have an explicit method call to the method of the back-end superclass. This is sometimes called forwarding or delegation.
    What is more composition brings stronger encapsulation than inheritance. It is because each time we change a method from superclass the code relying on the subclass is not broken. So e.g. changing the method1() return value from A class would not force change in the interface of class B and thus no problems caused in the main application using the B class only. The problem might arise in class B method1() but not in the main app.
    This way the main project is not affected. 

    Compare & Contrast: composition & inheritance


      1. As shown in previous section it is much less complicated to propagate changes from back-end class down the hierarchy with composition that it is superclass down the inheritance hierarchy.
        In
        composition, change to the back-end class interface would force possible changes in front-end class implementation but not its interface. Therefore the change does not have to propagate. The code depending on front-end class interface still can work if it interface does not change with the back-end class interface change.
        In case of
        inheritance any change to superclass’s interface would not only force changes down the inheritance hierarchy of classes but will cause problems with the code using those classes.
      2. The problem however arises also when we try to modify the second classes: front-class in case of composition or subclass in case of inheritance.
        In
        inheritance it is impossible to change the subclass’s interface in a way that is not confirming the compatibility with the superclass interface. E.g. it is not possible to add to the subclass a new method with the same signature but with different return type as a method inherited from superclass.Composition allows the change of interface of front-end class without affecting back-end classes.
      3. The aspect of object creation. Composition is capable of lazy creation of back-end objects until they are really needed and what is more, the back-end objects can be changed during the lifetime of the front-object.
        Inheritance on the other hand creates superclass part as soon as subclass is being created. It is part of a subclass object to the end of its lifetime.
      4. Polymorphism of inheritance comes with ease of creation of new subclasses. A superclass interface code will work with any new subclass created.Composition without use of interfaces does not bring such feature. However adding interface to composition can overcome this limitation. [see article]
      5. In most cases the performance of explicit method invocation forwarding (delegation) from composition is less efficient comparing to single invocation of an inherited superclass method implementation. This is however mostly JVM related.

    When Compose when Inherit?


      The A,B,C rules of thumb.
         
      1. Inherit only when is-a relationship exist. Use inheritance only when the  subclass IS-A superclass:
        e.g. Car is-a Vehicle, Horse is-a Mammal etc.
        What is more this relation must be true along the lifetime of an application using speciffic domain model
        e.g. Employee is-a Person up to a point when an Employee becomes unemployed or a Supervisor. So Employee is not a Person but a role a person plays during the lifetime of application. In this case we should consider composition
      2. The code reuse can not determine the use of inheritance. Only the is-a relationship is valid determinant. Otherwise use composition.
      3. The polymorphism can not determine the use of inheritance. Without IS-A relationship it is enough to use composition with interfaces instead of inheritance. [see article]

      so[L]id 

      Let us mention here one of the most important principles in object-oriented design :
      SOLID (Single responsibility, Open-closed, Liskov substitution, Interface segregation and Dependency inversion). 

      Actually we will focus here only on the L (LSP) part of this acronym.
      objects in a program should be replaceable with instances of their subtypes without altering the correctness of that program.
      Typical violation of this principle is with a specific class that inherits from more general class. E.g. Square inherits from Rectangle. Let us assume we would have a method called calculateField() resulting in field value as a product. Now if we would consider a Square as a Rectangle then it's sides length still must stay the same.
      Now changing the side lengthto the Square i.e. :
      rectangle.setWidth(10);
      rectangle.setHeight(20);
      

      would cause some unexpected behavior because there should be a mechanism assuring that both sides are even in case of Square and in Rectangle there is none. 
      What is more the result of the field would be 100 for square instead expected 200 for rectangle. Therefore this voilates the Liskov substitution as it is not working as expected.

      Friday, September 6, 2013

      Programisty 7 grzechów głównych

      Wszyscy jesteśmy grzesznikami. Jedni są nimi bardzo, inni są nimi mniej.
      Również programiści mają swoje grzechy główne, za których popełnianie będą się smażyć w piekle IT :)

      Grzechy wybitnie dotyczą świeżo upieczonych absolwentów kierunków informatycznych, albowiem uczelnie z tajemniczego powodu rzadko uczą zasad, które opisuję poniżej.

      1.Pycha - nie stosowanie wzorców

      Inżynieria oprogramowania jest pełna wzorców - sprawdzonych, nazwanych i zestandaryzowanych rozwiązań, z których składają się duże systemy informatyczne. Oczywiście zawsze cel można osiągnąć "po swojemu", jednak ryzyko popełnienia błędu jest wysokie, a nawet jeśli się uda - inni żeby je zrozumieć będą potrzebowali dużo czasu i wysiłku intelektualnego.

      Wzorce najczęściej odnoszą się do programowania obiektowego (chociaż nie tylko) i można próbować je klasyfikować w następujący sposób:

      • Wzorce GRASP (skrót od General Responsibility Assignment Software Patterns) - zasady przydziału odpowiedzialności klas.
      • Wzorce GoF (skrót od Gang of Four) - w latach 90 została opublikowana książka "Design Patterns: Abstraction and Reuse of Object Oriented-Design" autorstwa E. Gamma, R. Helm, R. Johnson, J. Vlissides (stąd nazwa gang of four) która identyfikuje 26 wzorców projektowych podzielonych na 3 kategorie:
        • Wzorce konstrukcyjne - definiują i nazywają zasady tworzenia obiektów
        • Wzorce strukturalne - określają sposób łączenia ze sobą obiektów
        • Wzorce behawioralne - kategoryzują sposoby realizacji algorytmów

          Oprócz wzorców wymienionych powyżej świat IT jest pełen innych typów wzorców (wzorce architektoniczne, integracyjne, UI), ale znajomość wzorców GoF i GRASP ma absolutnie fundamentalne znaczenie w pracy programisty.

      2. Chciwość - nie będę dzielił się kodem przy pomocy systemu SCM


      Dawno temu wymyślono SCM (skrót od Source Code Managment). Najpierw popularnosć zdobył CVS - systemy pozwalający dzielić wspólny kod między programistów, rejesstrować historię zmian, gałęzie (odgałęzienia). Potem przyszedł SVN, który działał dużo optymalnie. Teraz popularnośc zdobyły takie rozwiązania jak GIT czy Mercurial - rozproszone systemy kontroli wersji, które działają w bardzo optymalny i wydajny sposób.

      Co z tego ? Częsty jest widok grup programistów dzielących się kodem przez
      pocztę elektroniczną, lub współdzielony zasób. I smutny to widok, bo mimo dobrych chęci - nadpisują sobie kod, a kolejne wersje wywołują chaos.

      Tym co tego nie robili - radzę zapoznać się z systemami SCM, mimo pewnego wysiłku na zapoznanie się nowym narzędziem, jego znajomość przyniesie wkrótce korzyści.

      3. Nieczystość - niestosowanie zasad Clean Code


      Wyobraź sobie że zepsuł ci się rower, chcesz go naprawić i masz do dyspozycji warsztat. Usterka jest nieskomplikowana, ale po wejściu do warsztatu okazuje się że nie możesz znaleźć narzędzi bo są porozrzucane po kątach, kiedy je znajdujesz okazuje się że są brudne i uszkodzone.

      Dokładnie takie mam wrażenie gdy zaglądam do kodu w projekcie przy tworzeniu którego programiści nie znali lub nie trzymali się zasad Clean Code.

      Szczegółowy opis zasad znajdziesz w książce Roberta Martina "Clean Code: A Handbook of Agile Software Craftsmanship", ja opiszę najczęściej spotykane problemy:

      • Klasy składające się z wielu tysięcy linii - jeśli widzę taką klasę to mogę mieć prawie pewność, że klasa jest odpowiedzialna za wiele czynności, przez co kod jest trudny do zrozumienia. Do takiej klasy jest często wiele powiązań. W żargonie takie klasy określane są często jako "boskie klasy" - klasy które realizują wiele zadań, lub "ośmiotysięczniki" - klasy składające się z tysięcy linii. Staraj się pisać tak od klas by powstało wiele małych, dobrze nazwanych klas, realizujących swoje odpowiedzialności.
      • Nic nie mówiące nazwy klas i zmiennych. Ostatnio zajrzałem do projektu, gdzie klasy nazywały się Rot, Enc, Kod, a zmienne w środku rot, dec, ii. Czy coś wam to mówi ? Bo mi nie. Starajcie się nazywać klasy i metody tak by zadania realizowane przez nie były tak oczywiste, by nie  było konieczne analizowanie ich działania ani sięganie do dokumentacji. Wiem, że jednoliterowa nazywa metody albo zmiennej to oszczędność wciskania klawiszy przy kodowaniu, ale wszystkie współczesne IDE mają funkcję podpowiadania nazw zmiennych i wystarczy wcisnąć ctrl+spacja...
      • Brak jasnych komentarzy, brak javadoc - wiem że jeśli pracujesz przy kodzie klasy oczywiste jest dla ciebie co dzieje się w środku. Ale gwarantuję ci, jeśli wrócisz do projektu po 2 latach, nie będziesz wiedział co się dzieje w środku, a zrozumienie tego innym zajmie czasem tyle samo czasu co tobie. Pisanie dobrych komentarzy i javadoc rozwiązuje ten problem, kod jest czytelny, i świadczy o twojej wysokiej kulturze.
      • Metody i konstruktory przyjmujące wiele argumentów - znów chodzi o czytelność. Trudno domyśleć się jakimi dokładnie zasilać danymi metodę, która przyjmuje 10 argumentów, w szczególności gdy część z nich jest opcjonalna i pozwala na użycie null, a część po podstawieniu null - powoduje wyjątek. Dobrą praktyką jest tworzenie metod, które nie posiadają więcej niż 10 argumentów.
      • Fatalne formatowanie kodu - nawet dobrze napisany kod, gdy jest źle sformatowany - wygląda źle. Proponuje używanie formatterów w IDE, i skonfigurowanie tego tak, by w momencie zapisu - kod był formatowany.

      4. Zazdrość - nie dzielenie się projektem przez SCM

      Świat IT od lat zna rozwiązania potrafiące zapewnić możliwość pracy kilku osób nad wspólnym kodem. Jeśli okaże się że dwie osoby w tym samym czasie edytowały plik, systemy SCM potrafią rozwiązać takie konflikty automatycznie, lub wspomóc w manualnym rozwiązaniu konfliktu. Możliwe jest śledzenie zmian, cofanie się w dowolny moment czasu, tworzenie wersji kodu (odgałęzień). Kiedyś był CVS, potem SVN, teraz królują takie rozwiąznaia jak GIT i Mercurial.
      Co z tego, jeśli wielu świerzo upieczonych programistów nie wie co to system kontroli wersji. I smutek wywołuje widok 5 programistów programujących w grupe, wysyłających sobie kawałki kodu mailem, albo trzymających kod na wspólnym zasobie sieciowym. Po co się męczyć, skoro są dedykowane systemy współdzielenia wersji, i tylko trzeba włożyć trochę wysiłku w ich poznanie...

      5. Nieumiarkowanie w jedzeniu i piciu pisaniu na kosolę

      Każdy stawaiający swoje pierwsze nieśmiałe kroki programista robi błędy. Błędy te również próbuje lokalizować.Schemat zwykle jest taki sam - po skompilowaniu naszego i uruchomieniu naszego kodu okazuje się, że uruchomiony plik binarny nie funkcjonuje w zamierzony sposób. Jakie genialne rozwiązanie nasuwa się samo ? Umieścimy w kodzie całe mnóstwo poleceń System.out.println(...), jeśli ma być kolorowo, to możemy nawet sięgnąć po Sysstem.err.println(). Zamierzony efekt zostaje szybko osiągnięty -na konsoli pojawiają się wartości zmiennych, nierzadko przeplatanych losowymi lub wulgarnymi słowami (które łatwiej pozwalają nam zlokalizować miejsce ich występowania. Teraz wyobraźcie sobie że kilku albo kilkunastu programistów spotyka się przy pracy nad projektem. Szybko konsola wypełnia się niezrozumiałymi komunikatami, trudno odróżnić moje linijki od kolegów. Log przesuwa się tak szybko że trudno orientować się co się dzieje. Co gorsza taki system może się sprzedać i później administrator serwera zastanawia się jakim cudem po 3 dniach pracy systemu plik dziennika błędów systemu ma więcej niż 1GB. Czy wymyśliłem tą sytuację ? NIE. Sam widziałem takie przypadki wiele razy, sam pisałem uparcie na konsolę.
      Czy jest jakaś alternatywa ? No pewnie że jest. Nawet więcej niź jedna.
      Używaj debugera wbudowanego w IDE. Java ma możliwosć świetnego debugowania. Wystarczy w twoim ulubionym IDE postawić breakpoint, twój program zatrzyma się w odpowiednim miejscu a IDE  da ci możliwość śledzenia zawartości wszystkich zmiennych i wykonywania programu krok po kroku, z możliwością podglądu aktualnie wykonywanej linijki.
      Druga możliwość - skorzystaj z Loggera. Artykuł ciekawy wpis autorstwa Michała znajdziesz tutaj


      6. Gniew - u innych którzy będą pracowali z twoim kodem wywoła:

      • nieumieszczanie sensownych komentarzy w kodzie
      • nieumieszczanie Javadoc-ków

      7. Lenistwo - grzech nienapisanego kodu


      Gdy jesteś programistą, to zwykle - wcześniej lub później będziesz miał okazję w swoim kodzie używać bazy danych.

      Jak kod wyglądać powinien ?
            //1 - potrzebujemy deklaracji pól tutaj, by później można było próbować je zamknąć
              Connection conn = null;
              Statement stmt = null;
              try {
                  //2 - ładowanie sterownika JDBC
                  Class.forName(DB_DRIVER);
                  //3 - łączenie z bazą
                  conn = DriverManager.getConnection(DB_URL, DB_USER, DB_PASS);
                  //4 - wykonanie zapytania
                  stmt = conn.createStatement();
                  String sql = "SELECT * FROM klienci";
                  ResultSet rs = stmt.executeQuery(sql);
                  //5 - pobieranie wyników
                  while (rs.next()) {
                      int id = rs.getInt("id");
                      int age = rs.getInt("wiek");
                      String first = rs.getString("imie");
                      String last = rs.getString("nazwisko");
                      System.out.printf("%s %s\n",first,last);
                  }
                  //6 - obsługa wyjątków
                  rs.close();
                  stmt.close();
                  conn.close();
              } catch (SQLException se) {
                  //Obsługa błędów JDBC
                  se.printStackTrace();
              } catch (ClassNotFoundException e) {
         // W przypadku nieznalezienia sterownika jdbc niewiele możemy zrobić
         e.printStackTrace();
        } finally {
                  //finally block used to close resources
                  try {
                      if (stmt != null) {
                       //jeśli wystąpiły błędy to musimy spróbować zamknąć statement
                          stmt.close();
                      }
                  } catch (SQLException se2) {
                   //jeśli się nie udało - nic już nie możemy zrobić
                  }
                  try {
                      if (conn != null) {
                       //próba zamknięcia połączenia, jeśli istnieje
                          conn.close();
                      }
                  } catch (SQLException se) {
                   //jeśli nie udało się go zamknąć - komunikat
                      se.printStackTrace();
                  }
              }
      
      
      jak widać banalne zadanie pobrania danych z bazy wiąże się z koniecznością zadbania o zamykanie obiektów Connection, Statement. zasoby te trzeba zamykać nawet wtedy gdy pojawia się wyjątek (w sekcji finally) A najczęciej wygląda tak:
        
      
         // 1 - ładowanie sterownika JDBC
         Class.forName(DB_DRIVER);
         // 3 - łączenie z bazą
         Connection conn = DriverManager.getConnection(DB_URL, DB_USER, DB_PASS);
         // 4 - wykonanie zapytania
         Statement stmt = conn.createStatement();
         String sql = "SELECT * FROM klienci";
         ResultSet rs = stmt.executeQuery(sql);
         // 5 - pobieranie wyników
         while (rs.next()) {
          int id = rs.getInt("id");
          int age = rs.getInt("wiek");
          String first = rs.getString("imie");
          String last = rs.getString("nazwisko");
          System.out.printf("%s %s\n", first, last);
         }
         // 6 - obsługa wyjątków
         rs.close();
         stmt.close();
         conn.close();
        } catch (Exception ex) {
         ex.printStackTrace();
        }
      
      
      Jeśli przy pobieraniu wyników wystąpi wyjątek, to obiekt Statement nie zostanie nigdy zamknięty. W praktyce najczęściej oznacza to same problemy....


      Thursday, September 5, 2013

      From Asotiation to Composition & More.

      Association, Aggregation, Composition, Inheritance - what are those?
      (OOP, UML)


      Either association and aggregation  topic terms are both concepts of software design. They are considered in terms of relation between two classifiers, such as classes (but also use cases), that describe the relation reasons and rules  that governs it.
      In this article we assume readers basic knowledge of UML class diagrams.


      A relationship is a general term covering the specific types of logical connections found on class and object diagrams in UML.
      Below we will try to focus on gathering information about a relationship between classes of objects:


      Inheritance > Composition > Aggregation > Association > Link


      Link

      The most general relationship is Link. It simply only gives a notion of a relation not describing its particular properties. A link is a relationship between objects or instances of the classifiers. In general Link is an instance of an association, while an association is a relationship between two classifiers.
        

      Association: uses a

      Ex:a Class Man uses a Class Pen
      It is the weakest of all relations. An association represents a structural relationship that connects two classifiers. Like attributes, associations record the properties of classifiers.


      For example, in relationships between classes, you can use associations to show the design decisions that you made about classes in your application that contain data, and to show which of those classes need to share data. You can use an association's navigability feature, to show how an object of one class gains access to an object of another class or, in a reflexive association, to an object of the same class.    The name of an association describes the nature of the relationship between two classifiers and should be a verb or phrase. In the diagram editor, an association appears as a solid line between two classifiers.

      In General:

      • temporal relation between objects
      • objects associated are independent (deleting one does not mean delete second)
      • associated objects contain reference to the other object
      • In Java equal to field

      Example:

      Passenger knows about his ticket reservations and reservation knows about who is its owner. In case reservation does not have reference to passenger when the association is unidirectional type (with an arrow in UML). With bidirectional association there are no arrows and both objects have references to each other


        • In Java


      The association relationship is a way of describing that a class knows about and holds a reference to another class. This can be described as a "has-a" relationship because the typical implementation in Java is through the use of an instance field. The relationship can be bi-directional with each class holding a reference to the other. Below there is a bi-directional association implemented many-to-one in Java using fields:

      public class Department {
      
      private Set staff = new HashSet();
      ...
      }
      
      public class Employee {
      
      private Department department;
      ...
      }
      

      To make it uni-directional, one of the classes would not have its relation field.

      What is the problem with a bi-directional association?

      Unlike a relation in a RDBMS, a bi-directional association is stored on two ends. Lets illustrate it with example. We want to add a new employee to a department:

      Department sales     = DepartmentsStore.getDepartment(...);
      Department it        = DepartmentsStore.getDepartment(...);
      
      Employee john = Employees.getEmployee(“john_id”);
      
      john.getDepartment(); //  Lets say JOHN works in “IT” dept.
      
      john.setDepartment(sales); //!? 
      


      This would not work. We would still had to add “john” to “sales” and remove him from “it”:
      sales.getStaff().add(john);
      it.getStaff().remove(john);
      
      So we have to take care of all this maintenance. Otherwise the application would collapse. And you can imagine in how many places this would have to be repeated in enterprise application.
      Lets make it more OOP in terms of behaviour and responsibilities. We would have to consider business logic. Thats why we assume that the hire/fire is responsibility of Department.

      public void hire(Employee employee)throws HumanResourceException {
      staff.add(employee);
      }
      
      public void fire(Employee employee) throws HumanResourceException {
      
      if (!staff.contains(employee)) throw new HumanResourceException("Employee does not work at this department");
      
      staff.remove(employee);
      
      }
      
      But this is only the Department part not the Employee state needs to be modified:
      void _changeDepartment(Departmentdepartment) {
          assert this.department == null;
      
          this.department = department;
      }
      
      void _removeFromItsDepartment() {
          assert this.department != null;
          this.department = null;
      
      }
      


      But still those methods should be used only by Department and there is no way to limit the scope of a method to one other class. You can only put it to the same package and follow convention of underscore meaning “used internally”.

      This is still ugly and do it at home or work by yourself.


      Aggregation: has a

      Ex:a Class Man has a Class Car ( Car is still there when Man die )
      Aggregation (white diamond) has no semantics beyond that of a regular association. It is, as Jim Rumbaugh puts it, a modeling placebo. People can, and do, use it - but there are no standard meanings for it. So if you see it, you should inquire as to what the author means by it. I would advise not using it yourself without some form of explanation.       
      - Martin Fowler


      This relationship is described as a “has-a” or “whole/part” relation between two classes. It is more strict relation than association. One of the classes - so called aggregate class - contains reference to the second class and is therefore said to have ownership of that second class. The class that is being referenced from within aggregate class is considered to be part-of the aggregate class. Aggregation is a stronger case of association as a directional association between objects.
      You can say that you have aggregation between two objects when an object
      “has-a” another object. The additional information about relation’s direction is determined by deciding which object contains the other object.

      In General:

      • Stronger than association
      • there is an owner and owned connected with their time of existence
      • It is part-to-whole type of relation i.e. a part might belong to many unities therefore unity do not govern time of “part” existence
      • aggregation means enclosing


      Example:

      • The university division does NOT create nor delete instance of professor it only contains it.
      • Book register at library and particular book card. The register encloses book cards.





      Composition: contains/owns a (Total composition) HAS-A

      Ex:a Class Man owns a Class Heart ( When Man die, Heart die )
      Composition (black diamond) does carry semantics. The most particular is that an object can only be the part of one composition relationship. So even if both windows and panels can hold menu-bars, any instance of menu-bar must be only held by one whole. This isn't a constraint that you can easily express with the regular multiplicity markers.   
      - Martin Fowler


      The strongest from the relationships. Composition is a special case of aggregation. A restricted aggregation is called composition. Therefore, composition is when a an object contains the other object and the contained object cannot exist without the existence of container object. In ther words: composition ensure that the containing object is responsible for the lifetime of the object it holds. If Object BAR is contained within Object FOO, then Object FOO is responsible for the creation and destruction of Object BAR. Unlike aggregation, Object BAR cannot exist without Object FOO.

      In General:

      • Just like aggregation relationship of part-whole
      • The Whole object is the only owner, creator and administrator of the Part object.
      • Part and Whole cannot exist without each other ie. their time of existence is connected
        • deleting the Whole object removes all its Part objects
      • Referred as “has-a


      Example:

      • Encyklopedia has many toms.
      • University has a Department



      REMEMBER:

      Both Composition and Aggregation are Associations.
      Composition IS-A strong Association.
      Aggregation IS-A weak Association.

      Inheritance/Generalization: IS-A

      Ex:a Class Man is a Class Human ( Man is a Human )


      As the name inheritance suggests an object is able to inherit characteristics from another object. In more concrete terms, an object is able to pass on its state and behaviors to its children. For inheritance to work the objects need to have characteristics in common with each other. Inheritance can be defined as the process where one object acquires the properties of another. With the use of inheritance the information is made manageable in a hierarchical order. When we talk about inheritance, the most commonly used keyword would be extends and implements. These words would determine whether one object IS-A type of another. By using these keywords we can make one object acquire the properties of another object.


      • Java
      There is a quite complex explanation of how to consider inheritance in java at Java1 and Java2



      General Example 1:


      And the code:


      public abstract class Item {
      
              int positionInList;
              String fullName;
      }
      
      public class MenuItem extends Item{
      
              Currency price;
              String description;
      
      void changePrice (Currency newPrice){
                   this.price = newPrice;
            }
      }
      
      
      /* AGGREGATION
      * In Menu we can change MenuItem price, but the mItem is not only internal consern of Menu.
      * It can be swapped, or even completely removed.
      */
      
      public final class Menu {
      
            private List<MenuItem> mItem;
      
      
      void addMenuItem(MenuItem mi){
                  mItem.add(mi);
      }
      
      void changePrice(Currency newPrice, int position){
      
          if (mItem.get(position) != null){
            mItem..get(position).changePrice(newPrice);
          }
       }
      }
      
      public class Order {
      
      private final List<OrderItem> oItems;
      
      Order(List<OrderItem> items){
         this.oItems = new ArrayList<OrderItem>();
         this.oItems.addAll(items);
      }
      
      void modifyItem(String wish, int position){
          oIitems.get(pos).addNote(wish);
        }
      }
      
      public final class OrderItem extends Item{
      
      String guestNotes;
      List<int> positionInMenu;
      
      private final addNote(String wish){
         this.guestNotes = wish;
      }
      }
      


      General Example 2:





      And the code:

      public class University {
      
      private List<Department> departments;
      
      public void destroy(){
      //it's composition, when i destroy a university I also destroy the departments. they cant live outside my university instance
          if(departments!=null)
          for(Department d : departments)
             d.destroy();
          departments.clean();
          departments = null;
        }
      }
      
      public class Department {
      
      private List<Professor> professors;
      private University university;
      
      Department(University univ){
          this.university = univ;
      }
      
      public void destroy(){
      //It's aggregation here, we just tell the professor they are fired but they can still keep living
         for(Professor p:professors)
           p.fire(this);
         professors.clean();
         professors = null;
         }
      }
      
      public class Professor extends Person{
      
      private String fullTitle;
      private List<Department> attachedDepartments;
      
      public void destroy(){
      }
      
      public void fire(Department d){
          attachedDepartments.remove(d);
          }
      }
      
      
      public class Student extends Person{
      }
      
      public abstract class Person{
        
         String name;
         String surname;
      }
      



      There is more explanation of differences between inheritance and composition in following article.

      Social Buttons End POst