简体   繁体   中英

Which class should be responsible for certain actions?

I am making a Storage System Application. Each storage system contains up to 10 Warehouses capable of storing Stock Items.

I want to create a method for updating a Warehouse properties (Name, Description etc). There is a business rule that each Warehouse within a storage system must have a unique name, and im unsure which class should be responsible for this. Im trying to stick to the principle that each class should only be responsible for itself.

Here is a simple mock up of the code (C#)

 public class StorageSystem
{
    public List<Warehouse> Warehouses{Get;}
}

public class Warehouse
{
    public string Name{Get; private Set;}

    public int StorageSystemId{Get; Set;}
    public StorageSystem Sotrage System{Get; Set;}
}

I think i should do the following,

Step1. Create a method in StorageSystem class.

public bool WarehouseNameAvailable(string name)
{
   //Check List of Warehouses for the name
   //if found return false
   //else return true
}

Step2. Create a method in the Warehouse

public void UpdateWarehouseName(string name)
{
   if(StorageSystem.WarehouseNameAvailable(name))
    {
        this.name = name;
    }
    else 
    {
        //Throw Exception 
    {
}

Is this the "proper and correct" way to do this?

Make T_WAREHOUSE.NAME unique (just assumed that your table/columns would have names like this) - database wise and handle the exception if a second entry gets written with the same name.

You could rise that error/exception up to user level too, to show users what went wrong: enter a different name please, "Super Dooper Warehouse" is already taken


Your questions text suggests that this will be a bigger project with many classes that interact with each other.

If you are not using a ORM, think about using one! It does a lot what you are trying to achive via custom methods loke your WarehouseNameAvailable workaround.

If you are using Entity Framework you can do this on your class properties via [Unique] attribute.

Is this the "proper and correct" way to do this?

This highly depends on your overall application architecture, imho. Ask 5 developers whether your solution is "proper and correct" and you will get 6 opinions.

To get to the point: When purely relating on DDD concepts, your solution seems at least possible. But to be honest, i've never come across an enterprise application of notable size that was able to project its business logic entirely in the domain model in a structured (!) and maintainable (!) way and did not need some kind of service layer upon it. I personally like this approach and would recommend pojecting this requirements in separate classes, that represent business/use cases:

public class RenameAction {
    //Some Kind of DbSet, Database Connection, external service,...
    //I'll go with an EF - DbSet<Warehouse> in this example
    private readonly DbSet<Warehouse>_warehouses;
    private readonly DbSet<StorageSystem> _storageSystem;

    public void Execute(int storageSystemId, int warehouseId, string name) {
        var storageSystem = _storageSystems.Single(system => system.Id == storageSystemId);

        if (_storageSystem.Warehouses.Any(wh => wh.Name == name))
            throw new BusinessLogicException("Warehouse names must be unique within storage systems!");
        var warehouse = storageSystem.Warehouses.Single(wh => wh.Id == warehouseId);
        warehouse.Name = name;

        //Write back the updated warehouse to whereever, this won't work with an DbSet<Warehouse>.
        _warehouses.Update(warehouse);
    }
}

But again, this is just how I would deal with that.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM