コード例 #1
0
        private void TakeMoney(decimal amount)
        {
            string error = _atm.CanTakeMoney(amount);

            if (error != string.Empty)
            {
                NotifyClient(error);
                return;
            }

            decimal amountWithCommission = _atm.CalculateAmountWithCommission(amount);

            _paymentGateway.ChargedPayment(amountWithCommission);
            _atm.TakeMoney(amount);
            _repository.Save(_atm);

            /*Option 1 :
             *           HeadOffice headOffice = GetHeadOfficeInstance();
             *          headOffice.Balance += amountWithCommission;
             *          _headOfficeRepository.Save(headOffice);
             *
             * Drawbacks:
             *  a - coupling HeadOffice to viewModel entity, i.e. additional dependency between ATM and mgnt bounded context
             *      not only mgt knows about ATM but also ATM becomes aware of mngt => bidirectional coupling!!!
             *
             *  b - if we add another viewAtmModel we should also repeat our selves transfering the balance to the head office.
             *      => Error prone due to code duplication and possible human factor!
             */

            //OR

            /*Option 2 :  TakeMoney adding  headOffice as param :  TakeMoney(decimal amount, HeadOffice headOffice)
             *         headOffice.Balance += amountWithCommission;
             *
             * Pros: it allows us to eliminate code duplicate but...
             * Drawbacks:
             *     a - still bidirectional coupling between ATM and mngt bounded contexts => should be avoided
             *         not only mgt knows about ATM but also ATM becomes aware of mngt => bidirectional coupling!!!
             *
             *     b - ATM entity gets responsability which not related to ATM itself, it's not up to ATM to increase
             *     the balance of the headoffice
             */
            /********************************************************************************
            * Option 3 : decoupling of the bounded context through the use of Domain events
            *   - ATM raise event when cash withdrawal
            *   - Mngt should subscribe to such events
            ********************************************************************************/

            NotifyClient("You've taken " + amount.ToString("C2"));
        }