Ian Cooper 的个人资料Staccato Signals日志列表 工具 帮助
4月29日

London .NET user group May 10th

More to follow but our next event will be May 10th and we will have Mike Ormond talking about ASP.NET Ajax and Alan Dean asking if we have got Object-Orientation all wrong. Details to follow.

DDD5 Voting has begun

Voting has begun. You can register your favourites here.


LINQ to Entities and Occam's Razor

MS has announced that LINQ to Entities will not ship with Orcas. I think this is sensible as it seemed to be short of what was required from prime time. Better to get it right than to ship it.

MS has clarified their positioning of LINQ to Entities and LINQ to SQL in a new post. The post outlines the vision behind the Entity framework; and by implication behind LINQ to Entities which uses LINQ syntax as a query mechanism for LINQ to Entities. A key phase would be that the: "ADO.NET Entity Framework... [enables] applications to write to a conceptual data model with strong notions of type, inheritance, and relationships." Essentially the ADO.NET team have implemented an ADO.NET provider that consumes an abstraction of the underlying data source, be the DB or something else and allows developers to query against that store using an abstract form of SQL called ESQL. ADO.NET works as before against this new provider, but uses ESQL or you can use LINQ to Entities.

This is a noble vision of independence from the underlying physical storage; however, I think that we need to bear in mind the YAGNI principle. In a lot of cases the abstraction provided by a single mapping file or attributes, as in LINQ to SQL or other ORM tools like NHibernate or Wilson O/R Mapper, has proved to be more than enough to insulate us from the DB and the additional complexity of the new ADO.NET provider is not required. We have solutions that work without it, today.

For me the sweetspot for LINQ to Entities - legacy database systems or complex mapping requirements - means the tool is too complicated for most instances. The POJO movement was a reaction to the overcomplexity of J2EE. Hopefully we can learn from the Java community and not repeat their mistakes by forcing engagement with product that is too heavywieght for many tasks. Otherwise I forsee a 'plain old SQL' movement rising up against the complexities of the Entity Framework. The Entity Framework will suffer as a result from being pitched in the wrong space,.

The key to most ORM toolsets adoption is the productivity benefits they bring and the clean programming model - persistance ignorance - that they support. When I look at LINQ to Entities I see the former being dragged-down by additional abstractions and in the latter case entirely absent; by contrast, LINQ to SQL hits both of these spots.

LINQ to Entities is overcomplex for many needs and its use in many scenarios defies Occam's Razor - Entities should not be multiplied beyond necessity. For simple mapping scenarios, LINQ to Entities feels bloated and I don't want to use until I have to use it. The very design goals for LINQ to Entities preclude it ever being a simple solution.

It is interesting to note that MS states that the reasons to use LINQ to Entities over LINQ to SQL are as follows:

If you are writing an application that requires any of the following features, you should use the ADO.NET Entity Framework:

The ability to define more flexible mapping to existing relational schema, for example:
  • Mapping a single class to multiple tables
  • Mapping to different types of inheritance
  • Directly Modeling Many to Many relationship
  • Mapping to an arbitrary query against the store
The ability to query relational stores other than the Microsoft SQL Server family of products.
 The ability to share a model across Replication, Reporting Services, BI, Integration Services, etc.
 A full textual query language
The ability to query a conceptual model without materializing results as objects

Some of these look like very valid scenarios for LINQ to Entities; we do need support for complex legacy structures that do not map well on to simple ORM tools, and I would welcome the Entity Framework in that context - we have a legacy DB that falls firmly into that position; however bitter experience suggests to me that trying to build a shared model across Replication, Reporting Services, BI, Integration Services, etc is a nightmare and you should consider just having a seperate model for your transactional stores from your reporting stores etc and using SQL and BI tools to do your transformations. Don't do evil to begin with.

However the decision not to support querying to relational stores other than Microsoft SQL Server from LINQ to SQL seems to be deliberately crippling that product for no good reason. The provider model should be exposed and other implementations encouraged. Isn't that the value of LINQ? This feels like an internal turf war over who provides the standard data access layer to .NET developers. As a customer I am not interested in your internal disputes but in solving my customer's problems with your tools. LINQ To SQL should be capable for simple mapping scenarios across backend types and the provider model should be opened up for that. Do not force us to swallow the whole LINQ To Entities pill, just to get support for mutliple backends. This is not a reasonable decision.

Similarly I would hope that later releases of LINQ to SQL could be enhanced to support many-to-many associations and table per concrete classes inheritance strategies. Why force an upgrade to LINQ To Entities to obtain these feature sets which are common to many ORMs which do not have an additional abstraction layer? I do not see any technical reason for the Entity Framework being a requirement for these to work. NHibernate and Wilson for example, already provide these capabilities on the existing ADO.NET framework.

Experience with many MS developers suggest that if you give an 'upgrade path' to LINQ to Entities you will implicitly degrade LINQ to SQL as being a toy. It is not; unless you make it so.

Come on give us the LINQ to SQL we deserve and keep the Entity Framework for the complex scenarios that require that level of abstraction? Hell, the 'Plain Old LINQ to SQL' movement starts here. Feel free to join up!

Style guide for using var in C#3.0

One interesting piece of feedback from the MVPs at the summit was quite how many seemed concerned that the new C# 3.0 keyword var - which allows type inference - would be abused. Specifically many seemed concerned that people would type:

var anExampleString = "I am an example";

instead of

string anExampleString = "I am an example";

The heart of the objection is that this becomes lossy; we are no longer explicit about the type. I am not sure that I agree with the strength of this objection.

var can only be used for local variables so the distance between declaration and usage should always be short. Short enough that you can look back and see the type from the declaration. Having the type on the lhs does not help with this lookup, because you still need to look back to the declaration. Your method body should be short anyway, less than a page. If it is longer you need to refactor to Extract Method to Express Intent; look for comments that describe code blocks as seams to extract out a well-named method. If it short then in a lot of cases, inferring the type should be as simple for compilers as humans.

We do potentially lose some information on numeric types as to how the value is stored and I guess that where people are unsure how literals will be translated there may be a desire to be more explicit, but I suspect that in the majority of cases with primitives and built in types, this is not really an issue. My style guidance right now would be explicit where it is otherwise unclear, but default to var where it is obvious so as to avoid unecessary duplication.

Of course when we call a method and assign its return type to var, it may not be so obvious:

var result = myClass.GiveMeYourState()

In this case it is a lot less clear what the type of result is. Intellisense is obviously a help here as it will tell you what methods and properties the type supports, and you may take the attitude that you don't care what type it is, only what operations you can carry out on it. Still it might be less obvious to a reader what type you are dealing with. I'm inclined to lean toward not needing to know what type it is for now. Hopefully the capabilities of the object should be obvious from the interaction. I am happy I think to rely on tool support to help me figure out the exact type, even if outside an IDE that is not available. I think that even knowing the type, I cannot guarantee to recall the operations that are valid on the class without browsing it. Recognition is always easier than recall and the productivity benefits from intellisense come from the ability to explore a type's capabilities not the knowledge around its type. Again I suspect my style guidance is to default to var.

I am embracing change here, but I suspect mileage may vary a lot until folks get used to this paradigm.



4月25日

Venue Details: London .NET User Group 26 April

Just a reminder that our meeting this Thursday is the first of our 'wilderness years' and will not be at Microsoft's facility in Great Pultenay Street. Instead we will be over in Docklands. So those of you working for investment banks may find it easier to make one of our meetings because we will be right on your doorstep.

CSFB are kindly hosting this event for us at their Docklands office. Details are:

18:30 until 8:30.
The address is:

Credit Suisse
One Cabot Square
London
E14 4QJ
 
Transport wise: you can use the DLR or the tube (Jubilee Line towards Stratford), Canary Wharf station.
 
Get off the tube at Jubilee exit to the right. Go up the escalators and exit the station out the main glass domed exit.
Turn right out of the station. Walk past some clocks/bar/restaurants. Go up some steps, to the road level. Turn left and follow road under a light rail bridge (DLR) You will
arrive at Cabot Square. Look up and look diagonally across the  park/fountain and see our building.

Ask at the ground floor reception for Leslie Muller and they will direct you to the right floor.


4月19日

Geek Dinner 24 May

Our next geek dinner will be 24 May. Zi has put a page up for the dinner on our wiki, so sign up if you want to come along.

http://66.129.68.3/wiki/24th%20May%20Geek%20Dinner.ashx

4月17日

London .NET User Group 26 April

I just wanted to let you know the date of the next meeting. The first of our 'wilderness years' presentations as we wander between venues waiting for our new London home it is likely to be in Docklands, so bear that in mind when planning. I will confirm the location details later.

April 26th: Go With the Flow - An Introduction to Windows Workflow

Changing business requirements are the bugbear of the application developer. The Windows Workflow Foundation is a new component of .NET 3.0 designed to ease the pain by providing an easier way of modelling long-running business processes in code.
The engine provides in-built support for transactions, business rules, and persistence. Extensions to Visual Studio provide a graphical environment for modelling workflows. All of this can be incorporated into your applications to make them more adaptable, reliable and reduce your development time.
This talk is aimed at existing .NET developers who want to understand Windows Workflow and have enough knowledge to decide whether it will be useful in their projects. The talk introduces workflows, the workflow engine and its design tools, looks at compensation and fault handling, the rules engine, transactions and communicating with external services.

Bio:

Ben Lamb has been writing business applications since the days of Visual Basic 2.0. During the dot-com era he had a brief foray into web development helping to write the UK's first online hotel reservation system, LeisureHunt, and developed geo-location services for a 3G mobile phone company. Realising that .NET was his platform of choice he now writes financial trading systems for investment banks in the City with occasional diversions into Python, Open Source and other interesting technologies.

4月12日

Designing for testability, TypedMock, and the dangers of an easy life

I was pointed in the direction of an article on Test-Driven Development on the Code Project by Eli Lopian called Stop Designing for Testability.  Eili is one of the team behind TypeMock. The article looks at using Test Doubles and shows an example of using a Fake Object and then using TypeMock, which is a Mock Object library to replace the fake.
 
 The necessity to test doubles comes from the issue that we are trying to write unit tests. But the unit we are placing under test may itself have dependencies on other units. There are a number of issues with testing multiple units.
 
  • When we start writing tests that cover these multiple units we will find that changes can cause mulitple tests to fail, resulting in it being hard to diagnose faults.
  • If we cannot seperate out our dependencies we can end up having to write complex test setup code to put a single method under test and may have no easy way to test the success or failure of an operation.
  • The dependencies may not be suitable for unit testing, such as components that talk to the database, network, or file system.
It turns out of course that the act of getting our unit under test forces us to decouple it from problematic collaborators by using a test double. This has the virtue Making our classes testable helps move us toward the Open Closed Principle (OCP) and the Dependency Inversion Principle (DIP). This property of Test-Driven Development is sometimes called Emergent Design and is a key benefit of the TDD approach.
 
Mock object libraries take some of the work out of creating test doubles, they do this by creating an instance using reflection and allowing you to set the return values method calls. Mock libraries can also allow you to confirm that you get the interactions you expect. There is an issue here around maintainability.  Fowler has a good summary in Mocks Aren't Stubs of the issues here. You should be aware that opinion is divided in the TDD community over the dangers and value of mocks as opposed to stubs. My experience here is that interaction based testing (or behaviour driven testing) is more expensive to maintain, because the test peers into the implementation making refactoring of that implementation expensive as it tends tor require changing the test. I went heavily with interaction based on previous project for DB access, where  would now use a fake Repository instead. Other people may have different experiences.
 
TypeMock is interesting because its selling point is that you do not need to design for testability. TypeMock intercepts object construction allowing you to replace instances with mocks 'on-the-fly'. Eli's article states that this is a principle advantage of TypeMock, not needing to design for testability. But by removing the need to design for testability TypeMock also risks removing the driver for emergent design. Simply put if I can check the objects that my class is composed from without needing to inject them, I don't have the motivation from TDD to decouple them and as a result I won't see OCP or DIP emerging. For this reason I always feel that TypeMock is too sugary. It seems tempting, it tastes good for a bit, but ultimately overconsumption will make you sick. BTW the record and play model of mocking is available in Rhino Mocks, without the same perils.
 
I tend to see an enthusiasm for TypeMock among people who don't have a very good grounding in the properties of good OO designs. Often those who think that OO begins and ends with encapsulation.
 
A number of people raise the issue of the value of using TypeMock with legacy code i.e. code without tests. I'm cautious here but can see the argument in that it may be one way to provide a seam for behaviour preserving tests to use object construction. The danger I think is that you will get addicted to this approach and thus not be motivated to refactor your design. I'm still undecided on this usage of TypeMock, but my gut feeling is that it could be very easy not to break out of the big ball of mud that you probably have if you use TypeMock as a crutch.
 
 
 
4月6日

Processes, Practices, and Priorities

Ivar Jacobson is currently speaking out against the focus on process over practice in development methodologies. I saw Ivar make similar statements at the Architect Insight conference earlier this year. Considering that Ivar Jacobson is one of the parents of UML and the father of the Rational Unified Process, that's quite a heavywieght opinion. Ivar notes that
 
"it doesn't matter which process you adopt as long as it is adaptable, extensible, and capable of absorbing good ideas, even if they arise from other processes.
 
To achieve this kind of flexibility, things need to change. The focus needs to shift from the definition of complete processes to the capture of reusable practices. Teams should be able to mix-and-match practices and ideas from many different sources to create effective ways of working."
The problems with existing process for Ivar can be summarized as:
 
    • Processes accrete new elements as they strive to become more complete, and never indicate that portions can be dropped making the whole expensive and unwieldy. Yet at the same time processes are sold as an 'all-or-nothing' proposition.
    • Teams will always tend to modify the process to fit their scenarion and practices. This means that while the organzation believes it is following the process most of its teams are not. This increases cost as unecessary work is done, or resources are spent on auditing the process to ensure conformance. That cost does not contribute towards delivery of the project.
    • Learning the process is often costly and does not in itself help the team deliver, just conform to the process. What the team wants is practical advice on specific issues.
    • Process is a set of guidelines to be followed not a set of tools to help you.

Ivar suggests that instead we need to focus on sharing practices, the difficulty for Ivar is how we collate that practice and share it, without it becoming process.

Personally I have always liked Alistair Cockburn's approach to Agile development in his Crystal methodologies. Alistair focuses on priorities for software development and his various flavours of the Crystal methodology describe practices for different team sizes that can be used to achieve those priorities. Alistair observed teams working on software development projects and observed the following properties of successful projects:

 

    • Seat people close together, communicating frequently and with goodwill.
    • Get most of the bureaucracy out of their way and let them design.
    • Get a real user directly involved.
    • Have a good automated regression test suite available
    • Produce shippable functionality early and often.

And observed that if you can provide those properites "most of the process details will take care of themselves". These properties are the cornerstone of agile development methodologies from SCRUM to XP, not just Crystal and Alistair's point is that it is less imporant how you achieve them, but that you have the properties.

Within Crystal the properites of successful projects are achieved by meeting priorities.

A lot of organizations struggle with XP because it requires high maturity. It is not extreme programming for nothing. The problem is that teams who do not have sufficent maturity drop some of the practices, and with no guidance on how to compensate for the practices they have dropped, fail. XP practitioners often recite the mantra to 'follow all of the practices'. The issue is that for some teams, while they may be willing, the bar is out of reach. The teams lose confidence in agile methodologies, because XP does not deliver results for them. By dropping some of the practices they fail to meet some of the priorities of successful teams. Now experienced practioners of XP have probably internalized the priorities over time, which enables them to successfully coach XP teams to success. But XP is not explicit about its priorities in a way that allows a team figure out how to compensate for the practices they cannot achieve with alternative practices. 

By idenitfying priorities as Crystal does it becomes possible for teams to change practices that don't work for them, and provided that they still have some means to meet the priorities, succeed. In addition, it becomes possible to review practices, so that we fit the practice to the scenario, rather than assuming a one-size-fits-all approach. At that point the practice begins to work for us, rather than us working for the practice.

Cockburn's approach in prioritizing properties of a project over processes, seems to be the best way to meet Ivar's goal of switching the focus to practices without getting bogged down in process. Crystal identifies seven priorities:

    • Frequent Delivery
    • Reflective Improvement
    • Osmotic Communication
    • Personal Safety
    • Focus
    • Easy Access to Expert Users
    • Technical Environment with Automated Tests, Configuration Management, and Frequent Integration

While XP satisfies these properties, so do other combinations of practices. Working to priorities allows your team to evaluate practices to determine how well thet meet with these goals. It also allows you to review your project to see which items you are weak on and need improvement.

 

 

 

 

Doing my LINQ sessions as a webcast for VBUG

I will be doing my two LINQ sessions as a webcast for VBUG. The date on the events page is likely to change to May 2nd for the first session and a second session in June. I'll keep you all posted on the dates. I'll be adding some VB 9.0 examples to the talk over the next few weeks to account for the VBUG majority interest.
 
While we are talking about VBUG their next London event is on BAM:
 

VBUG: Business Activity Monitoring (BAM) in BizTalk with Benjamin Goeltz

Date: Wednesday 18 April 2007
Overview: Business Activity Monitoring (BAM) in BizTalk - BAM is capability that is often overlooked, but sorely needed, when integration solutions are implemented. In this talk, I would talk through what BAM is, how BizTalk enables business activity monitoring, and demonstrate how to implement it. This session requires a baseline understanding of core BizTalk concepts and artefacts (most significantly workflow / orchestrations and messaging / schemas), and covers both technical bits and business value.
Venue: Laser form Professional Solutions, Laserform House, 5 - 7 New Street , London , EC2M 4TP
Times: 18:00 - 20:30 (18:30 start)
Registration Details: Mailto: emma@vbug.com OR call 01753 649680
Price: FREE for VBUG Members & Guests

4月4日

Continuous Learning and Ruby

One of the admonitions of the Pragmatic Programmers is that developers spend time on improving their skill set continuously. The pace of change in this industry means that if you rely on your existing knowledge you will soon be left behind. I have been prety good at following this pattern over the years, and usually put in a lot more than the 4-5 hours a week (IIRC) that Andy and Dave recommend. But I've fallen behind a bit on their continuous learning goal of 'learn a new language every year'. I have had good intentions, but my copy and Andy and Dave's book on Ruby that I purchased in 2003 (the so-called pickaxe book) has sat stubbornly on the shelves.
 
So I dediced that it was time to dust it off. Partially the move has been inspired by learning the new features appearing with C# 3.0 and LINQ to go and look at how other languages use features like iterators (yield), lambda expressions, etc., and are more functional in approach than my traditional imperative language background, do things. When searching for best practices and patterns for their use it seems to be worth exploring languages that have experience of those feature sets. In addition thinkers whose work I like, like Martin Fowler, Justin Ghetland, and Robert Martin are increasingly speaking in Ruby. Not all the time, but enough to make me interested to speak that language with them. Finally I want to understand the hype around Rails and the best way to do that is to use it.
 
It is important to have goals with this kind of effort, so that it is not just an exercise in book reading, but involves using what you learn. Ruby is not looking like beoming my day-to-day language of choice, so I need a number of additional projects:
 
  • Using Ruby as a scripting language: In other words using it to automate repetitive tasks or help with testing. I'm intending to use Brian Marick's Everyday Scripting with Ruby to give me a leg up here.
  • Learn how to use Watir (pronounced 'Water'). Web application functional testing is definitely a weak spot in my armory and this looks like possibly filling that gap. Scott Hanselman raves about it, so there must be something there. I am tempted by Selenium too, but I have to focus somewhere...
  • Use some Rails. I'd like to get some experience of what makes Rails advocates say it is da'bomb for web site development. For me, that means learning Ruby and getting my hands dirty, rather than just reading what the rails guys blog about it. Dave Verwer gave a great presentation at a previous DDD, but I want to experience it.
  • Use Gardens Point Ruby.Net. I want to see where it is, and how far it has to go. The CLR is a multi-language platform after all.

I'll let you know my progress as I go, but already some of the understanding I am getting from Ruby's use of iterators and blocks is helping me comprehend what is possible with iterators and lamda expressions in C# 3.0. In that sense Andy and Dave are right that learning another language is helping me with the language I use everyday.

Out of interest, I looked at Boo as a choice as well. Boo looks really interesting, but I was drawn to Ruby by the support out there. having Andy and Dave write a book on your language sure helps. But I certainly have Boo tagged as a language to watch. Interestingly Boo is statically typed but has duck typing around interfaces (if it walks like a duck and talks like a duck...).

I also considered IronPython but it didn't give me access to the projects out there in Ruby so it lost the fight.

Finally, for those of you who want to know what the Pragmatic Programmers are pitching now, it seems that Erlang is the subject of one of their latest works. Just shows the growth of interest in parallel programming. But that's another post.