Meer informatie over het structureren van code

Opdracht 1 Identificeren van verantwoordelijkheden

Je werkt aan een applicatie waarbij een klasse zowel verantwoordelijk is voor het ophalen van gegevens, het berekenen van een resultaat, en het tonen van een bericht. Dit is niet ideaal omdat de klasse meerdere verantwoordelijkheden heeft, wat volgens het Single Responsibility Principle (SRP) niet wenselijk is.

Specificaties

  • Refactor de code zodat wordt voldaan aan het SRP principe.

Verwachte output

Totaal aantal bestellingen: 3
Totale waarde van bestellingen: 450

Nu jij

public class OrderService
{
    private List<Order> _orders;
 
    public OrderService()
    {
        _orders = new List<Order>
        {
            new Order { Id = 1, Amount = 100 },
            new Order { Id = 2, Amount = 200 },
            new Order { Id = 3, Amount = 150 }
        };
    }
 
    // Haalt een lijst van bestellingen op
    public List<Order> GetOrders()
    {
        return _orders;
    }
 
    // Bereken de totale waarde van de bestellingen
    public decimal CalculateTotalAmount()
    {
        return _orders.Sum(o => o.Amount);
    }
 
    // Print het resultaat naar de console
    public void PrintOrderSummary()
    {
        var total = CalculateTotalAmount();
        Console.WriteLine($"Totaal aantal bestellingen: {_orders.Count}");
        Console.WriteLine($"Totale waarde van bestellingen: {total}");
    }
}

Opdracht 2 Minimaliseren van afhankelijkheden

Je werkt aan een applicatie waarbij de OrderService klasse afhankelijk is van een specifieke implementatie van data-opslag (zoals DatabaseContext). We willen deze afhankelijkheid minimaliseren door gebruik te maken van een repository die als abstractie voor de data-opslag fungeert. Dit zorgt ervoor dat de OrderService klasse alleen afhankelijk is van de repository interface, en niet van een specifieke implementatie van de data-opslag.

Specificaties:

  • Refactor de code zodat wordt voldaan aan het SRP principe.
  • Tip: maak gebruik van interfaces. Hierdoor is het installeren van extra packages niet noodzakelijk.

Verwachte output

Geen.

Nu jij

public class OrderService
{
    private readonly DatabaseContext _dbContext;
    private readonly EmailService _emailService;
    private readonly NotificationService _notificationService;
    
    public OrderService()
    {
        _dbContext = new DatabaseContext(); // Directe afhankelijkheid van de DatabaseContext
        _emailService = new EmailService();  // Directe afhankelijkheid van de EmailService
        _notificationService = new NotificationService(); // Directe afhankelijkheid van de NotificationService
    }
 
    public void PlaceOrder(Order order)
    {
        // Bestelling opslaan in de database
        _dbContext.Orders.Add(order);
        _dbContext.SaveChanges();
 
        // Stuur een bevestigingsmail
        _emailService.SendConfirmationEmail(order);
 
        // Verstuur een notificatie naar de klant
        _notificationService.SendOrderNotification(order);
    }
}

Opdracht 3 Kleinere, modulaire klassen

Je werkt aan een applicatie waar je een klasse hebt die meerdere verantwoordelijkheden vervult. De klasse is te groot en moeilijk te testen vanwege de verschillende taken die het uitvoert. We willen deze klasse refactoren naar kleinere, modulaire klassen waarbij elke klasse één verantwoordelijkheid heeft (Single Responsibility Principle).

Specificaties:

  • Refactor de code zodat wordt voldaan aan het SRP principe.

Verwachte output

Geen.


### Nu jij
In de volgende code voert de OrderProcessor klasse zowel het verwerken van bestellingen, het genereren van facturen, als het verzenden van bevestigingsmails uit. Dit maakt de klasse moeilijk te onderhouden en te testen.  

Probleem: De OrderProcessor klasse heeft meerdere verantwoordelijkheden:
- Bestelling verwerken
- Factuur genereren en opslaan
- Bevestigingsmail versturen
Dit maakt de klasse moeilijk te testen en uit te breiden, omdat alle logica in één klasse is samengebracht.

```csharp
public class OrderProcessor
{
    public void ProcessOrder(Order order)
    {
        // Bestelling verwerken
        Console.WriteLine("Processing order...");

        // Factuur genereren
        var invoice = GenerateInvoice(order);

        // Factuur opslaan
        SaveInvoice(invoice);

        // Bevestigingsmail sturen
        SendConfirmationEmail(order);
    }

    private Invoice GenerateInvoice(Order order)
    {
        return new Invoice
        {
            OrderId = order.Id,
            Amount = order.Amount,
            Date = DateTime.Now
        };
    }

    private void SaveInvoice(Invoice invoice)
    {
        Console.WriteLine($"Saving invoice for order {invoice.OrderId}");
    }

    private void SendConfirmationEmail(Order order)
    {
        Console.WriteLine($"Sending confirmation email for order {order.Id}");
    }
}