Archive

Archive for the ‘Software engineering’ Category

ConfORM – Another NHibernate mapping possibility

September 1st, 2010 Patrick 2 comments

I recently hold two presentations at the .Net User Group Bern (DNUG) with René Leupold about object relational mapping in the .Net world. We showed Entity Framework 4.0 and NHibernate. My part was NHibernate. You could download the slides and samples from the DNUG website.

In the two presentations I showed the mapping possibilities with hbm.xml files, attributes and Fluent NHibernate. In a previous blog post I already showed those possibilities.ConfOrmBigTransparent

During the preparations I hadn’t time to try a new way to map your entities to the database. This new way is offered by the framework ConfORM, created by one of the contributors of NHibernate Fabio Maulo.

In a previous post I showed the other possibilities how you can map your entities. In this post I show you the most simplest way I found to map the entities with ConfORM. I used for this example the version 1.0.2 (Alpha 2) of ConfORM and the version 3.0.0 Alpha 2 of NHibernate. The current version of ConfORM is available here.

Domain

The domain for this sample is quite simple. It is a one to many mapping between Order and its OrderItems. The associations is bidirectional. Below you see the class diagram of the two classes:

ClassDiagram

Database

The following ERD show the two tables Order and OrderItem in the database. Between the two tables exists a foreign key constraint. None of the fields are nullable.

database

Configuration

First, we need to declare the connection string, so that we could connect to the database. I could do it in the code, but even for a such simple example it is too dirty for me. So I added an application configuration file (app.config) and added following lines:

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
	<connectionStrings>
		<add name="default" connectionString="Server=localhost;database=ORMSamples;Integrated Security=SSPI;"/>
	</connectionStrings>
</configuration>

Now I have a connectionstring named “default” which points to my local database ORMSamples.

When you are familiar with NHibernate, you know that you have to have a place where your session factory lives and will be created. For this purpose I normally create a class called PersistenceManager. The field factory, the property Factory and the method OpenSession are the code I would create also when I map my entities with hbm.xml files or with Fluent NHibernate or with attributes.

Where it starts to be different is the CreateConfiguration method. In this method I could create the configuration part by code. This fluent API to create a configuration is called Loquacious. Normally I would declare all this stuff in the application configuration file.

I think for a such simple application it is OK to do it like that, but I prefer the way over the application configuration file. The reason for that is, that I could configure my application for each scenario (depends on database product, etc.).

namespace ORMSamples.ConfORM.Utils
{
	public class PersistenceManager
	{
		private static ISessionFactory factory;

		private static ISessionFactory Factory
		{
			get
			{
				if(factory == null)
				{
					Configuration config = CreateConfiguration();
					factory = config.BuildSessionFactory();
				}

				return factory;
			}
		}

		public static ISession OpenSession()
		{
			return Factory.OpenSession();
		}

		private static Configuration CreateConfiguration()
		{
			var configure = new Configuration();
			configure.SessionFactoryName("Demo");

			configure.Proxy(p => p.ProxyFactoryFactory<ProxyFactoryFactory>());
			configure.DataBaseIntegration(db =>
			{
				db.Dialect<MsSql2008Dialect>();
				db.Driver<SqlClientDriver>();
				db.KeywordsAutoImport = Hbm2DDLKeyWords.AutoQuote;
				db.ConnectionString = ConfigurationManager.ConnectionStrings["default"].ConnectionString;
				db.LogSqlInConsole = true;
				db.HqlToSqlSubstitutions = "true 1, false 0, yes 'Y', no 'N'";
			});

			configure.AddDeserializedMapping(GetMapping(), "ORMSamples_ConfORM");

			return configure;
		}

		private static HbmMapping GetMapping()
		{
			return null;
		}
	}
}

Yet I didn’t map one entity but there is an empty method GetMapping. In this method we will program our mapping in the next section.

Mapping

Below you see the completed class PersistenceManager. The implementation was created based on the example in the source code of ConfORM. The main method here is the GetMapping method. It implements a template method pattern to create the mapping.

Very important for the mapping is the method DomainDefinition. There you define your domain what means you declare all root entities. In our case it means that we have to add Order and OrderItem as root entities. For this purpose you have to call TablePerClass on the instance of the ObjectRelationalMapper class for each entity (or call it once for a collection of entities).

The patterns in ConfORM I will leave here out and come directly to the Customize method. In this method I implemented again a template method pattern. In the method CustomizeRelations I define all specialties of my entities, in the method CustomizeTables I define the DB-Schemas and finally in the method CustomizeColumns I define that the properties are all not nullable.

namespace ORMSamples.ConfORM.Utils
{
	public class PersistenceManager
	{
		private static ISessionFactory factory;

		private static ISessionFactory Factory {...}

		public static ISession OpenSession() {...}

		private static Configuration CreateConfiguration() {...}

		private static HbmMapping GetMapping()
		{
			ObjectRelationalMapper orm = new ObjectRelationalMapper();
			orm.Patterns.PoidStrategies.Add(new NativePoidPattern());
			Mapper mapper = new Mapper(orm);

			var entities = new List<Type>();

			DomainDefinition(orm);
			RegisterPatterns(mapper, orm);
			Customize(mapper);

			entities.AddRange(GetEntities());

			return mapper.CompileMappingFor(entities);
		}

		private static void DomainDefinition(ObjectRelationalMapper orm)
		{
			orm.TablePerClass(GetEntities());
		}

		private static void RegisterPatterns(Mapper mapper, IDomainInspector domainInspector)
		{
		}

		private static void Customize(Mapper mapper)
		{
			CustomizeRelations(mapper);
			CustomizeTables(mapper);
			CustomizeColumns(mapper);
		}

		private static void CustomizeRelations(Mapper mapper)
		{
			mapper.Class<Order>(cm =>
			{
				cm.Id(o => o.Id, im => im.Generator(Generators.Identity));
				cm.Bag(
					o => o.Items,
					x =>
						{
							x.Key(k => k.Column("OrderId"));
							x.Lazy(CollectionLazy.NoLazy);
						},
					x => { });
			});
			mapper.Class<OrderItem>(cm =>
			{
				cm.Id(o => o.Id, im => im.Generator(Generators.Identity));
				cm.ManyToOne(
					x => x.Order,
					m =>
						{
							m.Column("OrderId");
							m.Fetch(FetchMode.Join);
							m.NotNullable(true);
						});
			});
		}

		private static void CustomizeTables(Mapper mapper)
		{
			mapper.Class<Order>(cm => cm.Schema("OneToMany"));
			mapper.Class<OrderItem>(cm => cm.Schema("OneToMany"));
		}

		private static void CustomizeColumns(Mapper mapper)
		{
			mapper.Class<Order>(
				cm =>
					{
						cm.Property(x => x.OrderNumber, m => m.NotNullable(true));
						cm.Property(x => x.CompanyName, m => m.NotNullable(true));
						cm.Property(x => x.Street, m => m.NotNullable(true));
						cm.Property(x => x.PostalCode, m => m.NotNullable(true));
						cm.Property(x => x.City, m => m.NotNullable(true));
					});
			mapper.Class<OrderItem>(
				cm =>
				{
					cm.Property(x => x.Quantity, m => m.NotNullable(true));
					cm.Property(x => x.ProductId, m => m.NotNullable(true));
				});
		}

		private static IEnumerable<Type> GetEntities()
		{
			return typeof(Order).Assembly.GetTypes().Where(t => t.Namespace == typeof(Order).Namespace);
		}
	}
}

How to test it

Normally I would start with the test first, but this post is about ConfORM and not about TDD or the test first approach. To test our simple example is quite easy: You could create some CRUD-Tests. To not clutter this blog post I publish here just a Create-Test. As you can see, it’s normal NHibernate code and the whole mapping is encapsulated in the PersistenceManager class.

namespace ORMSamples.ConfORM.Test.OneToMany
{
	[TestFixture]
	public class OneToManyCRUDTest
	{
		private Order order;
		private OrderItem orderitem;

		[SetUp]
		public void SetUp()
		{
			order = new Order();
			orderitem = new OrderItem();
		}

		[TearDown]
		public void TearDown()
		{
			using(ISession session = PersistenceManager.OpenSession())
			using(ITransaction tx = session.BeginTransaction())
			{
				session.Delete(order);
				tx.Commit();
			}
		}

		[Test]
		public void TestCreate()
		{
			// Arrange
			order.OrderNumber = "12345";
			order.CompanyName = "Test Company";
			order.Street = "Hauptstrasse 1";
			order.PostalCode = "1234";
			order.City = "Zürich";
			orderitem.Order = order;
			order.Items.Add(orderitem);
			orderitem.ProductId = 234;
			orderitem.Quantity = 1;

			// Act
			using(ISession session = PersistenceManager.OpenSession())
			using(ITransaction tx = session.BeginTransaction())
			{
				session.Save(order);
				tx.Commit();
			}

			// Assert
			Assert.AreNotEqual(0, order.Id);
			Assert.AreNotEqual(0, orderitem.Id);
		}
	}
}

Conclusion

The first impression of ConfORM was that it seemed to me more complicated than Fluent NHibernate. But after a while I was able to work with. I’m sure, that I didn’t understand all implemented ideas, but the framework still in alpha so I have time to learn them.

ConfORM doesn’t say you how to manage the code where you specify your mappings like Fluent NHibernate. So, you have to be cautious not to code all your mappings in one class (as I did with the PersistenceManager). In this point I find the more stricter way of Fluent NHibernate a bit better.

The owner and contributor of ConfORM, Fabio Maulo, has react very fast as I asked him to implement the missing fetch attribute for collections. If you have questions about ConfORM, you can ask him directly via twitter or the community via the Google user group. ConfORM is definitively an interesting alternative for mapping entities in a fluent way.

  • Share/Bookmark

Branching practices

April 6th, 2010 Patrick No comments

In an environment where several developers work at the same code base or several features have to be implemented, then branching will be a topic. I was asked to create a branching guide for my current employer which use TFS as source code repository.

Motivation

In our projects I found the following problems:

  • When the developers want to release a new version, not every feature was finished. So they had to deliver unfinished features. To solve that problem, they need to disable the unfinished features by configuration.
  • Some features which they had to implement were breaking features. In a such case, they were blocked to deliver new fixes or little features.
  • Sometimes they had to produce a hot-fix for the version which was in production. In a such scenario, they had to take manually the labeled version from the repository and build a hot-fix. After that, they had to copy the fixed code into the current code base.

Branching Guide

For those three scenarios branching could minimize the impact. So I described in the branching guide the following patterns to solve our problems:

  • Feature-Branch (and Team-Branch)
  • Developer-Versions
  • Production-Branch
  • Feature-Freeze

image

Feature-Branch

A Feature-Branch is a branch which is created always from the Main-Branch. It’s important to choose the right granularity for a feature. A worst-case-scenario is when you split a feature over several Feature-Branches, so that they become dependent on each other. A good granularity is for example a module or a workflow (several GUIs), something which is self-contained.

With Feature-Branches you have the possibility the use the cherry-picking method. That means, that before you release a new version, you choose by some quality gates (code coverage, code review, documentation, etc.) which Feature-Branches you want to merge back to the Main-Branch.

A special version of a Feature-Branch is the Team-Branch (not visible in the picture). A Team-Branch is a Feature-Branch which will be reused after a completed feature (and reverse integration to the Main-Branch). A Team-Branch will reduce the number of branches and it is assign exactly to one team or team member. It is also important, that on a Team-Branch it is allowed to implement exactly one feature at a time.

Developer-Version

The Developer-Version (in the picture the labels 2.1.2016.1 or 2.1.2016.2) are needed, when you have to create a version of your application or component to deliver it to another team. We had some dependencies of components and for breaking features, all of them were influenced. So we created a Feature-Branch in each component and published for each a Developer-Version. The dependent component could reference that Developer-Version in the corresponding Feature-Branch. A Developer-Version is just for internal use, it isn’t allowed to deliver it to the customer.

Production Branch

The Production-Branch is the representation of the actual delivered version of an application or component. In our situation, it wasn’t possible that there were several versions in production. So, we didn’t need for each release a separate branch, we could reuse a branch – the production branch.

There a two approaches how to refresh the Production-Branch: After the end of the Feature-Freeze, when the new version was shipped. The other possibility is before you create the first hot-fix (refresh with the help of the labeled version).

Feature-Freeze

When you have to create a new version, you have to decide what you will or could deliver. After you merged all good Feature-Branches then the Feature-Freeze begins. During the Feature-Freeze it isn’t allowed to add any features, but it’s allowed to fix the current version. Before the Feature-Freeze ends, you have to release your current version to ship.

When the Feature-Freeze takes a long time, then you have to create Feature-Branches to continue the development for the next version.

Branching and Continuous Integration

Branching and Continuous Integration aren’t the best friends. With Branching you want to isolate the features from each other, but you pay it when you have to merge. Merging is a manual integration of two versions, and it isn’t always fun to do it.

With Continuous Integration you want to prevent a big bang integration. You want to give the developers as early as possible feedback, that the current code is breaking or not.

In our situation, we had Continuous Integration for the Main-Branch, but not for the other branches. I would recommend to add Continuous Integration for the other branches too if they take a longer time. I would recommend also to forward integrate several times to avoid a difficult merge at the end.

Further Reading

Microsoft Branching Guide III

Feature Branch by Martin Fowler

Software Development Stages

  • Share/Bookmark

First developer meeting in Bern

January 21st, 2010 Patrick No comments

Today at the Fachhochschule happened the first developer meeting in Bern. The first tasks were the presentation of each participant and to collect the interests to discuss.

entwicklertreffen

After that Florian Kammermann presented his thoughts about software development. He’s highly interested in business oriented software developing. That means for him, that you have to be agile and follow the principles like DRY, separation of concerns, etc.

At the end of his presentation he showed his favoured design patterns strategy pattern and state pattern. He showed the patterns by java examples.

  • Share/Bookmark

Favoured podcasts

November 1st, 2009 Patrick 2 comments

I migrated my desktop PC to Windows 7 Professional. I didn’t choose the upgrade path, I install Windows 7 from scratch. So, after installing iTunes I had to register my favoured podcasts again:

.Net

Java

Currently I work in a .Net environment, so the list of .Net podcasts is a bit longer. If you are interested in more Java podcasts, there is a question about that topic on Stackoverflow. The following three podcasts are definitely interesting:

Do you have other interesting podcasts?

  • Share/Bookmark
Categories: .Net, Java, Private, Software engineering Tags:

Kaizen and Software Engineering

October 27th, 2009 Patrick 3 comments

Kaizen is a very interesting approach, also in the software industry. On Wikipedia you’ll find the following description of Kaizen:

Kaizen is a Japanese word adopted into English referring to a philosophy or practices focusing on continuous improvement in manufacturing activities, business activities in general, and even life in general, depending on interpretation and usage.

Kaizen aims to eliminate waste, to improve the process or activities (techniques). I heard about Kaizen the first time at an economic course, and I found the Muda (seven wastes) very interesting. I tried to find locations or situations where you can detect such wastes:

Overproduction

Overproduction happens each time you engage more resources than needed to deliver to your customer. For instance, large batch production, because of long change over time, exceeds the strict quantity ordered by the customer. For productivity improvement, operators are required to produce more than the customer needs. Extra parts will be stored and not sold. Overproduction is the worst Muda because it hides or generates all others, especially inventory. Overproduction increases the amount of space needed for storing raw material as well as finished goods. It also requires a preservation system.

Overproduction happens then, when you don’t follow the YAGNI principle. Don’t try to make assumptions about the future or the customers. Just produce the things as simple as possible.

Unnecessary transportation

Each time a product is moved it stands the risk of being damaged, lost, delayed, etc. as well as being a cost for no added value. Transportation does not make any transformation to the product that the consumer is supposed to pay for.

Don’t build chatty interfaces, make use of the coarse-grained interface pattern.

Inventory

Inventory, be it in the form of raw materials, work-in-progress (WIP), or finished goods, represents a capital outlay that has not yet produced an income either by the producer or for the consumer. Any of these three items not being actively processed to add value is waste.

Deliver early and often. Don’t wait at the end of the project to deliver the whole software at once. If you deliver your software earlier and often, you will receive more feedback and so the costs to fix bugs will reduce. Also the customer will be happier because he could use much earlier important parts of your software and he could observe better the progress of the software project.

Motion

As compared to Transportation, Motion refers to the producer or worker or equipment. This has significance to damage, wear, safety. It also includes the fixed assets, and expenses incurred in the production process.

Good hardware and a good chair is very important to be productive. Slow computers are just horrible to work with and a bad or cheap chair is not very good for the health of the software engineers. If the software engineer feels comfortable, he’s much more able to be concentrated or work longer.

Defects

Whenever defects occur, extra costs are incurred reworking the part, rescheduling production, etc.

Reduce Defects. Unfortunately there doesn’t exists a programming language where it isn’t possible to make no errors. So testing is absolutely necessary. Do unit testing with or without TDD, but a modern software project should have tests (unit tests, integration tests or acceptance tests, etc.). Without tests you don’t have a safety net (regression tests) if you change something in your project. One of the worst error a customer could find is one which he already found and was fixed.

Over-Processing

Over-processing occurs any time more work is done on a piece than what is required by the customer. This also includes using tools that are more precise, complex, or expensive than absolutely required.

Overengineering and Patternoholics are a danger to do more than it is necessary.

Waiting

Whenever goods are not in transport or being processed, they are waiting. In traditional processes, a large part of an individual product’s life is spent waiting to be worked on.

Slow computers where you have to wait for a build step or just for the compiler are an unnecessary waste. Also if you wait for an answer from your customer or an other teammate. Don’t wait, make a follow-up, make a phone call or write an other mail. Also don’t let the others wait. If you receive an email, answer it or write a short email to say that you will response later, so that the other knows, that you saw his mail and you planed to response him.

Conclusion

One important question is: “Do you add value to your solution, product or service which the customer is ready to pay for?” This question or view isn’t new. It focus all the actions in software engineering on business value, the value which the customer pays for. To reduce the waste you have to improve (Kaizen) your code, methods and communication with others. The seven wastes are a help to find locations or situations where waste could happen.

  • Share/Bookmark