LoginSignup
22
8

More than 1 year has passed since last update.

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

Posted at

執筆経緯

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

化粧品販売システム
Github

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

対象の読者像

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

メール機能の失敗談

導入

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

Screen Shot 2022-09-07 at 13.55.50.png

インスタンス変数の重要性 ~恐怖の引数数~

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個ありました...

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

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

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

インスタンス変数化する利点
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

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

クラス化しないとこうなる

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個離れて最後にミドルネームがくるのはホラーとしか言えない。。。
メール本文側の例
message_text = """
----------------------------------------------------------------------
このメールはお客様の注文に関する大切なメールです。
お取引が完了するまで保存してください。
----------------------------------------------------------------------
orderId: #{orderId}
#{billLastName} #{billFirstName} 様
この度はご注文頂きまして誠にありがとうございます。
下記の内容でご注文を承りましたので、ご確認をお願い致します。
..................
■□□□□□□□□□□□□□□□□□□□□■
■□□□□□□□□□□□□□□□□□□□□■
""" 

#==>誤ってメソッド自体を修正例2,呼び出す時に修正例1にすると
#==>#{orderId}にbillMidleNameが入ってしまうことが容易に想像できます...

更にメール送付メソッドは2ファイル間に2メソッド = 計4メソッドあるので全て修正しなければなりません
異常なメンテナンス性の高さですね...

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

クラス化するとメンテナンス性が一変する!!!

クラス化して、メール機能を1つの別ファイルに切り出して
呼び出しがわのファイルでrequireする形にすればメンテナンス性が大幅に向上しそうです
Screen Shot 2022-09-08 at 14.20.11.png

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を順不同で追加可能
メール本文側の例
message_text = """
----------------------------------------------------------------------
このメールはお客様の注文に関する大切なメールです。
お取引が完了するまで保存してください。
----------------------------------------------------------------------
orderId: #{@orderId}
#{@billLastName} #{@billFirstName} 様
この度はご注文頂きまして誠にありがとうございます。
下記の内容でご注文を承りましたので、ご確認をお願い致します。
..................
■□□□□□□□□□□□□□□□□□□□□■
■□□□□□□□□□□□□□□□□□□□□■
""" 

このようにするとmail.rb1ファイルにインスタンス変数を1つ追加してメールメソッド4つを修正すれば良いのでメンテナンスしやすいですね♪

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

終わりに

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

22
8
4

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
22
8