Single Responsibility Principle
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 |
/* + The following class has two reasons to change: one is that + the product definition/behaviour changes; the other is that + the tax calculation (values or formula) changes */ class Product { public title : string; public price : double; public taxRate : double; constructor(title, price, taxRate) { this.title = title; this.price = price; this.taxRate = taxRate; } calculateTax() { return this.price * this.taxRate; } } /* * A solution is to split the class in two, each one with just one * responsibility (reason to change). In this solution the tax rate * remains in the Product class, because it is different for * different products */ class Product { public title : string; private price : double; private taxRate : double; constructor(title, price, taxRate) { this.title = title; this.price = price; this.taxRate = taxRate; } getPrice() { return this.price; } getTaxRate() { return this.taxRate; } } class TaxCalculator { static calculateTax(product) { return product.getPrice() * product.getTaxRate(); } } /* * Still the product has the tax rate "hardcoded" in it. * A better solution is to identify the real "owner" of the * tax rate in the domain model, which is the ProductCategory, * because in real world the tax rates depend on the category * of the products. */ class Product { public title : string; private price : double; private category : ProductCategory; constructor(title, price, category) { this.title = title; this.price = price; this.category = category; } getPrice() { return this.price; } getCategory() { return this.category; } } class ProductCategory { public title : string; public taxRate : double; constructor(title, taxRate) { this.title = title; this.taxRate = taxRate; } getTaxRate() { return this.taxRate; } } class TaxCalculator { static calculateTax(product) { return product.getPrice() * product.getCategory().getTaxRate(); } } |