| Ian Cooper 的个人资料Staccato Signals日志列表 | 帮助 |
|
10月31日 London .NET user group 15th NovemberThe agenda for our 15 November session is finally agreed. We are focusing on connected systems with this one. Sign up at our site or mailing list. Introduction to Windows Communication Foundation This presentation will start with an introduction to WCF and it's features, before moving onto code examples and explanations of some of it's more advanced concepts. The presentation will conclude with demonstrations on how WCF can be used to implement common integration design patterns, and an open-floor conversation about how it can be put to use within your organisation. Dean Robertson works as a Senior Software Consultant for Cassium Technologies (part of the Netstore Group), delivering complex integration solutions to the UK financial industry. He has several years experience with Microsoft technologies, but has recently specialised in Microsoft BizTalk, .NET and WinFX. A walk inside BizTalk 10月26日 London .NET User Group: Next talk 15th NovemberThe next evening for the London .NET user group (and our last presentation of the year) will be on Wednesday 15th November. I'll hopefully confirm the speakers in the next couple of days, but we are hoping to bring you presentations on WCF and BizTalk right now. Watch this space and book out your diaries. Resharper bluntedAlthough it gave me faithful service, when it used to be the only refactoring tool in town I have pretty much done with Resharper now. It is just too bloated and unfriendly. I have turned off its feature set apart from code re-formatting and its object browsing capabilities. Instead I am wedded to CodeRush with Refactor! Pro. The refactoring experience is much smoother, the performance hit negligible and now that they have a Training Panel I am beginning to master the templates too. I have not really used a template approach to coding before, but I seem to be getting over the initial butterfingers period and seeing real productivity gains. One day I'll be as slick with them as Oliver Sturm... well maybe. All the DevExpress guys need is to add a reformatting option to CodeRush (and maybe some object browsing capabilities) and I can finally kill of the Resharper. For now its a shell, with all its options disabled, just so I can use corporate standard code formatting. 10月17日 Ted Neward nails the lack of knowledge for many .NET Enterprise developersTed Neward nails on the head the pitiful state of learnings from the Java community that the .NET community has picked up. From my perspecitve the average carries nothing like the OO skill set I would expect from someone who would class themselves as an Enterprise Developer. Many of the best books on patterns and practices are written in Java. But that should not stop at very least the C# developer from being able to understand them. Thankfully Robert C. Martin's Agile Software Development now has a C# edition and authors like Fowler with Patterns of Enteprise Application Architecture and Joshua Kerievsky Refactoring to Patterns with have both Java and C#. But Fowler's book on Refactoring and Beck on Test-Driven Development remain better than any of the C# clones that have re-phrased their work. The best patterns books for me are the GoF's Design Patterns and Head First's Design Patterns, neither of which are in C#. People need to read Evans Domain Driven Design and Better, Faster, Lighter Java by Tate and Gehtland. This is just scratching the surface. Think yourself lucky for now. A lot of the thought leaders are playing with Ruby - so you may have to develop a working knowledge of that language in time to keep up. Right now there is no excuse for Enterpise focused .NET developers not to be picking this stuff up. "No man is an island, entire of itself...any man's death diminishes me, because I am involved in mankind; and therefore never send to know for whom the bell tolls; it tolls for thee." - John Donne 10月14日 Databases and unit testingRoy Osherove has an article discussing ways to rollback data used in unit testing. It is an interesting piece and Roy has done some good work in this area, but I worry that Roy is straying away from the point: Unit tests should not talk to external resources, such as databases. Michael Feathers has a fairly good summary of the rules for tests (linked here). Rule One is that a test is not a unit test if it talks to the database. As Michael Feathers points out: Tests that do these things aren't bad. Often they are worth writing, and they can be written in a unit test harness. However, it is important to be able to separate them from true unit tests so that we can keep a set of tests that we can run fast whenever we make our changes. Kent Beck talks about this under Mock Objects in Test-Driven Development where he states the solution is not to use a real database most of the time. Using a mock object is the solution given there, but beware the naive approach of just using NMock2. The difficulty here is that you can end up with Fragile Tests because you are testing the interaction with the external component. See Martin Fowler for more on this. You may instead be better off with a Fake Object, whose state you can then query after. We have definitely begun to suspect that we might have been better off avoiding use of NMock to fake our databases in a couple of cases, as the tests may prove fragile (though there is no real pain yet). William Caputo has some good articles on testing across boundaries that look in detail at the ideas behind a fake database. Among other things the problem with database tests is that they don't push you toward de-coupling you data access layer in the way that the inversion of control of using a Test Double approaches. So you miss (im)proving the design by testing when you adopt the rollback approach. My personal experience has been that the Data Access layer has always benefited from the insights we gained this way. Its not about purism, its about the purpose of TDD. Though I confess that it is better that someone is testing and talking to the DB than not testing at all, it is important people understand what the alternative is. We tend to use two test assemblies in a project. One is the unit test dll. It represents the tests that need to run fast all the time. The other is the integration test dll where we put all the tests that break Michael's rules - the ones that talk to external resources. Note that we often have an overlap. A unit test will prove our design, and an integration test shows it all works when hooked together. That is no bad thing. These are both points of failure and it is good to automate them. Many of the techniques that Roy describes are valuable when dealing with these integration tests (or even acceptance tests driven by tools like FIT, but they should be separate from you unit tests). BTW once you are in .NET 2.0 you can use System.Transactions to provide the nested transactions you need for rollback of your unit tests, and there is no longer any need to use Enterprise Services to do the work. This has the advantage that it may not require an Ole Transaction. 10月12日 That man must smoke eighty a dayFollowing a link from Mike Taulty's blog I popped on over to the .NET 3.0 courses from Microsoft e-Learning. They are free, and supposedly about 2 hours long. The voice-over is done by a man with one of the gravelliest voices I have ever heard. Rod Stewart eat your heart out. That voice is surely the product of dedicated chain smoking. It can't be natural. I'm sitting here convinced that I am being taught by a programmer who has seen more than his share of strong black coffee, filtertless Camels, and whisky. More useful feedback when I have it 10月11日 Sacred Cows: Reference types and value typesOne of the standard interview questions we ask is "What is the difference between reference types and value types". The usual answer we get is "Reference types are allocated on the heap and value types are allocated on the stack". That is fairly common currency among .NET developers and articles like this one. When I then respond is that always true? I usually get some puzzled looks and maybe a stab at boxing. But what I am really searching for is an understanding that the common wisdom is, at least, equivocal with the truth. DefinitionsLet us get some definitions out of the way: The Stack: Also called the call stack it is an area of memory reserved for information about the currently executing call. The main job of the stack is to store the return address which we pop off the stack when we return (called unwinding the stack). You can see the stack in the Visual Studio IDE via the stack trace window. Local storage can happen on the stack. This is much faster than allocating memory from the heap. Variables declared on the stack are destroyed when the method returns, so don't need to be garbage collected (see also stackalloc). The Heap: This is a block of memory used for dynamic memory allocation. It is more expensive to allocate here and, as we have to free the memory we are using, variables declared on the heap need to be garbage collected. Reference Type: A pointer to the location on the heap of an object. Note the use of indirection, this is not the object itself. Hence the use of ReferenceType a reference (pointer) to a type. Value type: An object in memory, accessed without indirection i.e. the thing itself. Note that parameter passing is always by-value unless you declare it by-reference (ref or out). That means we copy. We copy both the value and the reference type (the pointer). That is why changes to a reference type are reflected when the method returns and value types are not unless you pass by-reference. It is also why if you assign a new object to your reference type that change is not reflected when you exit the method, you have only changed the copy of the pointer, unless you pass by-reference. Reference Types, Indirection, and Value TypesStill here? Good then let us talk about where value types and reference types are stored. First the easy part: The object pointed to by a reference type always goes on the heap. That is easy enough and what we usually mean by: reference types are allocated on the heap. Note that we mean the memory that we point to not the pointer itself. The lifetime of the pointer, and the object on the heap are different. Now it gets a little harder. Local value types are allocated on the stack (value types declared within a method body). Their lifetime is the life of the method, so we can allocate them on the stack (because it is okay to destroy them when the method returns). Reference types that are declared within a method body are allocated on the stack too! But only the pointer to the object, not the object itself. The object it points to is always on the heap, and may be available for garbage collection if the last pointer to it just vanished, but not the pointer. That lives on the stack if the declaration is within a method body. Value types and pointers declared as members of a reference type are allocated on the heap along with the reference type that they are part of. The lifetime of the parts of the object are the same as the lifetime of the object. If we could allocate them on the stack, then parts of our object would be de-allocated when the method returned, but parts would remain valid on the heap. If we had another extant pointer to that object (say an argument passed by the calling method) then attempting to access those contained value types and reference types would access memory that had been de-allocated. Bang! So value types and pointers declared as members of a reference type are allocated on the heap along with the reference type that they are part of. BoxingBoxing is used to refer to a value type via a pointer. When a variable is boxed memory for it is allocated on the heap and the state of the value type is copied into the heap. We then have a pointer to that heap allocated memory as a result of the boxing operation. That is what it means to convert from a value type to a reference type. The heap memory we point to is garbage collected, so when the last pointer to the boxed value type goes, it will be available for collection. Note that this is why changing the state of boxed type doesn't change the state of the value type. It's a copy. It is a bit disingeneous to say that in this case "value types are on the heap" as some candidates do. What we have done instead is to create a copy of the value type on the heap, which our reference type points to. What we are looking forSo the reason for asking this question is to flush out whether the developer knows anything about the difference between the stack and the heap and indirection (pointers). It's one way of differentiating skill levels. 10月8日 October 18th London .NET user group updateHi all, In response to feedback from my last session I will be doing a session on Test Driven Development at the London .NET User Group 18th October meeting, in addition to Oliver's XPO session Test-Driven Development (TDD) is a programming approach in which developers begin by writing a test case, implementing the code to pass the test, refactor the code, and then repeat. The technique was publicised as part of the Extreme Programming approach, but is actually a technique that exists in its own right. In this presentation we will look at the how of TDD - red, green, refactor - as well looking at the design benefits it can bring. We will also touch on advanced topics like stubs and mocks. 10月6日 A .NET version of Digg?DotNetKicks is new to me - maybe I've been living under a rock. It follows the Digg or Slashdot model of getting users to post stories. comment on them, and kick them (to keep them on the front page). It requires a login, that may be good as it could help prevent the usual flame wars started by anonymous trolls. This is potentially serious competition for sites like TheServerSide.NET. Certainly it seems to have that elusive x factor in its interface. London .NET user group October 18th: Object/Relational Mapping with XPOI have confirmed the following session by Oliver Sturm at our next London .NET user group meeting: Object/Relational Mapping with XPO I'm still looking in to the possibility of a DDD4 for preview for our second session, but if not I will probably give a session on Test-Driven Development as I had a lot of requests for it after my Top 10 OO practices session last month. To make it more interesting for vets of 10月5日 Sacred Cows: Public Fields vs. Public Properties
Don't Expose your implementation detailsThe advice about exposing state from an object that is reflexive for most of us is: don't expose your implementation details. So the usual pattern for handling state, that we want to share, is to create a private field, and wrap it in a public property: public class MyClass {
} Why do we adopt this approach of encapsulation? Well we might want to change implementation details at some point in the future. Hiding the implementaion protects us against future change, because we are talking to the property instead of the field. We get lower coupling and high-cohesion. Cool. You ain't going to need it?But in .NET it's fairly easy to change our implementation and transform a field into a property if we want to do something other than return the private field. So if my state is now a calculation then changing a field from public int MyState; to public int MyState { get { get 3* 4; } isn't that difficult. We need to note that changing a field to a property forces a re-compile, so if you have external clients to your assembly you don't want to force to rebuild it would seem to be a good idea to use a property. Is this a case of You Ain't Going to Need It (YAGNI). How often will we make the transformation and is the cost bearable when we do. We can't define rule but we need to think about the probabilities. A lot of people will never have an issue with the rebuild, some will. Let's defer this for now. The exception puts the rule to testHow many of you regulary write code like this though: public class MyClass {
} By doing so you are exposing the implementation details of your class - how the event is implemented. It's not common currency among .NET developers, but you can encapsulate your events: public class MyClass {
} Most of us don't do this. In other words, where we are simply returning the state we do not feel the need with events to wrap a property around them. So why do we feel the need to approach fields this way? Juval Lowy recommends that you do just that in the IDesign guidelines. This feature tends to only be used when people have a large number of events to manage. So when we are not just returning a field, but performing some sort of management or algorothm, we may want to use the add/remove accessor syntax. And there lies the obvious condition under which you need to use a property - when the implementation is more complicated than simply returning or setting the value of a field. We include in this when you want to control the ability to set a field i.e. provide a get but no set (and variations like providing differing access modifiers under .NET 2.0). But most of the time we don't change our events this way. So is it a fairly good bet for many of us that we can expose our events as public fields. If it was not, we would be wrapping these with accessors all the time. So can we infer that we do not need accessors a lot of the time? Contracts must have propertiesOne case where we do need properties is if we define a contract. The property may form part of our contract - clients expect us to supply the indicated state. Clients may expect that state to be readonly or volatile. We do not want to specify how you implement the state, we specify that you have it. So in such a case we want a property. Abstractions are the way to define contracts. An interface cannot have a field. It must have a property, because it has no implementation. It is just a contract. public interface IMyInterface Let's look again at the problem that changing a field to a property forces a re-compile. If we depend upon another module and we dont' want changes to that module to impact us we probably want to defined a contract to insulate us from that change. In fact the GoF rule is to program to an abstraction. Refinements of this principle the Dependency Inversion Principle (High level modules should not depend on low-level modules, both should depend upon abstractions; abstractions should not depend upon details, details should depend upon abstractions) and the Open/Closed Principle (Modules should be open to extension and closed to modification) mean that we are likely to have made some bets on interfaces already. So we would hope that we will be using interfaces, and thus properties at the points where we are likely to see the pressure to change the implementation, and thus be insulated from the likelihood of ever needing to change a field to a property. We have already bought into properties at that point. So where we are not dealing with an interface we might want to make the bet that we don't need a property. Or at least look at our options. Of course we will always lose some bets. Sadly computing has always been a win some/lose some propostion. So you need to judge if the benefits of going with the field outwiegh the risk of breaking change. It's about changeUltimately its about change. Encapstulation and information hiding are about insulating yourself against change. The question you need to ask is, is it likely? If so insulate yourself from it. That will probably mean more than just property syntax, and you might need to look at accessors on events too. If it isn't, worry about the cost of using a property when you don't need it. Don't reflexively wrap a private member with a public property, consider your actions in context. TDD and the property testSo is there a cost to having a property. Well apart from extra lines of code, and extra lines of code always increase TCO (total cost of ownership). For those doing TDD one benefit will be removing the pressure to test those property accessors. If you do the question may be, how valuable are your tests, if they are just testing get { return myState;}. But if you don't your code coverage will drop below 100%. Folks vacillate over 'should I be testing my properties'. If you don't know why you need to in that context, the answer might be that you didn't need a property at all. If you are testing an implementation of an interface you want to test 'everything that could break' now and in the future, including a change to the implementation of that contract. So at that point the 'property as part of contract' rule cuts in for us. But if it is not likely to change, you probably don't have an interface and using fields where there is no complexity or algorithm in the property begins to look like a smell of 'specualtive generalization'. ReflectionReflection can be a fly in your ointment because it recognizes the difference between a property and a field. But again the context is everything here. You might be able to ask for either and not care. If you do care then its best to document that for the implementor of the target. Don't forget internal!We talk about public fields here, don't forget if they are not consumed outside the assembly make them internal. Then the choice is a lot easier as if you change you need to rebuild that assembly anyway, but external clients didn't care. So favour an internal field when the context makes sense. Friend assemblies in .NET 2.0 make it easy to test internals without the need to promote to public, just to get them tested, so your public/internal decision can be driven by your consumers outside the assembly that are not just tests. Burn him, he's a witchThe issues around fields vs. properties don't seem well understood so be prepared for dismay from your co-workers if you start using public fields. A lot of coding standards (FxCop and IDesign) try to stamp on this one. Bear in mind the context of those standards (FxCop is driven by framework design guidelines, IDesign is influenced by component design) which may not be your context. It may require a little more thought than some are giving it. For now be prepared to argue the case on this one. You might want to consider your answer in a written test. After writing this blog, prompted by some mentoring I was doing at work, I looked around to see if anyone else was talking about this. There does not seem to be a lot of noise but Eric Gunnerson and Jeff Atwood seem to have had similar thoughts on this issue. 10月4日 London .NET user group: October 18thOctober 18th is the next date for the London .NET user group. Put in your diaries for now. I am confirming the speaker list, and will post session descriptions in the next couple of days. 10月3日 DDD4 Voting is now open
You can now vote for your favourite sessions for DDD4. Get to it. Your votes help us shape waht sessions will be available, and more importantly what rooms we will allocate to them. So we really appreciate yourhelp. 10月2日 Could BLINQ be ASP.NET's answer to Ruby On Rails?BLINQ has obviously been off my radar because the first I heard of it was Brad Abrams linking to Patrik Speiler's blog on generating a web app using BLINQ. What interests me here is that it feels like the kind of RAD tool that Ruby On Rails is popularizing (caveat: I have not had a chance to play with it yet). I have blogged before on the question of where is Microsoft's equivalent to Ruby on Rails and the question seems to get more pressing with time. LINQ will make some developers head spin and, IMO, Microsoft still needs to own the RAD developer market that had so successfully targetted in the past with VB6 (or even Access). Tools built on top of LINQ and the Guidance Application Toolkits look to have real hitting power in this area. Let's hope MS gets some of these prototype ideas into production so .NET developers can leverage its paradigms (and Ruby On Rails is about tools and approach not the RUby language) with the CLR. Oh and I'm aware of Ruby.NET, but like I say teh core of the success of Rails is a paradigm for development and suite of tools not a language. |
|
|