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.
Related
Background
I need to build a Rich-Client application using .NET. The app needs to handle TreeViewControls and TableViewControls with about 100000 entities. GUI is build with WPF, very likely using Telerik Controls. My question is about the general architecture of the data-layer. I've got some coarse ideas of the concepts, but would highly appreciate your comments / thoughts and hints into which technology I should dig deeper. Here're my thoughts:
Conceptual Layers
Presentation Layer
just the WPF Controls, I'd need performant synchronizing of different controls on property changes, but I don't anticipate major problems here.
Business Layer
creating views (object selections to be displayed in the controls), CRUD operations (modifications done directly with the POCOs), searching (global search, but also limited to a view)
Repository
holds POCOs in an enitity map, decides weather to load from persistence store
Persistence-Manager
I'm thinking of using a LocalDB or simple Key-Value Store as (persistent) Client-Cache. So, the Persistence-Manager would try to get an object from the local store. Otherwise get the data from the server. Also, persisting data to the Client-Cache. The data would be available via a webservice. I'm happy to give WCF Data Services a try.
Persistence-Layers
There would be two parts:
- Local DB connection using an ORM like EF or OpenAccess; or a simple key-value store
- HTTP connection to consume the Web-Service
Questions
In a layering like this, how about lazy loading referenced objects? I know EF and other ORMs take care of a lot of the issues I have here, too. But I don't see yet how to plug these frameworks into the above layering. Also, where to track changes? Where to secure consistency when deleting objects? (e.g. deleting references to these objects as well)
I would eager load whole views (hierarchical structures) and perform Linq to objects to those collections of POCOs. Maybe implement a simple inverted index if Linq performance would become a matter. But how should I best implement global searches on the server? Are there libraries ("Linq to OData") available?
What do you think about a fully "diconnected" scenario? Holding all data a user needs in a local database. Sync on start / stop and user triggered. I could use an ORM directly on the local DB, with good chances to save a lot of headaches trying to implement a lot of consistency features by hand (using the above layering).
Or in contrast, forget about the local database and batch eager load most of the needed data. Here I'm concerned about the performance of the webservices (without having experience with OData, WCF). I've build an app using Redis and Python that loads about 200000 business objects quite fast (< 1 min) to the client (the objects are already serialized cached in Redis).
I'll certainly do some prototyping and benchmarking, but to get a good start, any thoughts and recommendations are highly appreciate.
Cheers,
Jan
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 created for a project a single class, that contains all access code to the database.
Is this a good practice , under the assumption that this class doesn't contain any logic, or should i use several classes? If yes, how should i partition my code? I use C# .Net.
Actually Under the concept of MVC framework, it is a good practice to create a different class for database access, seperate class for logic and seperate class for your views.
You are doing good if you are writing a seperate class for database access under the assumption that it does not contain any logic.
In Agile Developement there is a term named as Database Encapsulation Layers.
A database encapsulation layer hides the implementation details of your database, including their physical schemas, from your business code. In effect this layer provides your business objects with persistence services – the ability to read data from, write data to, and delete data from – data sources. Ideally your business objects should know nothing about how they are persisted, it just happens. Database encapsulation layers aren’t magic and they aren’t academic theories; database encapsulation layers are commonly used practice by both large and small applications as well as in both simple and complex applications. Database encapsulation layers are an important technique that every agile software developer should be aware of and be prepared to use.
An effective database encapsulation layer will provide several benefits:
-> It reduces the coupling between your object schema and your data schema, increasing your ability to evolve either one.
-> It implements all database-related code in one place.
-> It simplifies the job of application programmers.
-> It allows application programmers to focus on the business problem and Agile DBA(s) can focus on the database.
-> It gives you a common place to implement data-oriented business rules and logic.
-> It takes advantage of specific database features, increasing application performance.
Hope this helps.
If your database is quite small, say, only a couple of tables, you could write all your queries in one class. otherwise I would suggest that per Entity/Table one class. for example, StudentDao.class will only focus on the queries to database table "STUDENT", and TeacherDao.class will only contain queries to table "TEACHER". if you are gonna implement a complex business logic, you may want to have a service class, to weave StudentDao and TeacherDao together.
Unless your data access is very simple, probably not.
you probably shouldn't need to write this code yourself. Take a look at some Object Relational Mapping tools. NHibernate is a popular .Net solution. http://en.wikipedia.org/wiki/NHibernate
If you really do want to write it yourself look up design patterns in this area, like the Data Transfer Object pattern. http://martinfowler.com/eaaCatalog/dataTransferObject.html
These are some of the suggestions while accessing database.
1.) Always keep your database access parameters in a properties file. Use a handler to get those data. Because when you change your database then you need not change your code just make a change in the properties file it's enough.
-- So here you need a handler class.
2.) Never create a single class (a god class) which performs all the actions. Disperse your behaviour in to different classes depending on the intent. For example Keep all read behavior in one class, Write behavior in another class ... so on.
3.) You can create a class which deals with connection creations and pooling stuff...
Hope this helps.
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
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.