Nejprve jak psal Kamil jde o to co preferujete. Paradoxne jsem vcera
zkusil postup s "prepinacem" typu Enum a treba na muj vkus mi to prinasi
vice problemu (NPE, vice testu) nez pozitiv a socialnich jistot :-) ale
je to o nazoru. Teda moje reseni je na zpusob:

interface Data 
{
    /* stejne by jste resil "int getCoJsem()" */
    public abstract void accept(ServisaA visitor);

}


class A implements Data {

  String name;
  ...
  /* casto implementuju copy constructor */
  public A(A a)
  { this.name = a.name }

  public void accept(ServicaA visitor) {
        visitor.selectData(this); // this je typu class A
  }
}


class B extends A {

   int size;
   ...
/* casto implementuju copy constructor */
   public B(A a)
   { super(a) }

   public B(B b)
   { 
        super(b);
        this.size = size;
   }


   public void accept(ServicaA visitor) {
        visitor.selectDataWithCounts(this); // this je typu class B
/* tady je zamysleni jestli vyhovuje pouziti pretizenych metod na zaklade typu 
parameteru ci nikoliv
alternativne: */
        visitor.selectData(this); // this je typu class B
   }
}


class ServisaA 
{
      public Servisa lookupService()
      { return ((Servisa)ctx.lookup("servisa")); }

        public void selectData(A data)  
       {
            ResultSet rs = con.createStatement("select name from
tabulka"); rs.next();

      data.name = rs.getString("name"); 

       }

       public void selectDataWithCounts(B data)
       {
            ResultSet rs = con.createStatement("select name,size from
tabulka"); rs.next();

      data.name = rs.getString("name"); data.size = rs.getInt("size");
      /* ale kdyby bylo size treba "select count(*) from tabulka" tak: */
      selectData(data);
      ResultSet rs = con.createStatement("select count(*) from tabulka"); 
rs.next();
      data.size = rs.getInt(1);

      }

      /* ted to je zase podle vkusu, nemusi to byt (visit=selectData) */
     public void selectData(Data data)
     {
            data.accept(this);
     }
}


ted:

class UplneJinaServisa
{
       public run()
        {
                  /* ve factory se vyrabi to ci oto, takze 5minut
vyrabite pouze A, pak si jednou vyrobite B a zase pet minut A, nebo
factory muzu vyrabet 1000 A pak 1 B a pak 1000 A ... */
                  Data data = DataFactory.newInstance(<Nejake paramtery
ktere muzou rikat co se vyrobi>);
                  ... furt stejnej kod co vsude byl ...
                  ... i volani 100 service ktera vubec nic nevi o
nejakem A nebo B ...
                  ... a nekde hluboko ... bud a)
                  /* ze servisaA.selectData(data); se stane */
                  data.accept(servisaA);
                  /* nebo protoze mame selectData(data) tak ten radek
zustane */
                  servisaA.selectData(data);
        }
}

takze celej slozitej a uz odzkousenej kod zustal stejny. Tusim, ze pak
compilator je schopen ty volani nahradit skoc sem skoc tam a pak zase
trosku jinam. Vyhoda je ze kdyz pridate C tak cely kod zustane stejny
pouze neco pribude na ServiceA, takze vam projdou vsechny testy pro A i
B.

ano rad nechavam hodne veci na kompilatoru.

Odpovedet emailem