A depreciation strategy separates an asset’s depreciation calculation from the asset itself. FundingDetails delegates the calculation to a DepreciationStrategy, so the method can change without reshaping the Asset model. This applies the Dependency Inversion Principle: the domain depends on a strategy interface rather than a particular calculation. section 3.3
Define one calculation contract and supply method-specific implementations:
- DepreciationStrategy exposes calculate_depreciation(FundingDetails) and returns a depreciation amount. section 4.1.4
- StraightLineDepreciationStrategy calculates (cost − salvage value) / useful life. section 4.1.4
- DecliningBalanceDepreciationStrategy and DoubleDecliningDepreciationStrategy provide alternative declining calculations; NoDepreciationStrategy returns 0. section 4.1.4
Refining an implementation prompt
A vague request can produce a plausible but wrong straight-line calculation that omits salvage value and useful life. State the formulas explicitly, even as pseudocode, then review the generated implementation against those requirements before using it. section 4.1.4
Listing 4.5 Output from our prompt to calculate depreciation methods
from abc import ABC, abstractmethod
from itam.domain.funding_details import FundingDetails
from math import pow
class DepreciationStrategy(ABC):
@abstractmethod
def calculate_depreciation(self, funding_details: FundingDetails) -> float:
pass
class StraightLineDepreciationStrategy(DepreciationStrategy):
def calculate_depreciation(self, funding_details: FundingDetails) -> float:
cost = funding_details.get_asset().get_cost()
salvage_value = funding_details.get_asset().get_salvage_value()
useful_life = funding_details.get_asset().get_useful_life()
return (cost - salvage_value) / useful_life
class DecliningBalanceDepreciationStrategy(DepreciationStrategy):
def calculate_depreciation(self, funding_details: FundingDetails) -> float:
cost = funding_details.get_asset().get_cost()
depreciation_rate = funding_details.get_depreciation_rate()
return cost * pow(1 - (depreciation_rate / 100),
datetime.now().year - asset.get_purchase_date().year)
class DoubleDecliningDepreciationStrategy(DepreciationStrategy):
def calculate_depreciation(self, funding_details: FundingDetails) -> float:
cost = funding_details.get_asset().get_cost()
depreciation_rate = funding_details.get_depreciation_rate()
return DecliningBalanceDepreciationStrategy()
.calculate_depreciation(funding_details) * 2
class NoDepreciationStrategy(DepreciationStrategy):
def calculate_depreciation(self, asset: Asset) -> float:
return 0
Inspect a representative Python implementation: an abstract strategy interface and four concrete calculation classes. section 4.1.4
