Saturday, September 1, 2007

Running Tests

When separating your unit tests into their own directory you have to do something like this, when you want to run all your tests from the eclipse plug-in RDT: class TestRequireFinder def _load(file_name) require File.expand_path(File.dirname(__FILE__)) +'/' + file_name end end test = TestRequireFinder.new

Monday, June 11, 2007

Nerdification

I had to do this. Nothing Better to do. I am nerdier than 81% of all people. Are you a nerd? Click here to find out!

Wednesday, May 30, 2007

Imposing Design (was Re: [TDD] Re: Wandering through layers of software)

[snipstart] --- In testdrivendevelopment@yahoogroups.com, "Kelly Anderson" <kellycoinguy@...> wrote: > > My TDD code throws more exceptions generally... so I'd really like to > hear more about your thoughts on this subject. > [snipend] Using the example as shown in: What is Exceptional? [126], The Pragmatic Programmer (converted from java to C#).

private TextReader ipstream;

public void open_passwd() { try { ipstream = new StreamReader(@"..\etc\passwd"); } catch(Exception) { throw new FileNotFoundException("No Password File Found"); } }

public bool open_user_file(string fname) { if (!File.Exists(fname)) return false;

ipstream = new StreamReader(fname);

return true; }

public void OpenUserFile(string fname) { if (!File.Exists(fname)) { Fire_FileDoesNotExistEvent(); return; }

ipstream = new StreamReader(fname); }

The method open_passwd has a dependency on passwd file. The second method is not dependent on a specific file. (In my opinion both methods are ripe to be refactored). Would you have written either of these methods with TDD/Refactoring. The point is that because of that dependency on the first method it has to have some way to communicate to the client that the part of the contract it is responsible for cannot be fulfilled. Also I am not saying that when you write code you shouldn't ever throw an exception.

As far as I have been able to determine there are only three standard ways objects can communicate in an OOP methodology.

  1. Exception Message (first method)
  2. Command Message (second method).
  3. Event Message (third method).
It is the third communication channel that for me is showing a lot of promise. It is the publish/subscribe pattern. The first two message type are hierarchical in nature, in other words you need the client to control those methods. While the third is collaborative. The method fires the event and forgets. The method does not care that a file does not exist. AND the client that called the third method does not have to be the one to handle the event message. When I first started on these groups I asked a question concerning an example Michael Feather's had concerning writing unit tests (A stack object). Ron Jeffries and others were kind enough to help me through the example, but one of the things that didn't sit well with me was that in explaining it to me Ron didn't bother with using the exception handling (Exception Message) he instead used the 'Command Message' (Query on state {IsEmpty})and then if IsEmpty == true then don't pop from stack. Now I want to create a contrived example. let us say we have a form with a button that when we click it it will use one of our (3) methods. Also if no file is found it will need to shutdown the system (Crash, Don't Trash [120], The Pragmatic Programmer) Now if you look in LoadFileForm class. Which of the click methods would you like to use? There is a lot of associated machinery that you have to add, every time you use the first two messages types. The first two message types create these dependencies for handling exceptions. The client really only is responsible for opening text files. Not handling errors. If you look at the unit tests you can see I was able to remove the SystemShutDown object from the constructor when using event messages. Also I was able to Subscribe a private method that also verified that the event was actually fired. In a normal application I really would have followed the Presenter First pattern. The final component then would have two presenters. These would wire up the form to the TextFileOpener and the TextFileOpener to SystemShutDown object. Because the Presenters are mappers. these three objects can change without affecting each other, because they initiate communication with each other via event messages. And anybody can subscribe to these events. I am not saying this type of programming Event Collaboration is a 'Silver Bullet'. But it is more along the lines of BDD. Other objects processing because of some other objects behavior.

using System; using System.IO; using NUnit.Framework;

namespace UnitTestAlarmSystem { [TestFixture] public class Test_FileOpener_NoExceptions { private const string FILE_NAME = "Tester"; private TextFileOpener textFileOpener; private ShutDownSystem shutDownSystem; private bool isNoFile;

[TestFixtureSetUp] public void TestFixtureSetUp() { textFileOpener = new TextFileOpener(); shutDownSystem = new ShutDownSystem(); }

[TestFixtureTearDown] public void TestFixtureTearDown() { shutDownSystem = null; textFileOpener = null; }

[Test] public void TestExceptionMessagesNoFile() { LoadFileForm form = new LoadFileForm(textFileOpener, shutDownSystem); form.ButtonClickException(); Assert.IsTrue(form.IsException); }

[Test] public void TestCommandMessageNoFile() { LoadFileForm form = new LoadFileForm(textFileOpener, shutDownSystem); form.SetFileName(FILE_NAME); form.ButtonClickCommand(); Assert.IsTrue(form.IsCommand); }

[Test] public void TestEventMessageNoFile() { isNoFile = false; textFileOpener.WhenLoadFile += new EventHandler(shutDownSystem.WhenNoFileHandler); textFileOpener.WhenLoadFile += new EventHandler(WhenNoFileHandler);

LoadFileForm form = new LoadFileForm(textFileOpener); form.SetFileName(FILE_NAME); form.ButtonClickEvent(); Assert.IsTrue(isNoFile); }

private void WhenNoFileHandler(object sender, EventArgs e) { isNoFile = true; } }

public class LoadFileForm { private TextFileOpener textFileOpener; private ShutDownSystem shutDownSystem; private string mFileName; private bool isCommand = false; private bool isException = false;

public LoadFileForm(TextFileOpener opener, ShutDownSystem shutDown) { textFileOpener = opener; shutDownSystem = shutDown; }

public LoadFileForm(TextFileOpener opener) { textFileOpener = opener; }

public bool IsException { get { return isException; } }

public bool IsCommand { get { return isCommand; } }

public void ButtonClickException() { try { textFileOpener.open_passwd(); //Process file } catch (Exception ex) { isException = true; shutDownSystem.SetException(ex.Message);

shutDownSystem.Execute(); } }

public void ButtonClickCommand() { bool fileOpenResult = textFileOpener.open_user_file(mFileName);

if (fileOpenResult) { //Process file } else { isCommand = true; shutDownSystem.SetException("No File Found {Command}"); shutDownSystem.Execute(); } }

public void ButtonClickEvent() { textFileOpener.OpenUserFile(mFileName); //Process file }

public void SetFileName(string file_NAME) { mFileName = file_NAME; } }

public class ShutDownSystem { private string mException;

public void Execute() { Console.WriteLine(mException); //Shut Down Logic }

public void WhenNoFileHandler(object sender, EventArgs e) { Console.WriteLine("No File Found {Event}"); //Shut Down Logic }

public void SetException(string exceptionMessage) { mException = exceptionMessage; } }

public class TextFileOpener { public event EventHandler WhenLoadFile;

private TextReader ipstream;

public TextReader Ipstream { get { return ipstream; } }

public void open_passwd() { try { ipstream = new StreamReader(@"..\etc\passwd"); } catch (Exception) { throw new FileNotFoundException("No File Found {Exception}"); } }

public bool open_user_file(string fname) { if (!File.Exists(fname)) return false;

ipstream = new StreamReader(fname);

return true; }

public void OpenUserFile(string fname) { if (!File.Exists(fname)) { Fire_FileDoesNotExistEvent(); return; }

ipstream = new StreamReader(fname); }

private void Fire_FileDoesNotExistEvent() { if (WhenLoadFile != null) WhenLoadFile.Invoke(null, null); } } }

Tuesday, May 29, 2007

User Story Spike

Spike:

  • Need to refine what I know about ASP.Net with Presenter First.
  • Need to refine SQL Server 2000 with DAL
Story1:
  • Customer submits an application.
  • Application is Validated and stored.
  • Customer is notified of application status via e-mail.

Story2:
  • Application is sent to manual processor via workload balancing (?).
  • The application is processed (Approved/Rejected) by manual processor.
  • Customer is notified of application status via e-mail.

Story3:
  • Manager needs to verify application statuses for all manual processors.
  • Manager can re-assign workload of manual processors.

Event Sourcing Revisit

Ah... Encapsulates Application State as derived from event/command messages. Pretty sweet.

Sunday, May 27, 2007

Event Sourcing

Was looking over event sourcing. I'm still trying to scratch my head. Will Keep plowing ahead and leave more remarks

Monday, May 7, 2007

    public class SubmissionModelLayer : SubmissionModel

    {

        public event EventHandler SubmissionCompleteEvent;

        public event EventHandler SubmissionIncompleteEvent;

 

        private SubmittedApplication mApplication;

        private ServiceLocater mLocater;

 

        public SubmissionModelLayer(ServiceLocater locater)

        {

            mLocater = locater;

        }

 

        public void SubmitApplication(SubmittedApplication application)

        {

            mApplication = application;

 

            mApplication.ValidateApplication(mLocater.GetValidationService());

            if(IsNotValidSubmisssion())

                return;

 

            mApplication.StoreApplication(mLocater.GetDataService());

            if(IsNotStoredSubmission())

                return;

 

            mApplication.NotifyCustomer(mLocater.GetMessageService());

            if (IsNotNotifiedSubmission())

                return;

 

            Fire_CompleteEvent();

        }

 

        private bool IsNotNotifiedSubmission()

        {

            if (!mApplication.IsCustomerNotified)

            {

                Fire_InCompleteEvent();

                return true;

            }

            return false;

        }

 

        private bool IsNotStoredSubmission()

        {

            if (!mApplication.IsStored)

            {

                Fire_InCompleteEvent();

                return true;

            }

            return false;

        }

 

        private bool IsNotValidSubmisssion()

        {

            if (!mApplication.IsValid)

            {

                Fire_InCompleteEvent();

                return true;

            }

            return false;

        }

 

        private void Fire_InCompleteEvent()

        {

            if (SubmissionIncompleteEvent != null)

                SubmissionIncompleteEvent.Invoke(null, EventArgs.Empty);

        }

 

        private void Fire_CompleteEvent()

        {

            if (SubmissionCompleteEvent != null)

                SubmissionCompleteEvent.Invoke(null, EventArgs.Empty);

        }

    }

Friday, May 4, 2007

Encapsulation in the Model

Looking at the above code you can see that the submission service is injected into the application. Encapsulation is more than just hiding data, but also is about protecting the client from having to know more than it needs to. I know it sounds like I said the same thing, but when writing the code if you focus more on hiding data than protecting the client then you might run into something like the following: The code needs to extract a boolean value from the validator then pass it back into the application. The original code did all this in the application object.

Presenter First Events

To keep track of the presenter first event connection, use a sequence diagram. The diagram is driven from Atomic Object's Ruby Code.

Saturday, April 28, 2007

New Stab At Presenter First

Presenter First: Mappers. Plain and simple. Maps events to actions/commands required on the injected objects in the presenter.

  • Benefit is that all the models and views can be isolated from each other so that they can change on their own. Views especially don't need to know about models.
Something else, It seems to me an event aggregator could replace all the presenters with only one presenter and store all actions/commands in a table. Need only to pass all models and views into aggregator. Need to define the mechanics for this refactoring.

Friday, April 27, 2007

Intention Driven Design

People who use code to communicate their ideas of software design should give their unit tests along with their implemented code. To me that only seems to be polite. If you’re going to be on a discussion group that has its main focus to be unit testing, you should give examples in unit tests. Give me your intention not your implementation. I really don’t care if you used a long or an integer to implement a counter inside your implementation. If unit testing is the documentation of the code and no other documentation is needed, why is so much implementation used in examples?

Wednesday, April 11, 2007

Presenter First #2 (Application Data)

Normally there are 3 data states in Presenter First design.

  • Record State. The persistent data store residing in the Data Layer. This could include RDBMS, XML, or text flat files.
  • Session State. Stored in-memory within application. Usually Data Transfer Objects.
  • Screen State. Data stored in the view.
It is very important the Session State and the Screen State remain synchronized. That is where the presenter object comes into play. The session data becomes dirty and generates an event to the Presenter. In my implementation the Presenter would then query the view for actiontype, check if view is in dirty state, if dirty retrieve DTO from view. Presenter would then pass DTO to the Domain Service to save the DTO information. Code Example follows:
public class ReformatAction : CommandAction
{
public ReformatAction(ViewAggregator viewAggregator,
 DomainService domainService) : base(viewAggregator, domainService){}

public override void Execute()
    {
     string formatModuleName = ViewAggregator.GetSelectedModuleName();
        ModuleDTO moduleDTO = ViewAggregator.GetModule();

        if (ViewAggregator.IsDirty)
             Service.SetModule(moduleDTO);
        ViewAggregator.SetModule(Service.GetModule(formatModuleName));
    }
}
This code example is the wiring between the view and domain. It is a command object. It pulls the module name from the view, pulls the module, if view is dirty then save module, reload saved module to view. The formating comes from where? See what happens in the service:
      public void SetModule(ModuleDTO module)
     {
          mModuleTable[module.GetModuleName()] = module.GetBody();
     }
So we see that it is all done in the service. But you say your unformatting and saving the unformatted int the module table. Correct. Look at this piece:
        public string GetBody()
      {
          ModuleUnformatter mu = new ModuleUnformatter(mBody);
          mu.UnformatModule();

          return mBody = mu.Module;
      }

      public string GetFormattedBody()
      {
          ModuleFormatter mf = new ModuleFormatter(mBody);
          mf.FormatBody();
          return mf.Module;
      }

Ask yourself why didn’t I just transfer the formatted directly into the text box…

Next Post #3: How to utilize command pattern so that the Presenter holds no instance of Domain or View and is nothing but command messages and event messages.

Post #4: Either Mocking and Unit Testing Presenter First or Event Handling.

DSL

Just got done finishing my implementation of Martin Fowler's 2 pass build reader for DSLs: I wish he would have added the reflection code. It really sucked trying to figure out all the reflection for dynamic assembly. Phew...got it anyway. Works sweet!
Did run across CodeDom. This will generate code. The next step would be to generate the dynamic assembly with CodeDom. Some how I want to use this after loading up the reader strategy. Looks like some abstraction is required. Refactor...Refactor.

Sunday, April 8, 2007

Presenter First

Presenter First is a pattern that includes Event Mapper (Presenter), Domain (Model), and Server (View) objects.

Figure 1.
The key point when designing with this pattern is to remember to keep the presenter stateless. Don't do any data manipulation in the event handling. Do it all in the Domain. Example:
You notice in the correct code you are using command messages to transfer the data around from Server (viewService) to Domain (domainService) and vice versus. All I am doing is wiring up the Server to to the Domain and Domain to Server. Next Post #2: How to utilize command pattern so that the Presenter holds no instance of Domain or View. Post #3: Encapsulation worth the effort for Presenter First? Post #4: Either Mocking and Unit Testing Presenter First or Event Handling. References: AtomicObject Marting Fowler Brian Marick Michael Feathers

Saturday, March 24, 2007

TaDA!

Just started this blog and wanted to get some content out there.