When do you need to call base.method () and what code should go to base.method ()?

In the following example, the writer of the derived class is expected to call base.Add (). If this happens 1, the base can do one kind of code. If this happens last, the base may execute different logic (see Sample). I don't seem to have two ways. And an easy fix would be to stop calling the base method altogether, because the base will never know if it is called first, last, or in the middle or twice!

What is an object oriented way to handle this? Should I just stop injecting code into the underlying methods because I will never know the prerequisites and post-conditions?

EDIT: The goal is to have a business object class that performs CRUD operations. Duplicate code will be moved to the base class. For example, checking if there is a record before adding a record, the identifier of the business object is 0 and it is checked that after saving the identifier of the business object is> 0.

namespace StackOverFlowSample
{
    class BusinessObjectBase
    {
        private bool _isNew;
        private int _id;
        public virtual void Add(string newAccount)
        {
            //Code that happens when subclasses run this method with the 
            //same signature

            //makes sense if base is called 1st
            if(_isNew && _id>0) throw new InvalidOperationException("Invalid precondition state");

            //makes sense if bae is called 2nd
            if (!_isNew && _id == 0) throw new InvalidOperationException("Invalid post condition state");
        }
    }
    class BusinessObject : BusinessObjectBase {
        public override void Add(string newAccount)
        {
            //doesn't make sense, because base will need to be called again.
            base.Add(newAccount);//pre validation, logging

            //Save newAccount to database

            //doesn't make sense, because base has already been called
            base.Add(newAccount);  //post validation, logging
        }
    }
}
+3
source share
3 answers

If you want a safe way to introduce validation before and after the state, you can make the addition non-virtual and instead use another method (AddInternal or something similar) that derived classes can (or should?) Override:

namespace StackOverFlowSample
{
    abstract class BusinessObjectBase
    {
        private bool _isNew;
        private int _id;

        protected abstract void AddInternal(string newAccount);
        public void Add(string newAccount)
        {
            if(_isNew && _id>0) throw new InvalidOperationException("Invalid precondition state");
            AddInternal(newAccount);    
            if (!_isNew && _id == 0) throw new InvalidOperationException("Invalid post condition state");
        }
    }
    class BusinessObject : BusinessObjectBase {
        protected override void AddInternal(string newAccount)
        {
            //Save newAccount to database
        }
    }
}
+3
source

, , - , , " t - , ( ) , , .

, , , - .. , , . , , . - , , ...

+2

Would it make sense to have something in the lines:

class BusinessObjectBase
{
    public void Add(string newAccount)
    {
        if(_isNew && _id>0) throw new InvalidOperationException("Invalid precondition state");

        AddOperation(newAccount);

        if (!_isNew && _id == 0) throw new InvalidOperationException("Invalid post condition state");
    }

    protected void virtual AddOperation(string newAccount)
    {
        // Code from base AddOperation
    }

}
class BusinessObject : BusinessObjectBase {
    protected override void AddOperation(string newAccount)
    {
        //custom AddOperation
    }
}
+1
source

Source: https://habr.com/ru/post/1711345/


All Articles