开发者中心 > 专栏 > 内容详情
分享
  • 点击前往QQ分享

  • 点击前往微博分享

  • 点击复制链接

从程序员到架构师,互联网人都必须学习的 4 种编程结构

  • 京东智联云开发者
  • 2020-10-09

我的小伙伴最近参加了一个在线编码训练营。 当我观看她的第一门编程课程时,我很惊讶地发现我在学校学到的很多东西都没有转化为工作。


在本文中,我们将确定四种编程结构,当您初次发现编程的工作原理时,即使相对基础,但忽略它们仍会拖慢您进阶的步伐。

01
抛却循环

循环是您在计算机编程专业中学习的第一批构造之一。一个简单的while循环演示了自动化的力量,您可以在其中重复执行一组指令,直到满足条件为止。


每当您看到项目集合时,您可能都会尝试使用while循环或for循环,但这很难成为最优解。


const groceries = [
  {
    name: 'Face Masks',
    price: 17.50,
  },
  {
    name: 'Disinfecting Wipes',
    price: 24.99,
  },
  {
    name: 'Goggles',
    price: 8.99,
  },
  {
    name: 'Gloves',
    price: 25.99,
  },
  {
    name: 'Hand Sanitizers',
    price: 24.99,
  },
];

例如,给定一个对象数组,其中每个对象代表一个杂货。如果要打印每个杂货项目的名称,该怎么办?



let index = 0;while (index < groceries.length) {
  console.log(groceries[index].name);
  index = index + 1;
}

这种while循环当然可以实现所需的功能,但是每次要抓取一件物品时,都必须跟踪索引以进入杂货数组。如果您忘记增加索引,也有进入无限循环的风险。


考虑以下替代方法:

groceries.forEach((item) => {
  console.log(item.name);
});

forEach是一个高阶函数,它将另一个函数作为参数,并对数组中的每个元素执行一次提供的函数。通过使用forEach,我们删除了使用索引来跟踪和访问数组的多余代码,并记录了逻辑的内容-打印出每个杂货项目的名称。


while和for循环通常太宽泛,无法捕获我们的代码的意图。如果要编写更好的代码,请首先使用功能更明确的函数替换循环。


以下是一些有关使列表变异和汇总列表的相关示例。

// Before:let index = 0;
const prices = [];while (index < groceries.length) {
  prices.push(groceries[index].price);
  index = index + 1;
}// After:groceries.map((item) => {
  return item.price;
});

// Before:let index = 0;
let total = 0;while (index < groceries.length) {
  total = total + groceries[index].price;
  index = index + 1;
}// After:groceries.reduce((sum, item) => {
  return sum += item.price;
}, 0);


02
抛却条件语句

每次添加else语句时,代码的复杂度都会增加两倍。if-else和switch语句之类的条件构造是编程领域的基础块。但是,当您要编写简洁,可扩展的代码时,它们会妨碍您的工作。


幸运的是,有一些技巧可以摆脱条件限制。


数据结构


考虑以下用于计算折扣的函数:

const discount = (amount, code) => {
  switch (code) {
    case 'DIJFNC':
      return amount * 0.80;
    case 'XPFJVM':
      return amount * 0.75;
    case 'FJDPCX':
      return amount * 0.50;
  }
};

每次要添加新的代码时,都必须在switch语句中添加新的案例。而且,如果您犯了一个错误,则会破坏整个计算。


现在,让我们将条件替换为对象。

const DISCOUNT_MULTIPLIER = {
  'DIJFNC': 0.80,
  'XPFJVM': 0.75,
  'FJDPCX': 0.50,
};const discount = (amount, code) => {
  return amount * DISCOUNT_MULTIPLIER[code];
};

这种重写有效地将数据与核心计算逻辑解耦,从而更容易地独立修改它们。


多态性


替换条件的第二种方法是利用面向对象编程语言的一个关键功能-多态。

const checkout = (amount, paymentMethod) => {
  switch (paymentMethod) {
    case 'credit-card':
      // Complex code to charge ${amount} to the credit card.
      break;
    case 'debit-card':
      // Complex code to charge ${amount} to the debit card.
      break;
    case 'cash':
      // Complex code to put ${amount} into the cash drawer.
      break;
  }
};const customers = [
  {
    amount: 75.00,
    paymentMethod: 'credit-card',
  },
  {
    amount: 50.00,
    paymentMethod: 'debit-card',
  },
  {
    amount: 25.00,
    paymentMethod: 'cash',
  },
];customers.forEach(({ amount, paymentMethod }) => {
  checkout(amount, paymentMethod);
});

用于处理各种付款方式的代码行散布在switch语句中,使代码难以阅读。而且,如果要修改特定付款方式的逻辑,还会给人带来伤害,这是冒着破坏其他两个风险的风险,因为它们都属于同一功能。

class CreditCardCheckout {
  static charge(amount) {
    // Complex code to charge ${amount} to the credit card.
  }
}class DebitCardCheckout {
  static charge(amount) {
    // Complex code to charge ${amount} to the debit card.
  }
}class CashCheckout {
  static charge(amount) {
    // Complex code to put ${amount} into the cash drawer.
  }
}const customers = [
  {
    amount: 75.00,
    paymentMethod: CreditCardCheckout,
  },
  {
    amount: 50.00,
    paymentMethod: DebitCardCheckout,
  },
  {
    amount: 25.00,
    paymentMethod: CashCheckout,
  },
];customers.forEach(({ amount, paymentMethod}) => {
  paymentMethod.charge(amount);
});

多态有助于我们打破冗长的switch语句。每个Class仅负责一种付款方式。


这里要注意的一件事是,即使我们成功地从重构代码中删除了条件语句,实际上,我们只是将选择付款方式的决定移到了上游。创建客户的人现在负责分配付款方式类。


03
抛却文字变量名称


编程教程中充斥着糟糕的变量和函数名,部分原因是代码示例通常不需要提供完整的上下文来说明其试图解释的任何要点。例如:

const arr = [
  'Breakfast Cereal',
  'Candy and Snack',
  'Dairy',
  'Paper Products and Cleaning Supplies',
];const func = (n) => {
  const i = arr.findIndex(i => i === n);
  console.log(i);
};func('Dairy');

该代码块很好地演示了findIndex的用法,但完全不适用于实际项目。变量名称没有告诉我们它们为什么存在。当我们对他们的服务目的一无所知时,对读者来说很难,甚至更难修改。


要写出更好的变量名字,我们必须从了解上下文开始。这里有一个常见的杂货店过道名称列表。过渡名称以有意义的方式排序,以便当我们使用给定的过渡名称调用该函数时,我们将返回其在此列表中的位置,代表过道编号。我们可以如下重写代码:

const aisles = [
  'Breakfast Cereal',
  'Candy and Snack',
  'Dairy',
  'Paper Products and Cleaning Supplies',
];const printAisleNumber = (name) => {
  const number = aisles.findIndex((aisleName) => {
    return aisleName === name;
  });  console.log(number);
};printAisleNumber('Dairy');

当您提出正确的变量名称时,它表明您真正掌握了代码要解决的问题的上下文。有目的的变量名将使您的代码从单纯的计算指令升级为用户指南,以帮助读者了解您的工作。


04
抛却Global Scope


第一次学习编程时,您可能会从一个简单的hello world程序开始。然后,您将学习在单个文件中编写代码,并观察程序从上到下逐行执行代码。您永远不会怀疑在文件开头声明的变量在其他地方不可用。


您编写的所有内容的想法都存在于所有人都可以访问的全局空间中,这是有效使用抽象的障碍。您没有动力创建封装代码的抽象。


我的建议是忘记Global Scope。将每个函数,对象和类都视为一个新的Universe。专注于如何创建摘要来表示您的想法以及这些想法如何相互影响。


TLDR 原 则

  • 用高阶函数替换循环

  • 将条件替换为数据结构和多态

  • 用有目的的变量名替换文字变量名

  • 忘记Global Scope


🔗原文链接:

https://levelup.gitconnected.com/4-things-you-have-to-unlearn-to-become-a-better-programmer-547adf476445


以上信息来源于网络,由“京东智联云开发者”公众号编辑整理,不代表京东智联云立场


共0条评论