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.cs: StoreData
01public static void StoreData() 02 { 03 File.Delete(Db4oFileName); 04 IObjectContainer container = Db4oFactory.OpenFile(Db4oFileName); 05 try 06 { 07 A a = new A(); 08 a.name = "A class"; 09 container.Set(a); 10 11 B b = new B(); 12 b.name = "B class"; 13 b.number = 1; 14 container.Set(b); 15 16 C c = new C(); 17 c.name = "C class"; 18 c.number = 2; 19 container.Set(c); 20 } 21 finally 22 { 23 container.Close(); 24 } 25 }
refactoringExample.cs: ReadData
01public static void ReadData() 02 { 03 IObjectContainer container = Db4oFactory.OpenFile(Db4oFileName); 04 try 05 { 06 IObjectSet result = container.Get(new A()); 07 System.Console.WriteLine("A class: "); 08 ListResult(result); 09 10 result = container.Get(new B()); 11 System.Console.WriteLine(); 12 System.Console.WriteLine("B class: "); 13 ListResult(result); 14 15 result = container.Get(new C()); 16 System.Console.WriteLine(); 17 System.Console.WriteLine("C class: "); 18 ListResult(result); 19 } 20 finally 21 { 22 container.Close(); 23 } 24 }
refactoringExample.vb: StoreData
01Public Shared Sub StoreData() 02 File.Delete(Db4oFileName) 03 Dim container As IObjectContainer = Db4oFactory.OpenFile(Db4oFileName) 04 Try 05 Dim a As New A() 06 a.name = "A class" 07 container.[Set](a) 08 09 Dim b As New B() 10 b.name = "B class" 11 b.number = 1 12 container.[Set](b) 13 14 Dim c As New C() 15 c.name = "C class" 16 c.number = 2 17 container.[Set](c) 18 Finally 19 container.Close() 20 End Try 21 End Sub
refactoringExample.vb: ReadData
01Public Shared Sub ReadData() 02 Dim container As IObjectContainer = Db4oFactory.OpenFile(Db4oFileName) 03 Try 04 Dim result As IObjectSet = container.[Get](New A()) 05 System.Console.WriteLine("A class: ") 06 ListResult(result) 07 08 result = container.[Get](New B()) 09 System.Console.WriteLine() 10 System.Console.WriteLine("B class: ") 11 ListResult(result) 12 13 result = container.[Get](New C()) 14 System.Console.WriteLine() 15 System.Console.WriteLine("C class: ") 16 ListResult(result) 17 Finally 18 container.Close() 19 End Try 20 End Sub

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.cs
01/* Copyright (C) 2007 db4objects Inc. http://www.db4o.com */ 02using Db4objects.Db4odoc.Refactoring.Initial; 03 04namespace Db4objects.Db4odoc.Refactoring.Refactored 05{ 06 class D: A 07 { 08 public int number; 09 10 public override string ToString() 11 { 12 return name + "/" + number; 13 } 14 } 15}
D.vb
01' Copyright (C) 2007 db4objects Inc. http://www.db4o.com 02 03Namespace Db4objects.Db4odoc.Refactoring.Refactored 04 Class D 05 Inherits Initial.A 06 07 Public number As Integer 08 09 Public Overloads Overrides Function ToString() As String 10 Return name 11 End Function 12 13 End Class 14End Namespace

We can also transfer B data into this class.

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

refactoringUtil.cs: MoveValues
01public static void MoveValues() 02 { 03 IObjectContainer container = Db4oFactory.OpenFile(Db4oFileName); 04 try 05 { 06 // querying for B will bring back B and C values 07 IObjectSet result = container.Get(new B()); 08 for (int i = 0; i < result.Count; i++) 09 { 10 B b = (B)result[i]; 11 D d = new D(); 12 d.name = b.name; 13 d.number = b.number; 14 container.Delete(b); 15 container.Set(d); 16 } 17 18 } 19 finally 20 { 21 container.Close(); 22 System.Console.WriteLine("Done"); 23 } 24 }
refactoringUtil.vb: MoveValues
01Public Shared Sub MoveValues() 02 Dim container As IObjectContainer = Db4oFactory.OpenFile(Db4oFileName) 03 Try 04 ' querying for B will bring back B and C values 05 Dim result As IObjectSet = container.[Get](New Initial.B()) 06 For i As Integer = 0 To result.Count - 1 07 Dim b As Initial.B = DirectCast(result(i), Initial.B) 08 Dim d As New D() 09 d.name = b.name 10 d.number = b.number 11 container.Delete(b) 12 container.[Set](d) 13 14 Next 15 Finally 16 container.Close() 17 System.Console.WriteLine("Done") 18 End Try 19 End Sub

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.cs: ReadData
01public static void ReadData() 02 { 03 IObjectContainer container = Db4oFactory.OpenFile(Db4oFileName); 04 try 05 { 06 IObjectSet result = container.Get(new D()); 07 System.Console.WriteLine(); 08 System.Console.WriteLine("D class: "); 09 ListResult(result); 10 } 11 finally 12 { 13 container.Close(); 14 } 15 }
RefactoringExample.vb: ReadData
01Public Shared Sub ReadData() 02 Dim container As IObjectContainer = Db4oFactory.OpenFile(Db4oFileName) 03 Try 04 Dim result As IObjectSet = container.[Get](New D()) 05 System.Console.WriteLine() 06 System.Console.WriteLine("D class: ") 07 ListResult(result) 08 Finally 09 container.Close() 10 End Try 11 End Sub

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