Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Source code for "On loquacious interfaces, again" post
// see http://notherdev.blogspot.com/2012/02/on-loquacious-interfaces-again.html
public class Program
{
static void Main(string[] args)
{
// the Building instance created "manually"
var classicBuilding = new Building()
{
Address = "1 Example Street",
Floors = new[]
{
new Floor()
{
Rooms = new[]
{
new Room() { Area = 33.0 },
new Room() { Area = 44.0 }
}
},
new Floor()
{
Rooms = new[]
{
new Room() { Area = 20.0 },
new Room() { Area = 30.0 },
new Room() { Area = 40.0 },
}
},
},
Roof = new Roof() { Type = RoofType.GableRoof }
};
// identical Building instance created by loquacious API
var loquaciousBuilding = Building(b =>
{
b.Address("1 Example Street");
b.Floor(f =>
{
f.Room(r => r.Area(33.0));
f.Room(r => r.Area(44.0));
});
b.Floor(f =>
{
f.Room(r => r.Area(20.0));
f.Room(r => r.Area(30.0));
f.Room(r => r.Area(40.0));
});
b.Roof(r => r.Type(RoofType.GableRoof));
});
}
public static Building Building(Action<IBuildingCreator> action)
{
var creator = new BuildingCreator();
action(creator);
return creator.TheBuilding;
}
}
// domain model
public class Building
{
public Building()
{
Floors = new List<Floor>();
}
public string Address { get; set; }
public ICollection<Floor> Floors { get; set; }
public Roof Roof { get; set; }
}
public class Floor
{
public Floor()
{
Rooms = new List<Room>();
}
public ICollection<Room> Rooms { get; set; }
}
public class Room
{
public double Area { get; set; }
}
public class Roof
{
public RoofType Type { get; set; }
}
public enum RoofType
{
None,
FlatRoof,
GableRoof
}
// loquacious builders - public part
public interface IBuildingCreator
{
void Address(string address);
void Floor(Action<IFloorCreator> action);
void Roof(Action<IRoofCreator> action);
}
public interface IFloorCreator
{
void Room(Action<IRoomCreator> action);
}
public interface IRoomCreator
{
void Area(double area);
}
public interface IRoofCreator
{
void Type(RoofType roofType);
}
// loquacious builders - internal part
internal class BuildingCreator : IBuildingCreator
{
private readonly Building _building = new Building();
public void Address(string address)
{
_building.Address = address;
}
public void Floor(Action<IFloorCreator> action)
{
var creator = new FloorCreator();
action(creator);
_building.Floors.Add(creator.TheFloor);
}
public void Roof(Action<IRoofCreator> action)
{
var creator = new RoofCreator();
action(creator);
_building.Roof = creator.TheRoof;
}
public Building TheBuilding { get { return _building; } }
}
internal class FloorCreator : IFloorCreator
{
private readonly Floor _floor = new Floor();
public void Room(Action<IRoomCreator> action)
{
var creator = new RoomCreator();
action(creator);
_floor.Rooms.Add(creator.TheRoom);
}
public Floor TheFloor { get { return _floor; } }
}
internal class RoomCreator : IRoomCreator
{
private readonly Room _room = new Room();
public void Area(double area)
{
_room.Area = area;
}
public Room TheRoom { get { return _room; } }
}
internal class RoofCreator : IRoofCreator
{
private readonly Roof _roof = new Roof();
public void Type(RoofType roofType)
{
_roof.Type = roofType;
}
public Roof TheRoof { get { return _roof; } }
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.