2009-03-12 5 views
0

Es ist wahr, was sie über Designmuster sagen, dass sie einfach die Verkörperung von Techniken sind, die bereits allgemein verwendet werden. Ich verwende das Active Record Pattern seit 1985.Best Practices für Active Record Pattern und die Verwendung von statischen Methoden für Gruppenoperationen

Eines der Attribute dieses Musters ist die Verwendung von statischen Mitgliedern in der Implementierung, um Suchen durchzuführen, die Sammlungen der zugrunde liegenden Daten zurückgeben.

class Customer { 
    static Customer FindCustomerById(int Id) { ... } 
    static Customer[] FindActiveCustomers() { ... } 
} 

In vielen Fällen, in denen ich viel mehr Flexibilität muss ich brechen Kapselung und umfassen ein Verfahren, wie

static Customer[] FindCustomers(string criteria) { ... } 

wo man es als

Customer[] customers = Customer.FindCustomers("LastName = 'Smith'"); 

Natürlich nennen würde dies eine ist von diesem Zeitpunkt an, als ich dieses Muster in C verwendet habe, ist eindeutig keine Best Practice, und in den falschen Händen kann SQL-Injektion und andere Probleme führen.

Gibt es ein geeignetes Muster oder eine Praxis, die angewendet werden könnte, damit die Kundenklasse ein "Kriterium" für eine solche Suche werden könnte?

Zum Beispiel nehme ich mag Kunden, dessen Nachnamen zu finden war Smith, halte ich könnte eine Implementierung wie das Schreiben:

static Customer[] FindCustomers(Customer customer) { ... } 

genannt zu werden als (mit dem entsprechenden Konstruktor natürlich):

Customer[] customersnamedsmith = 
    Customer.FindCustomer(new Customer("Smith")); 

Oder ist es besser, eine Co-Klasse zu erstellen, die die Kriterien definieren würde?

+0

Ich glaube nicht, dass es die Einkapselung bricht, solange die möglichen Kriterien auf die exponierten Attribute beschränkt sind. – Pesto

+0

Ich gab an, dass die Kapselung bei Verwendung generischer SQL WHERE-Syntaxkriterienzeichenfolgen unterbrochen wurde. In diesem Fall basieren die Kriterien nicht auf den Mitgliedsfeldern der Klasse. Indem der Benutzer der Klasse aufgefordert wird, SQL zu verwenden, um die Kriterien anzugeben, überlasse ich die Implementierungsdetails. – Bill

Antwort

1

Gerade von der Arbeit mit LINQ, mag ich die Idee, einen Ausdruck anstelle einer Zeichenfolge zu übergeben. Aber vielleicht ist das nur ich? Ich mag ActiveRecord auch nicht, da es den Zustand und das Verhalten desselben Objekts mischt. Nette Verpackung, aber keine saubere Trennung von Modell- und Datenzugriff.

Ich habe Fälle gesehen, in denen eine Kundenklasse an den aktiven Datensatz übergeben wurde, aber wenn Sie diese Route gehen, ist ein Repository-Muster viel sauberer und trennt das Verhalten vom Status. Ich sehe jedoch nichts falsch daran, die Investition zu verwenden, die Sie bereits im aktiven Datensatz haben und ein Objekt weitergeben.

Wenn Sie eine Kriterienklasse erstellen möchten, erhalten Sie ein bisschen ein Strategie-Muster, das Ihre aktive Aufzeichnung ein wenig aktiver machen kann als heute. Es ist jedoch ein anwendbares Muster und löst auch alle Probleme mit der Injektion.

0

Obwohl es Sie aus der Datenbankebene schiebt, könnten Sie etwas Ähnliches wie ein Komparator verwenden. Ich weiß nicht, C#, so dass ich es nur gepfuscht, aber Sie den Kern erhalten:

class CustomerLastNameEvaluator : IEvaluate 
{ 
    private Customer _customer; 

    public CustomerLastNameEvaluator (String lastName) 
    { 
     _customer = new Customer (lastName); 
    } 

    bool IEvaluate.Evaluate(Customer c) 
    { 
     return (_customer.LastName == c.LastName); 
    } 
} 

Customer[] customers = Customer.FindCustomers(new CustomerLastNameEvaluator("Smith")); 
0

ohne Angabe von Gründen nicht zu, ich habe eine Methode wie folgt zur Verfügung stellen würde:

public static IEnumerable<Customer> AllCustomers() 
{ 
    return Customers.AsEnumerable(); 
} 

Wenn Sie Haben Sie Gründe, dies nicht zu tun, müssen Sie diese Gründe artikulieren und sie im Detail untersuchen, um die richtige Lösung zu finden.

0

Werfen Sie einen Blick auf das WWPlatform DataAccess-Beispiel auf Codeplex.Es zeigt ein hervorragendes Beispiel für die Bereitstellung von Suchspezifikationsinstanzen als Parameter, wenn auch durch das Repository-Muster.

Verwandte Themen