DEV Community

Eπιλογή μεταξύ Repository Pattern και Helper Static Class

Η επιλογή μεταξύ Repository Pattern και Helper Static Class εξαρτάται από το τι προσπαθείς να πετύχεις.

Ας δούμε πότε πρέπει να χρησιμοποιήσεις το καθένα:

1️⃣ Repository Pattern

✅ Χρησιμοποίησέ το όταν:
✔ Θέλεις να διαχειριστείς την πρόσβαση στη βάση δεδομένων με καθαρό και οργανωμένο τρόπο.
✔ Χρειάζεσαι αφαίρεση (abstraction) μεταξύ του business logic και της βάσης δεδομένων.
✔ Θέλεις να εφαρμόσεις το Unit of Work Pattern για καλύτερη διαχείριση των συναλλαγών.
✔ Θέλεις να μπορείς να κάνεις mocking σε unit tests (π.χ. μέσω dependency injection).

📌 Παράδειγμα Repository Pattern στη C#

// 1️⃣ Δημιουργία ενός interface που ορίζει τις βασικές λειτουργίες
public interface IProductRepository
{
    IEnumerable<Product> GetAll();
    Product GetById(int id);
    void Add(Product product);
    void Update(Product product);
    void Delete(int id);
}

// 2️⃣ Υλοποίηση του repository που διαχειρίζεται τη βάση δεδομένων
public class ProductRepository : IProductRepository
{
    private readonly ApplicationDbContext _context;

    public ProductRepository(ApplicationDbContext context)
    {
        _context = context;
    }

    public IEnumerable<Product> GetAll() => _context.Products.ToList();

    public Product GetById(int id) => _context.Products.Find(id);

    public void Add(Product product)
    {
        _context.Products.Add(product);
        _context.SaveChanges();
    }

    public void Update(Product product)
    {
        _context.Products.Update(product);
        _context.SaveChanges();
    }

    public void Delete(int id)
    {
        var product = _context.Products.Find(id);
        if (product != null)
        {
            _context.Products.Remove(product);
            _context.SaveChanges();
        }
    }
}

// 3️⃣ Χρήση του Repository μέσω Dependency Injection
public class ProductService
{
    private readonly IProductRepository _productRepository;

    public ProductService(IProductRepository productRepository)
    {
        _productRepository = productRepository;
    }

    public void ProcessProducts()
    {
        var products = _productRepository.GetAll();
        foreach (var product in products)
        {
            Console.WriteLine($"Product: {product.Name}");
        }
    }
}
Enter fullscreen mode Exit fullscreen mode

🎯 Πλεονεκτήματα του Repository Pattern
✅ Απομόνωση του business logic από τον database access κώδικα.
✅ Ευκολία στη συντήρηση και επαναχρησιμοποίηση του κώδικα.
✅ Υποστηρίζει Unit Testing, αφού μπορούμε να κάνουμε mock τα repositories.


2️⃣ Static Helper Class

Χρησιμοποίησέ το όταν:
✔ Θέλεις να γράψεις βοηθητικές μεθόδους που δεν εξαρτώνται από κατάσταση (state) και δεν χρειάζονται εξωτερικές εξαρτήσεις.
✔ Θέλεις μια απλή και γρήγορη λύση για κοινές λειτουργίες όπως formatting, calculations, string manipulation κ.λπ.
✔ Δεν χρειάζεται να κάνεις mocking για Unit Testing.

📌 Παράδειγμα Static Helper Class στη C#

public static class StringHelper
{
    public static string ToTitleCase(string input)
    {
        if (string.IsNullOrWhiteSpace(input))
            return string.Empty;

        return CultureInfo.CurrentCulture.TextInfo.ToTitleCase(input.ToLower());
    }

    public static bool IsValidEmail(string email)
    {
        return Regex.IsMatch(email, @"^[^@\s]+@[^@\s]+\.[^@\s]+$");
    }
}

// Χρήση της static class
string title = StringHelper.ToTitleCase("hello world"); // "Hello World"
bool isValid = StringHelper.IsValidEmail("test@email.com"); // true
Enter fullscreen mode Exit fullscreen mode

🎯 Πλεονεκτήματα της Static Helper Class
✅ Απλή και γρήγορη χρήση, χωρίς ανάγκη για instantiation.
✅ Ιδανική για utility functions, όπως string manipulations ή μαθηματικές πράξεις.
✅ Δεν απαιτεί Dependency Injection.

📌 Πότε να χρησιμοποιήσεις το καθένα;

Πίνακας σύγκρισης Repository Pattern vs Static Helper Class

Χαρακτηριστικό Repository Pattern Static Helper Class
Χρήση με βάση δεδομένα ✅ Ναι, ενδείκνυται για data access ❌ Όχι, δεν έχει πρόσβαση σε DB
Stateful λειτουργίες ✅ Ναι, χρησιμοποιεί context για data access ❌ Όχι, δεν έχει κατάσταση (stateless)
Ευκολία Mocking/Testability ✅ Μπορεί να γίνει mocking για Unit Tests ❌ Δύσκολο να γίνει mock λόγω static nature
Αποσύνδεση εξαρτήσεων (Decoupling) ✅ Παρέχει abstraction και dependency inversion ❌ Συχνά δημιουργεί tight coupling
Utility Functions (π.χ. string formatting, calculations) ❌ Όχι, είναι overkill για τέτοιες εργασίες ✅ Ιδανική για τέτοιες περιπτώσεις
Χρειάζεται Dependency Injection; ✅ Ναι, το repository περνιέται μέσω DI ❌ Όχι, οι static classes καλούνται άμεσα

🎯 Συμπέρασμα
✔ Χρησιμοποίησε το Repository Pattern όταν έχεις ανάγκη για data access abstraction, dependency injection και unit testing.
✔ Χρησιμοποίησε Static Helper Class όταν έχεις απλές utility functions που δεν εξαρτώνται από δεδομένα και κατάσταση.

📌 Αν ο στόχος σου είναι η επεκτασιμότητα και η καθαρή αρχιτεκτονική, τότε το Repository Pattern είναι η καλύτερη επιλογή. Αν απλά χρειάζεσαι γρήγορες βοηθητικές συναρτήσεις, μια static class είναι πιο αποδοτική. 🚀
Δείτε επίσης: Repository Pattern στη C# με SOLID αρχές

Δείτε επίσης: Repository Pattern στη C# με SOLID αρχές

Top comments (0)