如何成为一个更好的程序员?设计原则I:KISS,DRY...

 

如何成为一个更好的程序员?设计原则I:KISS,DRY...

文章插图
 
当我开始编程时 , 我很高兴自己的程序正在编译并且可以按预期的方式运行 , 但是随着时间的推移 , 我编写了越来越多的代码 , 我开始欣赏设计模式 。
设计模式不仅使我的代码更好 , 更易读并且更易于维护 , 而且还为我节省了很多时间 , 我的意思是要花费大量的调试时间 。因此 , 我想与您分享一些内容 。
这种设计模式源自" DesignPatterns书"的作者"四人帮" 。他们介绍了这些原理 , 这些原理在面向对象编程中特别有用 。可能您已经在使用所有这些内容 , 但是刷新您的知识总是好的 。
所有代码示例均在TypeScript中 。
KISS:保持简单愚蠢这种模式的主要概念是保持尽可能简单的代码 。这意味着每个方法 , 类 , 接口的名称应尽可能清楚 , 函数 , 方法等内部的逻辑也应尽可能简单明了 。
KISS看起来不像的示例:
class payup {howmuchtopay(region: string, amount: number, tax: number, country: string, price: number) {if (country == "pl_PL") {if (region == "masovia" || region == "Lubusz") {if (amount > 15) {price -= ((15/100)*price);price += ((tax/100)*price);return (price * amount);}return ((price+((tax/100)*price)) * amount);} else {return ((price+((tax/100)*price)) * amount);}} else {return (price*amount);}}}const p = new payup();console.log( p.howmuchtopay("masovia", 25, 23, "pl_PL", 1000) );在此示例中 , 我们的代码什么都没有告诉我们 。类名 , 方法名写不正确 。方法的主体混乱不堪 , 如果不能维护则很多 。
使用KISS原理后 , 它看起来像这样:
interface Country {code: string;discountAmountPercent: number;taxAmountPercent: number;discountRegions: Array<string>;}class Poland implements Country {code: string = "pl_PL";discountAmountPercent: number = 15;taxAmountPercent: number = 23;discountRegions: Array<string> = ["masovia","lubusz"];}class Payment {setTax(price: any, tax: number) {return (price + (tax/100*price));}setDiscount(price: any, discount: number) {return (price - ((discount/100)*price));}pay(country: Country, region: string, amount: number, nettoPrice: number) {if (country.discountRegions.indexOf(region.toLowerCase()) != -1&& amount > 15) {nettoPrice = this.setDiscount(nettoPrice, country.discountAmountPercent);}const bruttoPrice = this.setTax(nettoPrice, country.taxAmountPercent);return (bruttoPrice*amount);}}const payment = new Payment();console.log ( payment.pay((new Poland), 'masovia', 25, 1000) );您可以在上面的代码中找到KISS原理 。这是可扩展的解决方案:我们可以有多个国家/地区 , 并轻松添加新的折扣区域 , 只需在国家/地区类别中修改DiscountRegions属性即可 。由于有了界面 , 我们还可以确保每个新国家都具有必需的属性 。支付类还具有以其功能命名的方法 , 由于这种结构 , 我们优化了代码 , 使其只有一个 。
那就是亲吻:干净 , 简单的代码 。
DRY:不要重复自己这个概念建议我们将执行相同操作的代码划分为小部分 。有时 , 我们有多行代码基本上都在做同样的事情:例如使用指定条件按数组过滤 , 向对象添加一些东西等 。通常的好习惯是摆脱它 。
不良DRY代码的示例是:
class Week {days: any;constructor() {this.days = [];this.days.push({name: "Monday",order: 1});this.days.push({name: "Tuesday",order: 2});this.days.push({name: "Wednesday",order: 3});this.days.push({name: "Thursdya",order: 4});this.days.push({name: "Friday",order: 5});this.days.push({name: "Saturday",order: 6});this.days.push({name: "Sunday",order: 7});}list() {console.log(this.days);}}const w = new Week();w.list();在此示例中 , 我们添加了多天 , 并且类的代码基本相同 。我们可以通过创建用于此目的的方法来避免这种情况 。同样 , 通过多次手动输入日期名称 , 我们扩展了出错的可能性 。
具有良好DRY代码的适当类的示例:
enum dayNames {Monday = "Monday",Tuesday = "Tuesday",Wednesday = "Wednesday",Thursday = "Thursday",Friday = "Friday",Saturday = "Saturday",Sunday = "Sunday"}class Day {name: string;order: number;constructor(name: string, order: number = 0) {this.name = name;this.order = order;}setOrder(order: number) : Day {this.order = order;return this;}}class Week {days: Array<Day> = new Array();private addDay(name: string): Day {const day = new Day(name);const index = this.days.push(day);day.setOrder(index)return day;}constructor() {for(let dayName in dayNames) {this.addDay(dayName);}}listDays() {console.log(this.days);}}const firstWeek = new Week();firstWeek.listDays();


推荐阅读