I will start to develop an application that has to access to database. What kind of design patterns area usually need to be implemented to make my application more flexible for example changing DB client from SQL to Oracle.
I believe to perform execution of some query I can implement Template Method Pattern. And to get connection a singleton pattern with double check would be sufficient.
Is there anything else I should know before starting?
Application will be developed in C#, so there is support for object inheritance and polymorphism.
Any help is appreciated.
Make sure all your code is encapsulated in a data access layer. Code against interfaces so that if you need to write a new data access library, you don't have to change all calling code. This will at least isolate all data access into on library. How likely is the changing of database to be? Don't make the software complex for the what-ifs as this will just make life more difficult.
Abstract something 'on-fly' and only when You can clearly see a benefit.
Otherwise - that's just waste of time.
Do not think like:
I should use pattern [x] because it might fix [y]
Think like this:
Oh crap, again got to write same stuff. Let's see how we could avoid that...
There's a good design pattern called Data Access Object, you will have to incorporate it into C#.
Summary:
The DAO implements the access
mechanism required to work with the
data source. The data source could be
a persistent store like an RDBMS, an
external service like a B2B exchange,
a repository like an LDAP database, or
a business service accessed via CORBA
Internet Inter-ORB Protocol (IIOP) or
low-level sockets. The business
component that relies on the DAO uses
the simpler interface exposed by the
DAO for its clients. The DAO
completely hides the data source
implementation details from its
clients. Because the interface exposed
by the DAO to clients does not change
when the underlying data source
implementation changes, this pattern
allows the DAO to adapt to different
storage schemes without affecting its
clients or business components.
Essentially, the DAO acts as an
adapter between the component and the
data source.
Check the Catalog of Patterns of Enterprise Application Architecture by Martin Fowler.
You may find a few good ideas there.
you should investigate the user of the data mapper pattern to keep the implementation details of how your data is stored (SQL/Oracele/Access) independent from the use of the data itself.
http://martinfowler.com/eaaCatalog/dataMapper.html
Related
I developing an application.
I read somewhere that database should not be accessed directly but there should be kind of layer and via it database should be accessed.
I don't know the exact reason.
It will be great if you can provide me some reasoning or links to follow.
Yes it is really a good practice to abstract/encapsulate your DB access logic from other part o. Data access layer should not be accessed directly or exposed to everyone. Meaning when you are designing an application, you must consider this important factor “Layered architecture” for example business layer, service layer, presentation layer and whatsoever. The work flow like service layer (if its web application) calls business layer and business layer calls data access layer. All this layers should be very abstracted to each other or it should be accessible only to the very immediate layer (so called clients).
Answer to your question: Let’s say your current data access implementation is based on plain JDBC/ODBC .After some time when your requirements grow; you are planning to implement it with some ORM framework. In this case it’s really easy to switch/migrate between different data access logic written in different APIs without affecting rest of your application and still other layers are not aware of your changes since your design is very abstracted in nature.
Bottom Line: Always work against abstracted interface rather against implementation.
Hope this is helpful and comments are appreciated
I am learning some patterns, Unity of work / repository... There are some examples on web, but no one connects to more than one database.
In my applications almost always I have the need to get some object from a database (for example users) and some other object from another, how can I use the patterns ? (Since I am a novice on this subject an explicit example is a must)
Thank you!
As a general reference I advise you and anyone interested to visit http://martinfowler.com/eaaCatalog/index.html
which has a collection of UML and explanation over the most common Design Pattern for enterprises software
In your specific case Unity of work is particularly suited to work along with Data Mapper and Identity Map. I guess to understand 100% unity of work one must master also the other 2 pattern.
To answer your question I think you can create a unity of work and save it in a registry, so it is available all over the application. The unity must be a singleton since you need to ensure a central gateway to communicate with the database. Inside your unity of work you will have an identity map which is a collection of valued Objects in memory representing your model which is responsible to maintain the object states during all the application's operations. The unity will be used by your service layer to perform CRUD operations over the model and commit these changes.
To work with more databases I guess you need to leverage some sort of namespaced access to the object stored in the Identity map. You have the choice where to namespace: unity of work or identity map. The decision is really up to your application and use cases. You might need to connect to different DBs for splitting responsibilities between read and write or trying to integrate heterogeneous data sources.
An alternative would be to inject the DB object into the unity of work methods, in this case the application has 100% control over which database is used.
The repository pattern as far as I understand helps you to abstract to the storage of you model and it is particularly useful when you are working with heterogeneous data sources of you must provide such a flexibility to your application. Therefore I guess it is quite different from unity of work and Data Mapper layer.
If my question isn't clear, please help me improve it with comments.
I'm new to Delphi and dbExpress and I'm just getting acquaintance with TSQLDataset, TDataSetProvider, TClientDataSet and TDataSource classes.
The project that I'm working on uses this components in a way that feels strange to me. There is a huge data module unit that contains lots and lots of the quartet of classes previously described. I'm guessing that there are better (and more modularized) ways of doing this. DataSnap is used only to place this data module in a server application, so the clients access the data through it.
So, let me try to explain some of my doubts:
What is the role of each one of this classes? I read the documentation but I can't get a practical insight on this subject (specially about TDataSetProvider).
Which classes should be in the data module and which should be in my forms?
Is it possible to create an intermediate layer to abstract my business model from my database setup (maybe creating functions that return immutable datasets?)?
If so, is it wise to use DataSnap to do so?
I'm sorry if I'm not clear enough. Thanks in advance.
Components
TDataSource is the bridge between data-aware controls and the dataset (TDataSet descendant) from which they are to get their values.
TClientDataSet is one such dataset. TClientDataSet can be used in isolation, for example to access data contained in xml files, but can also be hooked up to a TDataSetProvider.
TDataSetProvider is the bridge between the in-memory TClientDataSet and the actual dataset that takes its data from a database through some kind of driver. In Client Server development you will usually see a TRemoteDataSetProvider (name may be different, I don't work with these components that often), which bridges the gap between the client and server.
TSQLDataSet is the actual dataset getting its data from some database.
It would feel strange to me to see this quartet all in one executable. I would expect the TSQLDataSet on the server side hooked up to the TRemoteDataSetProvider's counter part. However, I guess that with an embedded database it could be a way to support the briefcase model, which is where TClientDataSet is really helpful (TClientDataset is very powerful, that is just one of its strong points.)
Single datamodule
Ouch. A single huge datamodule is lazy programming or the result of misconceptions about how to use datamodules. It is perfectly normal to have a single datamodule that "hosts" the database connection which is then used by various other datamodules that are more tightly focused on aspects of the application.
Domain abstraction
With regard to abstracting your business model, dbexpress and datasnap should really not be anywhere in your business model. They should be part of your data layer.
TDataSource, TClientDataSet and custom TDataSetProvider descendant(s) can be used to leverage the power of the data-aware controls in the UI while still keeping the UI separate from the business model. In this case the custom TDataSetProvider would be the bridge between the client dataset and the collections and instances in the domain layer.
Even so, I would still expect to see a separate data layer, using TRemoteDataSetProviders or straight TDataSet descendants (like TSQLDataSet) to provide the domain layer with its data.
The single huge data module you mentioned could be part of that data layer, with the client datasets providing the business layer with its data. As you also mention TDataSource as part of a common quartet, the application was probably developed in a RAD-data-aware fashion where UI controls are basically hooked up straight to database columns/tables.
If you want to transform this application to have a more layered architecture, tread carefully and slowly. Get to know the current architecture first and get to know it well enough to see the impact that this kind of transformation would have. The links provided by Serg will certainly help you there. Pawel Glowacki has written extensively about DataSnap.
The project you are working on is a Delphi Multitier Database Application
Your question is too wide for SO and hardly can be answered in its current form - you should learn to understand the underlying architecture.
You can start from video tutorial by Pawel Glowacki:
http://www.youtube.com/watch?v=B4uxLLIUddg
http://cc.embarcadero.com/item/28188
I have several objects, like products, order, etc. When I get information from my database I take a row and create one of the types of objects. I then work with that object created. I read this is called a factory.
Is there some advantage to doing this? Especially in a loosely typed language like PHP?
Thanks
edit: is this where I get database agnosticity? Is this what an ORM essentially does?
By creating your objects from the database queries, you are defining the mapping between your objects and the relational database. This is exactly what ORM software does.
By doing so and ensuring that your objects never directly access the database, but instead use your database-access functions/objects, you are protecting your code from changes in two ways:
Changes to your database schema will not ripple through your code. Instead, the code changes will be located only in your database access objects.
You can switch to a different DBMS by implementing a new database layer that follows the same interface as the original. Your other objects will not require changes.
I guess in that sense, you gain some database-agnosticity, but you'll probably be better off using a database library that provides that agnosticity out of the box.
In my opinion, the advantage is you are working with objects and gain all of the advantages that an object-oriented language offers. You can then read the domain logic at a higher level (in terms of the objects you have defined) without sifting through database queries. Writing the ORM yourself can be tough, but there are tools out there that help with that.
This is the route I normally take, but I don't do any PHP development, so I can't say how well it applies to that language.
What you're describing is an implementation of a Data Access Layer - it doesn't sound like an example of the Factory Method pattern, nor the Abstract Factory pattern.
Yes, ORMs bridge the gap from objects to relational databases, and can serve as your Data Access Layer. Bear in mind, any ORM you use has certain pros/cons/limitations. Depending on your experience and requirements, writing your own data access layer is sometimes a good idea; don't feel like you HAVE to use a 3rd-party ORM.
Yes, a good data access layer makes it easy to swap out your storage mechanism (different database, XML, flat files, whatever) without changing your business logic, UI, or other code.
Regardless of loose-typed or strong-typed languages, if you're working in an OO language, it will be much easier to write code using data objects (provided by an ORM or homegrown data access layer). I'm sure it's possible to write a system with no data access layer, where your business layer works directly with the database. But it will likely be more challenging to implement and maintain.
We are trying to come up with an architecture approach for designing an application where front end runs as a browser based xaml app.
this app contacts services on the web server that are built using wcf, the wcf services host domain model that uses nhibernate for persistence (so it is hibernate aware by using interfaces for lists and sets and such)
i understand that when using soap web services, only schema are shared and not types, but we would like to share types since types would have methods, business logic etc ..
and since both ends of communication are in our control, we don't really need to use soap, but for all clarity and debugging, security and general peace of mind, SOAP is desired.
wondering what if this is an approach people use, and if there are any frameworks out there that enable/guide/ease the task of converting proxies back to their original types..
or if there are any other approaches possible.
Marc is correct that you cannot share types in an SOA architecture. In fact, in SOA, it is undesirable.
But you've decided you don't need SOA, so you can share types if you like. Just click the "Advanced" button when you use "Add Service Reference", and choose the set of types you want shared between the client and service.
Of course, this does bind your client and service tightly together, and loses other benefits of SOA, but it's no worse than if you were using COM.
You CANNOT share types (e.g. classes) in a true SOA world - because in the end, what it really comes down to is everything is serialized into a XML stream and sent across the wire. Also - one end could be .NET and the other end PHP or Java - now I don't think your Java client will understand and be able to execute .NET methods on your object.
SOA is a different beast than "object remoting" - it just doesn't lend itself to actually remoting objects across the wire - it sends XML messages across - that's all it can do. It can send data back and forth, but not code.
If in your scenario you do control both ends of the conversation, of course what is available to you is the ability to package all your business objects into a shared assembly (or several), and then physically share those assemblies between your server and client. In this case, you could serialize an object "Customer" on the server, send the XML message across, and on the client side, deserialize it into a "Customer" again. But be aware : all you're sending across is the state of Customer - the values in its fields and properties. You're not really sending the code across - that just happens to be available on both ends of the wire.
What a lot of folks do in this case is extracting the information of interest from the actual "Customer" object into a "Data-Transfer Object" often called "CustomerDTO", by using e.g. something like AutoMapper in order to make it easier, and then they create a new Customer instance on the other end of the wire and copy the data back from the DTO into the "real" object.
Marc
There is an easy way to share types between client and service, just by adding reference to shared type assembly to your client BEFORE adding the service reference.
You can find the detailed scenario and sample project there:
http://blog.walteralmeida.com/2010/08/wcf-tips-and-tricks-share-types-between-server-and-client.html