Day 8 — 自动化回信机(5) 优化回信机

咦?我们都写完了,为什麽还不进入下一个专题呢?

啧啧,这你就不懂了!身为一个工程师,能动,只是交件标准。但是你後续如果还要维护,那麽你写的这份烂 code 会在未来搞死你!

真心不骗!

不说别的,其实我写这个系列时,我已经用了这个东东大概有 2 个月了,但是当我回头整理时,惊为天人!

这是哪个王八蛋写的 Code 啦!

心中真是充满了三字经…

所以我特别加了一个部分是要来「优化」你的程序码。

一方面,你可以在後续更好维护;另一方面,你在之後如果要扩增东西,也比较好处理!

但是在优化之前,我们先来解决一个 Bug!

不知道大家有没有发现,这支程序,有一个重大的 Bug 呢?

没错,就是勾选拿掉一样也会寄信!

这样就糟糕了!如果不小心把勾勾拿掉时,使用者不就会又收到重复信件,然後引发一连串你要「客服」的问题…

所以为了不要让未来的我们难过,我们这边必须要额外加上一个判断式:

function onEditTrigger() {
  const e = {
    range: SpreadsheetApp.getActiveRange()
  };
  if (e.range.isChecked()) {
    const theSheet = e.range.getSheet();
    const theRowIndex = e.range.getRow();
    const theColIndex = e.range.getColumn();
    const thisRange = theSheet.getRange(theRowIndex, 1, 1, theColIndex);
    const theData = {};
    theData.email = thisRange.getCell(1, 2).getValue();
    theData.shoolId = thisRange.getCell(1,3).getValue();
    theData.class = thisRange.getCell(1,4).getValue();
    theData.name = thisRange.getCell(1,5).getValue();
    console.log(theData);
    MailApp.sendEmail({
      to: theData.email, // 这边我们直接把取得的 email 带入
      subject: "【系统信件 请勿回复】就是爱兔兔教,兔兔教是唯一真神!",
      body: `亲爱的同学 ${theData.name} 你好
      你的密码已经修改为「我爱兔兔教」,
      请务必记好你的新密码!
      `
    });
    console.log(`Email已经寄出至 ${theData.email}`);
  } else {
    console.log(`取消勾选`);
  }
}

我们藉由判断该格是否已经被勾选成为 checked 状态来决定我们是不是要发信。

弄完之後我们回头去验证一下:

我们把勾勾拿掉,然後去看结果:

恩!果然不会寄信了!

但是一定有人会突发奇想:如果是修改到其他栏位呢?

我们直接来实验吧!

果然不用担心,因为其他栏位不是 CheckBox ,所以不存在被勾选起来的问题,因此永远都会是 false

这边也附上 Docs 的部分让你好查询相关细节: Class Range


结束了 Debug ,我们来谈谈其他优化的部分。

优化其实不只是将程序码结构、速度进行优化,同时也包含了使用介面、使用体验等等。

介面,我们是不用想了啦,就是那个试算表,但是我们可以调整程序码结构以及使用体验的部分!

你会问:速度呢?
这个我们先不管…

首先是程序码结构,我们把 MailApp.sendEmail() 直接写在 onEditTrigger() 中其实看似没问题,但是当我们要额外扩充功能时,例如:针对每一个系统要发不同内容的信件,就会出现问题。

因此我们要修改一下,把 MailApp.sendEmail() 这个功能提取出来另外用一个函式来包装:

function onEditTrigger() {
  const e = {
    range: SpreadsheetApp.getActiveRange()
  };
  if (e.range.isChecked()) {
    const theSheet = e.range.getSheet();
    const theRowIndex = e.range.getRow();
    const theColIndex = e.range.getColumn();
    const thisRange = theSheet.getRange(theRowIndex, 1, 1, theColIndex);
    const theData = {};
    theData.email = thisRange.getCell(1, 2).getValue();
    theData.shoolId = thisRange.getCell(1,3).getValue();
    theData.class = thisRange.getCell(1,4).getValue();
    theData.name = thisRange.getCell(1,5).getValue();
    console.log(theData);
-    MailApp.sendEmail({
-      to: theData.email, // 这边我们直接把取得的 email 带入
-      subject: "【系统信件 请勿回复】就是爱兔兔教,兔兔教是唯一真神!",
-      body: `亲爱的同学 ${theData.name} 你好
-      你的密码已经修改为「我爱兔兔教」,
-      请务必记好你的新密码!
-      `
-    });
+    sendMail(theData.email, theData.name)
    console.log(`Email已经寄出至 ${theData.email}`);
  } else {
    console.log(`取消勾选`);
  }
}

+function sendMail(email, name) {
+  MailApp.sendEmail({
+    to: email,
+    subject: "【系统信件 请勿回复】就是爱兔兔教,兔兔教是唯一真神!",
+    body: `亲爱的同学 ${name} 你好
+    你的密码已经修改为「我爱兔兔教」,
+    请务必记好你的新密码!
+    `
+  });
+}

不知道有没有人注意到,之前写过的 sendMail() 函式这边可以拿出来用 ???
如果你还没删掉,那就拿出来用一用吧!

甚至,我们直接要求传递进 sendMail() 函式参数为 Object 型态,再用解构赋值 (注一) 的方式得到需要的内容。

这样的好处是我们需要什麽内容,都不用再去更动到 onEditTrigger() 中的程序码,只要去修改 sendMail() 中的参数就可以把功能进行修整了!

当然啦,这有没有符合 Function Programming 的原则,那就是另外一回事了!
如果你想了解更多,你可以参考 注二

总之,藉由这样的方式我们把 MailApp.sendMail() 这件事情拆出来,在後续的程序码维护上会更佳的容易!


接下来来到了体验的优化。

就请你想想看,如果今天你申请了三种不同的系统,但是你都收到同一种信件,这样合理吗?

当然不合理啊!

所以我们必须要在寄信时,顺便判断他究竟是哪一个系统,来决定我需要寄出哪一封信。

这边,我决定跟着上面的步伐,将这个「选择寄出信件内容」的功能额外拆分出来,独立成一个 Function:

function selectMailContent(name, system) {
  return `亲爱的同学 ${name} 你好
  你申请了 ${system} 的密码重设,
  系统管理员已经将您的密码重新设为 「${system === "A 系统" 
   ? "我爱兔兔教"
   : system === "B 系统" ? "兔兔叫好听"
   : "这是兔兔教你知道的"
  }」
  请务必记好你的新密码!
  `;
}

这边我使用了「三元运算子」(注三) 来决定我要发出去什麽内容

接着将我的程序码替换进去:

function onEditTrigger() {
  const e = {
    range: SpreadsheetApp.getActiveRange()
  };
  if (e.range.isChecked()) {
    const theSheet = e.range.getSheet();
    const theRowIndex = e.range.getRow();
    const theColIndex = e.range.getColumn();
    const thisRange = theSheet.getRange(theRowIndex, 1, 1, theColIndex);
    const theData = {};
    theData.email = thisRange.getCell(1, 2).getValue();
    theData.shoolId = thisRange.getCell(1,3).getValue();
    theData.class = thisRange.getCell(1,4).getValue();
    theData.name = thisRange.getCell(1,5).getValue();
+    theData.name = thisRange.getCell(1,6).getValue();
    console.log(theData);
    sendMail(theData)
    console.log(`Email已经寄出至 ${theData.email}`);
  } else {
    console.log(`取消勾选`);
  }
}

-function sendMail({email, name}) {
+function sendMail({email, name, system}){
  MailApp.sendEmail({
    to: email,
    subject: "【系统信件 请勿回复】就是爱兔兔教,兔兔教是唯一真神!",
-    body: `亲爱的同学 ${name} 你好
-    你的密码已经修改为「我爱兔兔教」,
-    请务必记好你的新密码!
-    `
+    body: selectMailContent(name, system)
  });
}

function selectMailContent(name, system) {
  return `亲爱的同学 ${name} 你好
  你申请了 ${system} 的密码重设,
  系统管理员已经将您的密码重新设为 「${system === "A 系统" 
   ? "我爱兔兔教"
   : system === "B 系统" ? "兔兔叫好听"
   : "这是兔兔教你知道的"
  }」
  请务必记好你的新密码!
  `;
}

接下来去试验一下:

成功~


今天的教学就到这里罗~

我们成功地完成了一个简单的勾选寄信系统!明天就要来写新的专题啦!

有没有兴奋啊?(终於脱离这个奇妙的轮回了…)

今日作业:

请试着想想看还有没有可以优化的部分呢?

我知道大家可能前面的作业都还没做,今天先出个延伸题请大家去想一想喔~

明天见罗,掰掰!


关於兔兔们:


学生:话说回来,我们不是工程师,可不可以原本那样写就好?
我:只要解决问题的人,就都是工程师!所以当然还是得好好优化一下自己的程序码啊?
学生:但是…能动就好不是吗?这样很麻烦耶!
我:说的也是啦…话说这次的成绩,「能补考就好」对吧?加减给个 59 分好了…
学生:老师,我觉得优化是非常重要的,我马上去进行!(溜走)

注一:
https://developer.mozilla.org/zh-TW/docs/Web/JavaScript/Reference/Operators/Destructuring_assignment

注二:
[Javascript] Functional Programming 一文到底全纪录

注三:
https://developer.mozilla.org/zh-TW/docs/Web/JavaScript/Guide/Expressions_and_Operators#%E6%A2%9D%E4%BB%B6%EF%BC%88%E4%B8%89%E5%85%83%EF%BC%89%E9%81%8B%E7%AE%97%E5%AD%90


<<:  [Day 8]开赛八天即遭遇难题(前端篇)

>>:  Unity与Photon的新手相遇旅途 | Day8-角色动画(Idle、walk)

CSS 命名基础介绍 DAY40

今天要来介绍 CSS 命名 首先先来介绍 驼峰式命名: https://zh.wikipedia.o...

替代网站(Alternative Sites)- 冷站点的最大好处

冷站点没有适当的计算机设备,因此它不提供异地数据存储、保留替代计算能力或响应电子发现请求。 冷站点是...

Day 16 -资料查询语言 LEFT JOIN 和 RIGHT JOIN!

LEFT JOIN 可以用来建立左外部连接,查询的 SQL 叙述句 LEFT JOIN 左侧资料表 ...

AutoCAD ActiveX #4 Block & Layer

Layer A logical grouping of data, similar to trans...

[Day 3] Course 1_Foundation - Data Analytics 介绍

《30天带你上完 Google Data Analytics Certificate 课程》系列将...