Connector
The connector pattern is one of my own design, specifically to address the issue raised in my seventh law of software design, If it can't be measured, it doesn't exist.
"If it can’t be expressed in figures, it is not science; it is opinion." - Robert Heinlein
My contention is that a design should be abstracted and constructed using sound principles of encapsulation, loose coupling and other principles of a sound architecture. Once the architecture is in place, performance tuning can begin and areas identified where changes need to be made. In these cases a connector can be created to "punch a hole" through the layers of abstraction and encapsulation specifically for the purpose of performance enhancement. Too often design is the reverse of this method, with almost no architectural design but every component tightly couple for "performance". Usually this performance is ephemeral at best.
Designing first for a sound architecture and then creating connectors as necessary results in better design and the capability of improving performance as necessary.
Note in the first pseudo code fragment that a <meta_data> table is created in the <utility> database. Rather than replicate that to each application database a facade is created in each application database in the form of a function which simply passes the call through to the working function in <utility>. The facade function can then be used to create a pseudo foreign key restraint as shown. The constraint can be set to no check prior to bulk load. This is a very useful pattern for cross database referential integrity, but it does have potential performance issues. My design preference is to create this pattern first, and only if performance issues are a problem create a connector.</utility></utility></meta_data>
---------------------------------------------------------------------------------------
-- cross database referential integrity pattern
use <utility>;
go
declare <schema>.<meta_data> (<key> <type>, <value> <type>);
insert into <schema>.<meta_data> (<key>, <value>) values (<key>, <value>)...
declare function <schema>.<get_meta_data> (@key) returns <type> as
return (select <value> from <schema>.<meta_data> where <key> = @key);
use <application>;
go
declare function <schema>.<get_meta_data> (@key) returns <type> as
return (select <schema>.<meta_data> (@key));
alter table <schema>.<application_table> add constraint [fk_meta_data]
check (select <schema>.<get_meta_data>(<meta_data>) is not null);
---------------------------------------------------------------------------------------
-- cross database referential integrity pattern
-- connector
-- replication alternative - identical to the first but the table is replicated to the
-- application database. This leaves the original pattern in place for all other
-- objects. Objects in this database will get the new table due to the
-- function definition.
use <application>;
go
declare <schema>.<meta_data> (<key> <type>, <value> <type>);
<replicate <utility>.<schema>.<meta_data> to <application>.<schema>.<meta_data>>
declare function <schema>.<get_meta_data> (@key) returns <type> as
return (select <value> from <schema>.<meta_data> where <key> = @key);
alter table <schema>.<application_table> add constraint [fk_meta_data]
check (select <schema>.<get_meta_data>(<meta_data>) is not null);
---------------------------------------------------------------------------------------
-- cross database referential integrity pattern
-- singleton connector
use <application>;
go
declare @function <schema>.<get_meta_data> (@key) returns <type> as
begin
<TODO> - finish this when I have access to a sql server!
end
copyright Katherine Elizabeth Lightsey 1959-2013 (aka; my life)
"You may say I'm a dreamer, but I'm not the only one. I hope someday you'll join us. And the world will live as one." - John Lennon
Wiki: design_pattern
Wiki: facade_pattern
Wiki: katherines_laws_of_software_design
Wiki: software_architecture