【初学者向け】classの概念を無視してメソッドのみで全自動化した結果

# 執筆経緯

本格的にプログラミングを学ぶきっかけになった
独学で作成した下記の販売管理システムを元に
classの概念を無視するとエグいコードになるという知見を共有するために執筆します。

[化粧品販売システム](https://motoya-portfolio.com/cosme-system/)
[Github](https://github.com/motoya0118/cosme_system_public)

:::note alert
筆者は独学時代classの概念は完全に無視して実装しておりました
:::

# 対象の読者像
・class使わなくても実装できるからとclassを無視して実装している方
・class使う意義がわからない方
・classを使わないとどうなるかホラー話を聞きたい方www

# メール機能の失敗談
## 導入
作成した販売管理システムのメール送付機能は下記の図のように
・AM11時に起動するプログラム内に2機能(注文承諾・手配遅延)
・PM8時に起動するプログラム内に2機能(発送通知・レビュー依頼)
を実装しております。

![Screen Shot 2022-09-07 at 13.55.50.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2646082/04778623-fea9-1024-113b-63a64846625a.png)

## インスタンス変数の重要性 ~恐怖の引数数~
```ruby:def send_gmail_first
def send_gmail_first(
billFirstName,billLastName,orderId,orderTime,payMethodName,shipMethodName,
shipRequestDate,shipRequestTime,shipLastName,shipFirstName,shipZipCode,
shipPrefecture,shipCity,shipAddress1,shipAddress2,shipPhoneNumber,title,
totalPrice,usePoint,shipCharge,totalCouponDiscount,settleAmount,total_cal,
billMailAddress,totalMallCouponDiscount,store_name,store_adress,store_zip,
store_url,store_mail
)

#==>呼び出す時を考えると
#村上 元矢さんにメールを送りたいとき
#def send_gmail_first("元矢","村上",...)が正解で
#def send_gmail_first("村上","元矢",...)は間違い
#<==めっちゃわかりにくい。。。
```
引数29個ありました...

:::note alert
問題点
メソッド使用時に引数の順番をテレコしてしまう可能性が超絶高いこと
:::

作った本人の私が何回も順序テレコしたので、他の人が使用する場合を考えたら恐怖ですね。。。

:::note
classを使って下記のようにするのが良さそうです
:::

```ruby:インスタンス変数化する利点
class Mail
  attr_accessor(:billFirstName,:billLastName,:orderId, ...)
  
  def initialize()
    @billFirstName
    @billLastName
    @orderId
    ...
  end
　
　def send_gmail_first
    #使用するインスタンス全てがtrueの場合送付する
  end

end
#==>呼び出す時を考えると
#村上 元矢さんにメールを送りたいとき
#mail = Mail.new
#mail.billFirstName = "元矢"
#mail.billLastName = "村上"
#mail.send_gmail_first　で注文承諾メールを送付する
#-------------------------
#テレコ例
#mail.billFirstName = "村上"
#mail.billLastName = "元矢"
#<==テレコに気付きやすくなった！！！
```
クラス化することでコードの可読性が物凄く向上しました！

### 使用したclassの機能
#### インスタンス変数
ex) @billFirstName
#### initializeメソッド
def initialize()
end
#### アクセサメソッド
attr_accessor

## ミドルネームを追加しよう♪(メンテナンス性) ~恐怖の多重修正~

![Screen Shot 2022-09-07 at 13.55.50.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2646082/04778623-fea9-1024-113b-63a64846625a.png)

繰り返しになりますが本システムは、クラスの概念を一切無視してメソッドのみで書き上げた代物です...
よって、メンテナンス性が異常に悪くなっております。
その例として全てのメール本文にミドルネームの概念を追加することを想定して解説していきます！

### クラス化しないとこうなる
```ruby:send_gmail_first

#原本
def send_gmail_first(
billFirstName,billLastName,orderId,orderTime,payMethodName,shipMethodName,
shipRequestDate,shipRequestTime,shipLastName,shipFirstName,shipZipCode,
shipPrefecture,shipCity,shipAddress1,shipAddress2,shipPhoneNumber,title,
totalPrice,usePoint,shipCharge,totalCouponDiscount,settleAmount,total_cal,
billMailAddress,totalMallCouponDiscount,store_name,store_adress,store_zip,
store_url,store_mail)

#修正例1(引数の可読性重視)
def send_gmail_first(
billFirstName,billLastName,BillMidleName,orderId,orderTime,payMethodName,
shipMethodName,shipRequestDate,shipRequestTime,shipLastName,shipFirstName,
shipZipCode,shipPrefecture,shipCity,shipAddress1,shipAddress2,shipPhoneNumber,
title,totalPrice,usePoint,shipCharge,totalCouponDiscount,settleAmount,total_cal,
billMailAddress,totalMallCouponDiscount,store_name,store_adress,store_zip,
store_url,store_mail)
#==>引数の順番が変わってるのでテレコが容易に発生する

#修正例2(引数の順番重視)
def send_gmail_first(
billFirstName,billLastName,orderId,orderTime,payMethodName,
shipMethodName,shipRequestDate,shipRequestTime,shipLastName,shipFirstName,
shipZipCode,shipPrefecture,shipCity,shipAddress1,shipAddress2,shipPhoneNumber,
title,totalPrice,usePoint,shipCharge,totalCouponDiscount,settleAmount,total_cal,
billMailAddress,totalMallCouponDiscount,store_name,store_adress,store_zip,
store_url,store_mail,BillMiddleName)
#==>メール本文側のメンテナンスは楽になるが、最初に姓名がきて
#==>27個離れて最後にミドルネームがくるのはホラーとしか言えない。。。
```
```ruby:メール本文側の例
message_text = """
----------------------------------------------------------------------
このメールはお客様の注文に関する大切なメールです。
お取引が完了するまで保存してください。
----------------------------------------------------------------------
orderId: #{orderId}
#{billLastName} #{billFirstName} 様
この度はご注文頂きまして誠にありがとうございます。
下記の内容でご注文を承りましたので、ご確認をお願い致します。
..................
■□□□□□□□□□□□□□□□□□□□□■
■□□□□□□□□□□□□□□□□□□□□■
""" 

#==>誤ってメソッド自体を修正例2,呼び出す時に修正例1にすると
#==>#{orderId}にbillMidleNameが入ってしまうことが容易に想像できます...
```
**更にメール送付メソッドは2ファイル間に2メソッド = 計4メソッドあるので全て修正しなければなりません**
**異常なメンテナンス性の高さですね...**

:::note alert
問題点
メンテナンスに要するリソースが超絶高いこと
:::

### クラス化するとメンテナンス性が一変する！！！
**クラス化して、メール機能を1つの別ファイルに切り出して**
**呼び出しがわのファイルでrequireする形にすればメンテナンス性が大幅に向上しそうです**
![Screen Shot 2022-09-08 at 14.20.11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2646082/d62ed41e-de8d-f0a7-20c8-55acbeeac1af.png)

```ruby:mail.rb
class Mail
  attr_accessor(:billFirstName,:billLastName,:orderId, ...)
  
  def initialize()
    @billFirstName
    @billLastName
    @orderId
    ...
  end
　
　def send_gmail_first
  end

  def send_gmail_delay
  end
  
  def send_gmail_ship_Notification
  end

  def send_gmail_after_Notification
  end
end

#==> attr_accessorとinitializeにbillMiddleNameを順不同で追加可能
```
```ruby:メール本文側の例
message_text = """
----------------------------------------------------------------------
このメールはお客様の注文に関する大切なメールです。
お取引が完了するまで保存してください。
----------------------------------------------------------------------
orderId: #{@orderId}
#{@billLastName} #{@billFirstName} 様
この度はご注文頂きまして誠にありがとうございます。
下記の内容でご注文を承りましたので、ご確認をお願い致します。
..................
■□□□□□□□□□□□□□□□□□□□□■
■□□□□□□□□□□□□□□□□□□□□■
""" 
```
**このようにするとmail.rb1ファイルにインスタンス変数を1つ追加してメールメソッド4つを修正すれば良いのでメンテナンスしやすいですね♪**

:::note
学び
classを無視するとメンテナンスできないシステムになる
:::

## 終わりに
まだまだオブジェクト指向の触りしか理解してませんが、
クラス設計を無視して開発を進めるとえらいことになるという
失敗体験を共有できたら幸いです！