阅读《Better, Faster, Lighter Programming in .NET and Java》http://www.onjava.com/pub/a/onjava/2004/07/14/BFLJava.html

感悟:
透明 除了domain(罗辑层)外,其他的都相对于domain是透明的,都是Servicees 包括persistent(数据层) presentation layer (表示层) 也就是说domain中不能够访问Services的方法,或者说domain不可以向Servic发消息——因为它不知道他们的存在

摘要:
In order to keep the business model light, simple, and easy to maintain, you want to keep it as uncluttered with ancillary code as possible. The services provided to the domain model should be transparent, meaning that you shouldn’t have to add anything to your domain objects to get the benefit of those services. At the very least, you shouldn’t have to add anything to them that you can’t safely ignore when you need to, such as at unit-test time.

This domain class doesn’t know anything about how it will be displayed to the user or how it will be persisted to the database. It is entirely focused on representing the code business abstraction invoice, and the rules that apply to its data. Nothing else clutters the code.

感悟:
数据层包含了对数据库所有操作,其他层如domain层必须通过数据层才可以来访问数据库。一切越过数据层直接操作数据库的操作都是不合法的。这样做所有的对当前特定的数据库操作都被封装到了这个数据层里了,对于其他层来说使用什么样的数据库已经变得透明起来。这样以后无论是对数据库的改动还是迁移到另外的数据库支持上,都是可以只在数据层来实现,无需对其他层的代码进行改动了。还有一点建立数据层不是只建立一个类表示数据层(当然这样可强制程序员必须按照层间协议做),我想多个类在一个命名空间里也可以,但这样如何约束程序员不能跨层操作呢?

object/relational (O/R)

 

摘要:
The persistence layer is the same way. By separating out your persistence logic into another class (PersistenceManager) you abstract away the common, non-business- specific functionality of interacting with a database to a transparent part of the code. To implement PersistenceManager, you have a variety of choices. You can implement the transactional script pattern, which is essentially what we did in the first page above. That is to say, you use the native data interaction objects provided by .NET (DataSet, SqlDataAdapter, etc.) to manually pull values out of the Invoice instance and modify the database, manually controlling any transactional semantics yourself.

On the other hand, you could use an object/relational (O/R) mapping framework to handle the work for you. O/R mappers are frameworks that, given a mapping file that relates class definitions with database schema, can auto-generate the SQL scripts needed to perform persistence activities. These kinds of frameworks simplify your code greatly by eliminating all of the hard-coded SQL scripts used by the transactional script pattern, and free you to work in terms of your domain model only. Currently, the major O/R mapping framework available to .NET developers is NHibernate, a .NET port of the popular Java Hibernate framework. NHibernate is an open source project found at nhibernate.sourceforge.net. Microsoft has its own O/R mapping technology called ObjectSpaces that is going to be released with Longhorn and/or Whidbey, but unless you are a beta tester for Microsoft, you can only get NHibernate at present.

摘要:
In the Java world, there are a hundred ways to do anything. If you want an MVC framework, there’s Struts, WebWork, SpringMVC, and one implementation for every J2EE vendor. For O/R mapping, there’s Hibernate, JDO, Kodo, EJBs, etc. Heck, there are even five or six viable IDEs. On the Microsoft side of the world, we have tended to be less diverse. We use Visual Studio for development, ADO.NET for data access, and ASP.NET for our web front end. There aren’t nineteen different web form strategies (Tapestry, Velocity, JavaServer Faces, etc.). However, that focus on a single vendor is starting to change.

If you take a look at SourceForge, you will notice that there are almost as many .NET projects as Java projects now. All of the major tools on the Java side are being ported to .NET. This list includes:

Struts.NET for web MVC
NHibernate for O/R mapping
NUnit for unit testing
Pico.NET and Spring.NET for lightweight alternatives to EnterpriseServices/COM+
NAnt for build management
CruiseControl.NET and Draco.NET for integration builds
C# support in Eclipse and IDEA

摘要:
In general, this means writing code that allows for the unknown. This sounds like an impossible proposition, but in reality, the key factor is understanding where future users are likely to want to change the way your application works, and making those areas as loosely coupled to the rest of the application as possible.

IDocument document = Document.CreateInstance(“some_document_type”,
    “some_assembly”);
The beauty of factory methods is that they can return any concrete type that implements IDocument, not just the original Document class, and they can look up the actual implementation at runtime using reflection. The implementation of CreateInstance might look like:

public static IDocument CreateInstance(string type, string asm)
{
    Assembly assembly = Assembly.Load(asm);
    return (Idocument)assembly.CreateInstance(type);
}

As long as the calling code has passed in an accessible assembly, and the type they asked for implements the IDocument interface, then it doesn’t matter what the concrete type is, or even if it existed when the application was first written.

A special note about reflection: it gets a bum rap. Reflection is slower than direct coupling, but usually measured at about two or three times slower. That means you shouldn’t do everything via reflection, but its judicious use for something like loading a dynamically assigned class at runtime (but binding it statically to a known interface) is perfectly reasonable, especially if you are talking about a modern distributed application, where the two more important criteria for boosting performance are limiting round trips on the network and minimizing hits to the database. If you can solve those problems, then maybe you can think about how a little reflection affects performance. I find that extensibility is usually a more important factor for me.


1条评论

  1. asdfasdfasdfsd

发表评论

评论也有版权!

click to change验证码