Best Way to Split Class into Multiple Classes
Hello, I need to determine the best way to split a class containing multiple methods(about 20), into multiple classes in which each method is in its own class. I am wondering if there is another way other than manually creating the different classes, and copying each method into each class. Doing this in Intersystems Studio.
Comments
may I ask why you would want to do this? What is the downside of the methods all being in the same class?
I don't think there is any way of doing this other than manually. I think you'll need to create a new class and then copy the method definition into the new class.
The class contains thousands of lines of code. This way multiple developers can work on each method/class without stepping on each other's work.
For a handful of methods the manual method is likely the fastest... in case, you have a real big bunch of methods to copy put this "short" method into a class and let it run...
/// Transfer all or selected methods from a class into/// individual classes/// cls : the donor class/// list: list of methods to be transfered: "method1,method2,..."/// or empty to transfer all methodsClassMethod Transfer(cls, list = "")
{
s old=##class(%Dictionary.ClassDefinition).%OpenId(cls)
s:list]"" list=$lfs(list)
i old {
f i=old.Methods.Count():-1:1 {
s met=old.Methods.GetAt(i) // grab the next method
i list]"",'$lf(list,met.Name) continue// skip if not to copysnew=old.%ConstructClone() // duplicate old classs tmp=old.Name // grab the old classnames$p(tmp,".",*)="Parts."_met.Name // create a new classnamesnew.Name=tmp
snew.Abstract=1// make the class abstractsnew.Super=""// remove all superclassess dup=met.%ConstructClone() // duplicate the old methods dup.Name=met.Name // but keep the old namednew.Properties.Clear() // remove all propertiesdnew.Parameters.Clear() // remove all parameters dnew.Methods.Clear() // remove all methodsdnew.Methods.Insert(dup) // insert the copied method onlyd old.Methods.RemoveAt(i) // Remove this method from old class
i old.Super="" { sd="" } else { sd="," }
s old.Super=old.Super_d_new.Name // add the new class to extends-lists st=new.%Save() // save the new classwnew.Name,"-->",$s(st:"OK",1:$system.Status.GetOneErrorText(st)),!
// Possibly compile the class: do $system.OBJ.Compile(...)
}
s st=old.%Save() // save the old classw old.Name,"-->",$s(st:"OK",1:$system.Status.GetOneErrorText(st)),!
// Possibly compile...
}I suggest give the destination package a different name, maybe the original class name? or a value passed in from a parameter.
Suppose, you have a class my.test with two methods: check1 and check2 then after running the above methode:
do ##class(your.class).Transfer("my.test", "check1,check2")
creates two new classes
my.test.parts.check1 and
my.test.parts.check.2
so what do you mean with "give the destination package a different name, maybe the original class name" ?
Yes or something like :
- my.test.cls (original class)
- my.test.check1.cls (Method 1)
- my.test.check2.cls (Method 2)
To do so I've added:
Set destPackage=""if ($length(cls,".")>1),$length($translate($piece(cls,".",2,99),".")'="") set destPackage=$Piece(cls,".",2,999)
//[some code]set$piece(tmp,".",*)=destPackage_"."_met.Name // create a new classnameThank you Julius!
I do agree that the best way would be to manually create the new classes and copy and pasting each method. However, I was tasked with coming up with different solutions. I really appreciate everyone's input on this.
Most welcome - good luck with the final conclusion of your work!
Establishing of source control based development technology needs some efforts, while gives much more advantages. It's possible even with Studio, while easier with VS Code.
Besides, when each developer has its "own" methods it would be easier to resolve possible merge conflicts.
Create a two new classes that inherit from the "Big Class", and Override the methods that you need in each specific class. When finished remove the inheritance.