⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 tiofp documentation - what is an object persistence framework.htm

📁 tiOPF 面向对象的数据库持久层持久层开发的框架
💻 HTM
📖 第 1 页 / 共 3 页
字号:
  along with the vendor-specific implementations that will also be 
  developed.<BR><EM><BR>Yes. Currently we have Oracle via DOA, Paradox via BDE, 
  Interbase via IBObjects, and multi tier via HTTP and a custom ISAPI DLL. To 
  write another persistence flavor, clone the code from one of the above, modify 
  and recompile into a new package which gets loaded at 
startup.</EM><BR></LI></OL>
<H2>How the tiOPF compares with Scott Ambler’s requirements</H2>
<P>The following 14 requirements where lifted from his paper on object 
persistence frameworks: ‘The design of a robust persistence layer for relational 
databases’ which can be found in full at <A 
href="http://www.ambysoft.com/persistenceLayer.pdf">http://www.ambysoft.com/persistenceLayer.pdf</A></P>
<OL>
  <LI><STRONG>Several types of persistence mechanism.</STRONG> A persistence 
  mechanism is any technology that can be used to permanently store objects for 
  later update, retrieval and/or deletion. Possible persistence mechanisms 
  include flat files, relational databases, object-relational databases, etc. 
  Scott’s paper concentrates on the relational aspect of persistence 
  layers.<BR><BR><EM>This requirement is partially met. The tiOPF is optimised 
  for object RDBMS mapping, and is currently being extended to support flat file 
  and XML persistence layers. This, however is not a trivial task because in the 
  process of optimising the framework for OO-RDBMS mapping, we have boxed our 
  selves into a design corner which is making it difficult to create a 
  persistence layer that maps to a not SQL database.</EM><BR>
  <LI>Full encapsulation of the persistence mechanism(s). Ideally you should 
  only have to send the messages save, delete and retrieve to an object to save 
  it, delete it or retrieve it respectively. That’s it, the persistence layer 
  takes care of the rest. Furthermore, except for well-justified exceptions, you 
  shouldn’t have to write any special persistence code other than of the 
  persistence layer itself.<BR><BR><EM>This requirement is well met, although 
  you do not send a message like save or retrieve to the object, you pass the 
  object to the persistence manager and ask it to handle the saving.<BR><BR>For 
  example, you do not call: FMyObject.Save ; <BR>but rather gPerMgr.Save( 
  FMyObject ) ;</EM><BR>
  <LI><STRONG>Multi-object actions.</STRONG> Because it is common to retrieve 
  several objects at once, perhaps for a report or as the result of a customised 
  search, a robust persistence layer must be able to support the retrieval of 
  many objects simultaneously. The same can be said of deleting objects from the 
  persistence mechanism that meet specific criteria.<BR><EM><BR>This requirement 
  is well met. You can make a call like gPerMgr.Read( FPeople ) where FPeople is 
  an empty list which will hold 0..n TPerson(s)<BR><BR>You can also make calls 
  like FPeople.Delete which will mark all the TPerson(s) in the list for 
  deletion. When gPerMgr.Save( FPeople ) is called, all the TPerson(s) marked 
  for deletion will be removed from the persistence store.</EM><BR>
  <LI><STRONG>Transactions.</STRONG> Related to requirement #3 is the support 
  for transactions, a collection of actions on several objects. A transaction 
  could be made up of any combination of saving, retrieving, and/or deleting of 
  objects. Transactions may be flat, an ‘all-or-nothing’ approach where all the 
  actions must either succeed or be rolled back (cancelled), or they may be 
  nested, an approach where a transaction is made up of other transactions which 
  are committed and not rolled back if the last transaction fails. Transactions 
  also be short-lived, running in thousandths of a second, or ling-lived, taking 
  hours, days, or weeks, or even months to complete.<BR><BR><EM>This requirement 
  is partially met. Transactions are supported if the persistence mechanism 
  supports them. (ie a RDBMS). A single transaction will be supported per call 
  to the persistence layer. For example, all objects being saved in a call to 
  gPerMgr.Save(FPeople) will be saved in the same transaction. If one fails to 
  save, none will be saved. The abstract business object has a property 
  ObjectState which indicates if an object is clean (it does not need to be 
  saved) or dirty, (it must be created, updated or deleted) A single transaction 
  can exist between the objects and the database. The is no support for inter 
  object transactions, or object-GUI transactions.</EM><BR>
  <LI><STRONG>Extensibility.</STRONG> You should be able to add new classes to 
  your object application and be able to change persistence mechanisms easily 
  (you can count on at least upgrading your persistence mechanism over time, if 
  not port to one from a different vendor). In other words your persistence 
  layer must be flexible enough to allow your application programmers and 
  persistence mechanism administrators to each do what they need to 
  do.<BR><BR><EM>Not really sure what Scott is getting at here. It is possible 
  to add new objects to the application (I can’t see when it would never be 
  possible).<BR><BR>The persistence connection mechanism is wrapped up in a 
  Delphi package which is loaded when the application initialises so changing 
  from one database access API is as easy as loading a different package 
  (BPL)<BR></EM>
  <LI><STRONG>Object identifiers.</STRONG> An object identifier (Ambler, 1998c), 
  or OID for short, is an attribute, typically a number that uniquely identifies 
  an object. OIDs are the object-oriented equivalent of keys from relational 
  theory, columns that uniquely identify a row within a table.<BR><BR>Scott’s 
  high-low long integer based OIDs are implemented. There is no support for non 
  integer OIDs and this should probably be a requirement as it makes it 
  difficult to map to many legacy databases.<BR>
  <LI><STRONG>Cursors.</STRONG> A persistence layer that supports the ability to 
  retrieve many objects with a single command should also support the ability to 
  retrieve more than just objects. The issue is one of efficiency: Do you really 
  want to allow users to retrieve every single person object stored in your 
  persistence mechanism, perhaps millions all at once? Of course not. An 
  interesting concept from the relational world is that of a cursor. A cursor is 
  a logical connection to the persistence mechanism from which you can retrieve 
  objects using a controlled approach, usually several at a time. This is often 
  more efficient than returning hundreds or even thousands of objects all at 
  once because the user may not need all of the objects immediately (perhaps 
  they are scrolling through a list).<BR><BR><EM>There is no support for 
  cursors.</EM><BR>
  <LI><STRONG>Proxies.</STRONG> A complementary approach to cursors is that of a 
  ‘proxy’. A proxy is an object that represents other objects but does not incur 
  the same overhead as the object that it represents. A proxy contains enough 
  information for both the computer and the user to identify it and no more. For 
  example, a proxy for a person object would contain its OID so that the 
  application can identify it and the first name, last name and middle initial 
  so that the user could recognise whom the proxy object represents. Proxies are 
  commonly used when the results of a query are to be displayed in a list, from 
  which the user will select only one or two. When users select the proxy object 
  from the list the real object is retrieved automatically form the persistence 
  mechanism, an object that is much later than the proxy. For example, the full 
  person object may include an address and a picture of the person. By using 
  proxies you don’t need to bring all of this information across the network for 
  every person in the list, only the information that the user actually 
  wants.<BR><BR><EM>The principle discussed here is implemented, but not by 
  using proxies. The abstract business object has a property, ObjectState. One 
  possible ObjectState is posPK, meaning persistent object state ‘Primary Key’ 
  This means the OID and enough information for a human to navigate a list of 
  the objects has been loaded.</EM><BR>
  <LI><STRONG>Records.</STRONG> The vast majority of reporting tools available 
  in the industry today expect to take collections of database records as input, 
  not collections of objects. If your organisation is using such a tool for 
  creating reports within an object-oriented application your persistence layer 
  should support the ability to simply return records as the result of retrieval 
  requests in order to avoid the overhead of converting the database records to 
  objects and then back to records.<BR><BR><EM>There is no support for records, 
  although there is a record like family of classes. The easy alternative to 
  this would be to hook into a TClientDataSet, however this was not done to 
  avoid building a dependency on the Enterprise version of Delphi.</EM><BR>
  <LI><STRONG>Multiple architectures.</STRONG> As organisations move from 
  centralised mainframe architectures to 2-tier client/server architectures to 
  n-tier architectures to distributed objects your persistence layer should be 
  able to support these various approaches. The point to be made is that you 
  must assume that at some point your persistence layer will need to exist in a 
  range of potentially complex environments.<BR><BR><EM>This requirement has 
  been moderately well met. There is a remote persistence layer that will pass 
  all calls through the tiDBProxyServer and on to a database. The 
  tiDBProxyServer is a standalone Windows Service (build using TIndyHTTPServer). 
  The service may be recompiled as an ISAPI DLL to run under IIS.</EM><BR>
  <LI><STRONG>Various database versions and/or vendors</STRONG>. Upgrades 
  happen, as do ports to other persistence mechanisms. A persistence layer 
  should support the ability to easily change persistence mechanisms without 
  affecting the applications that access them, therefore a wide variety of 
  database versions and vendors, should be supported by the persistence 
  layer.<BR><BR><EM>This requirement is well met. To connect to a different 
  database or using a different connection API, just load an alternative Delphi 
  package at runtime.<BR></EM>
  <LI><STRONG>Multiple connections</STRONG>. Most organisations have more than 
  one persistence mechanism, often from different vendors, that need to be 
  accessed by a single object application. The implication is that a persistence 
  layer should be able to support multiple, simultaneous connections to each 
  applications persistence mechanism. Even something as simple as copying an 
  object from one persistence mechanism to another, perhaps from a centralised 
  relational database to a local relational database, requires at least two 
  simultaneous connections, one to each database.<BR><BR><EM>Multiple 
  connections to a single database (via database connection pooling), or 
  multiple connections to multiple databases of the same access are possible. 
  Work has been commenced to allow multiple connections to different database 
  types and it will not be too difficult to meet this requirement.</EM><BR>
  <LI><STRONG>Native and non-native drivers.</STRONG> There are several 
  different strategies for accessing a relational database, and a good 
  persistence layer will support the most common ones. Connection strategies 
  include using Open Database Connectivity (ODBC), Active Data Objects (ADO), 
  and native drivers supplied by the database vendor and/or third party 
  vendor.<BR><BR><EM>This requirement is well met by swapping runtime 
  packages.</EM><BR>
  <LI><STRONG>Structured query language (SQL) queries</STRONG>. Writing SQSL 
  queries in your object-oriented code is a fragrant violation of encapsulation 
  – you’ve coupled your application directly to the database schema. However, 
  for performance reasons you sometimes need to do so. Hard-coded SQSL in your 
  application should be the exceptions, not the norm, an exception that should 
  be well-justified before being allowed to occur. The persistence layer will 
  need to support the ability do directly submit SQL code to a relational 
  database.<BR><BR><EM>Several ways of submitting SQL to the database are 
  possible.<BR><BR>The default is for the SQL to be maintained with a tool 
  called the tiSQLManager that stores the SQL in the database. This has many 
  advantages but it does mean the three tiSQLManager tables must exist in the 
  database.<BR><BR>SQL can be generated on the fly (this requires work before it 
  could be regarded as production quality)<BR><BR>SQL can be hard-coded into the 
  application.</EM> </LI></OL>
<P>The next section</P>
<P>The next section describes the Visitor framework and can be read <A 
href="http://www.techinsite.com.au/tiOPF/Doc/2_TheVisitorFramework.htm">here</A>. 
</P><!-- InstanceEndEditable -->
<DIV id=Footer>(c) TechInsite Pty Ltd, Melbourne, Australia. 
www.techinsite.com.au</DIV></DIV><!-- InstanceEnd --></BODY></HTML>

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -