1

I am trying to update a legacy application and need some advice about how to organize the data level.

Today, all the data is stored in a binary file created with the help of binary serialization. The data that is stored is a several levels deep tree structure.

The object level of the saved data:

ApplicationSettings
   CommunicationSettings
   ConfigurationSettings
      HardwareSettings
         and so forth some additional levels

All this classes have a lot of logic to do different things. They also have status information that should not be saved to the file.

The data is constantly updated during the execution of the program, and saved when updated to the binary file by the "business logic".

I try to update the program, but doing unit tests for this is a nightmare.

I want the data still be saved in a file in any way. But otherwise, I'm open to suggestions how to improve this.

Edit:

The program is quite small, and I do not want to be dependent on large, complex frameworks. The reason I need help is to try to clean up the code where virtually the entire application logic is in one huge method.

magol
  • 6,135
  • 17
  • 65
  • 120
  • How are the settings consumed? Static class, or passed through into the constructor? – Meirion Hughes Mar 11 '13 at 12:11
  • What you have described is pure XML structure so why not to use it? There are complete tools set already in framework to manage XML. – Denys Denysenko Mar 11 '13 at 12:12
  • From the beginning, almost all classes was static. But I have after a lot of work update it to use DI. So now, all settings are injected via the constructors. – magol Mar 11 '13 at 12:15
  • I have been considering XML as well. But I do not see how it would do something better. XML and binary serialization are handled almost the same. What I need help with is how data is moved back and forth between the data and domain level – magol Mar 11 '13 at 12:18

1 Answers1

1

What I would do;

First, turn the settings into contracts;

public interface IApplicationSettings
{
     ICommunicationSettings CommunicationSettings{get;} 
     IConfigurationSettings ConfigurationSettings{get;}
}

Now, break up your logic into separate concerns and pass in your settings at the highest level posible; Such that if MyLogicForSomething only concerns itself with the communication settings, then only pass in the communication settings;

public class MyLogicForSomething
{       
    public MyLogicForSomething(ICommunicationSettings commSettings)
    {
    }

    public void PerformSomething(){/* ... */}
}

ICommunicationSettings is easily mockable here; with something like Rhino Mocks

You can now easily test to ensure something in your settings is called/set when you run your logic

var commSettings = MockRepository.GenerateStub<ICommunicationSettings>();
var logic = new MyLogicForSomething(commSettings );

logic.PerformSomething()

commSettings.AssertWasCalled( x => x.SaveSetting(null), o=>o.IgnoreArguments() );
Meirion Hughes
  • 24,994
  • 12
  • 71
  • 122
  • Thanks for your reply. In fact I have already done this. The problem is that MyLogicForSomething iterates all objects that are in under it, and therefore I must set the values ​​of all of these object also when I mock. – magol Mar 11 '13 at 12:33
  • Break that up too then (into sub-logic for each object type) test that one object (or state case) is delt with correctly; then you only have to ensure that your outer loop calls the correct sub-logic; – Meirion Hughes Mar 11 '13 at 12:37
  • The problem is that all logic is in the same method. So I have to mock the complete tree structure to be able to run the method. – magol Mar 11 '13 at 13:17
  • You'll have to break up the logic method into smaller chunks. – Meirion Hughes Mar 11 '13 at 13:44
  • Refactory is why I intend to begin writing unit tests. But it is not easy to write unit test for this method. But I seem to have no option :-( – magol Mar 11 '13 at 14:43
  • But if you had built this program from scratch. How would you have done then (just curious)? – magol Mar 11 '13 at 14:44
  • Generally, I try to keep to single responsibility as much as possible and if I have to mock more than two objects, it means my code is doing too much and needs to be broken up further. Your problem sounds like you want unit tests in place before you refactor it so you don't break anything. if you have anything like if(state == FOO) doSomething, then you put doSomething as a method... you keep doing that until you can't break it up anymore. You are not really changing anything, just turning sections into methods. But they should be easier to test. – Meirion Hughes Mar 11 '13 at 15:05