Removing Class From A Hierarchy


Let's use A,B and C classes and remove B class, copying its values to the updated C class.

First of all let's store some class objects to the database:

refactoringExample.java: storeData
01public static void storeData(){ 02 new File(DB4O_FILE_NAME).delete(); 03 ObjectContainer container = Db4o.openFile(DB4O_FILE_NAME); 04 try { 05 A a = new A(); 06 a.name = "A class"; 07 container.set(a); 08 09 B b = new B(); 10 b.name = "B class"; 11 b.number = 1; 12 container.set(b); 13 14 C c = new C(); 15 c.name = "C class"; 16 c.number = 2; 17 container.set(c); 18 } finally { 19 container.close(); 20 } 21 }
refactoringExample.java: readData
01public static void readData(){ 02 ObjectContainer container = Db4o.openFile(DB4O_FILE_NAME); 03 try { 04 ObjectSet result = container.get(new A()); 05 System.out.println("A class: "); 06 listResult(result); 07 08 result = container.get(new B()); 09 System.out.println(); 10 System.out.println("B class: "); 11 listResult(result); 12 13 result = container.get(new C()); 14 System.out.println(); 15 System.out.println("C class: "); 16 listResult(result); 17 } finally { 18 container.close(); 19 } 20 }

If we will remove B class and update C class to inherit from A, we won't be able to read C data from the database anymore (exception).  In order to preserve C data we will need to transfer it to another class:

D.java
01/* Copyright (C) 2007 db4objects Inc. http://www.db4o.com */ 02package com.db4odoc.refactoring.refactored; 03 04import com.db4odoc.refactoring.initial.A; 05 06public class D extends A { 07 public int number; 08 09 public String toString(){ 10 return name + "/" + number; 11 } 12}

We can also transfer B data into this class.

Once D class is created we can run the data transfer:

refactoringUtil.java: moveValues
01public static void moveValues(){ 02 ObjectContainer container = Db4o.openFile(DB4O_FILE_NAME); 03 try { 04 // querying for B will bring back B and C values 05 ObjectSet result = container.get(new B()); 06 while (result.hasNext()){ 07 B b = (B)result.next(); 08 D d = new D(); 09 d.name = b.name; 10 d.number = b.number; 11 container.delete(b); 12 container.set(d); 13 } 14 15 } finally { 16 container.close(); 17 System.out.println("Done"); 18 } 19 }

Now B and C classes can be safely removed from the project and all the references to them updated to D. We can check that all the values are in place:

RefactoringExample.java: readData
01public static void readData(){ 02 ObjectContainer container = Db4o.openFile(DB4O_FILE_NAME); 03 try { 04 ObjectSet result = container.get(new D()); 05 System.out.println(); 06 System.out.println("D class: "); 07 listResult(result); 08 } finally { 09 container.close(); 10 } 11 }

When performing refactoring on your working application do not forget to make a copy of the code and data before making any changes!