Nir
Nir

Reputation: 4013

Design Question: Behavior in different contexts

I have a general question: What should be done when an object's behavior should change according to context? (Please note that this is regarding SQL and not C#, but I could really use ideas here)

For example, the Search class, let's call it "SearchObject". This SearchObject gets a search term and returns 5 results from Google. It does this and this only.
Now I have a new requirement: if the object is called from a certain context, it appends results from another search engine. For example, if I call a search from a web page, this object should bring 10 results: first 5 from Google, last 5 from Bing. If it's called from a console application, it should bring the last 5 results from AltaVista.

How do I keep this object's behavior according to the OOP principles AND get the desired result? (The implementation will be in SQL, so I can't use the design patterns I know in C#...)

Thanks!

Upvotes: 0

Views: 96

Answers (3)

mikemanne
mikemanne

Reputation: 3575

Whenever you have multiple algorithms/techniques/approaches to accomplish a goal, and want to make a runtime decision of which technique to use, you should consider using the Strategy pattern.

Strategy is frequently paired with FactoryMethod pattern. Basically, call the FactoryMethod, passing whatever data is necessary for it to make a decision. It encapsulates the actual decision-making logic, and returns an instance of the appropriate strategy object.

Upvotes: 0

Conrad Frix
Conrad Frix

Reputation: 52675

Obviously its much more common to do this in elsewhere, but if you're keeping the behavioral logic in SQL you could do one of the following

Use a parameter

just pass something to the procedure. For Example

Create Proc sp_Search (@Search varchar(500), @behavior int)
AS

if @behavior = 1
 ...
if @behavior = 2
...

However this requires your applications to have knowledge of this parameter, and this may not be what you're looking to do.

Use something about the session

You could also use information about the session. For example APP_NAME()

Create Proc sp_Search (@Search varchar(500))
AS

if APP_NAME()=  'Application A'
 ...
if APP_NAME()= 'Application B'
...

Use a specific user

Another option is to dole out the user names to the context they're going to use and then use CURRENT_USER

Create Proc sp_Search (@Search varchar(500)) AS

if CURRENT_USER()=  'ConsoleCreds'
 ...
if  CURRENT_USER()= 'WebCreds'
...

Honestly I would rather allow any behavior by any application (The Mechanism) and then configure the policy for each application, rather than tying the Mechanism and Policy together (as above)

Upvotes: 1

dfb
dfb

Reputation: 13289

If I were writing this in C#, I would do something along the lines of having a context object that is provided to the SearchObject and produces the necessary parameters.

To implement a similar idea in SQL, you would have a Context table with ContextName,SearchEngine,TopX, etc. and join that to a Searches table (assuming you're doing some sort of caching here) to get your results.

Something like..

SELECT * FROM Searches s  
  INNER JOIN Context ct ON sr.search = ct.search
  WHERE sr.rank <= ct.TopX
  AND   (searchterm = ... etc )
UNION
SELECT * FROM (SELECT s.*, rank() OVER (partition by search_term,search order by rank asc), FROM Searches s ORDER BY rank ASC)
  INNER JOIN Context ct ON sr.search = ct.search
  WHERE sr.rank <= ct.BottomX
  AND   (searchterm = ... etc )

Upvotes: 0

Related Questions