ショートコードの属性に関する処理を集めたユーティリティクラス
ショートコードの属性に関する処理を集めたユーティリティクラスについて、PHPソースコードを解説しています。
このユーティリティクラスには、ShortcodeAttributeクラスのインスタンスを作成するstaticメソッドが、あります。
ShortcodeAttributeクラスは、ショートコードの各属性を保持するクラスです。
ショートコードの属性に関するユーティリティクラスを用意することで、
全てのソースコードの中から、ショートコードの属性に関する処理を見つけやすくなっています。
ショートコードの各属性を保持するShortcodeAttributeクラスのインスタンスを作成する
class ShortcodeAttributeUtils {
public static function makeShortcodeAttribute($operation, $searchIndex,
$keyword, $numberToDisplay,
$itemTitleLength, $itemReviewLength): ShortcodeAttribute {
中略
$shortcodeAttribute = new ShortcodeAttribute ();
$shortcodeAttribute->setOperation ( $operation );
$shortcodeAttribute->setSearchIndex ( $searchIndex );
$shortcodeAttribute->setKeyword ( $keyword );
$shortcodeAttribute->setNumberToDisplay ( $numberToDisplay );
$shortcodeAttribute->setItemTitleLength ( $itemTitleLength );
$shortcodeAttribute->setItemReviewLength ( $itemReviewLength );
return $shortcodeAttribute;
}
以下省略
上記ソースコードのmakeShortcodeAttribute()関数は、ShortcodeAttributeクラスのインスタンスを作成します。
ショートコードの各属性の値が、ShortcodeAttributeクラスのインスタンス変数$shortcodeAttributeに対して、設定されます。
例えば、以下のショートコードの場合、
[goodsmemo_affiliate service="amazon" keyword="WordPress 開発" number="1"]
ShortcodeAttributeクラスのインスタンス変数$shortcodeAttributeには、以下の値が設定されます。
$shortcodeAttribute->setKeyword()に、"WordPress 開発"が設定される。
$shortcodeAttribute->setNumberToDisplay()に、1が設定される。
最後に、インスタンス変数$shortcodeAttributeは、return文によって返されます。
※関連記事:アフィリエイト商品表示・WordPressプラグイン、ショートコードの属性
特定の対象に関する処理を集めたクラス、ユーティリティクラス
Java言語でプログラミングしていた時期から、ユーティリティクラスを利用するようになりました。
ユーティリティクラスとは、ざっくり言うと、特定の対象に関する処理を集めたクラスです。
ShortcodeAttributeUtilsクラスの場合、ショートコードの属性に関する処理だけを集めたクラスになります。
ユーティリティクラスは、 staticメソッドだけがあります。
ユーティリティクラスのインスタンスを、作ることはありません。
例えば
$utl = new Utils();
という使い方はしません。
今後のプログラミングにおいて、もしもショートコードの属性に関する処理を新規作成する場合、
ShortcodeAttributeUtilsクラスに対して、メソッドを新規作成することになります。
ショートコードの属性に関する処理は、ShortcodeAttributeUtilsクラスにだけ存在しています。
よって、全てのソースコードの中から、ショートコードの属性に関する処理を見つけやすくなっています。
特定の処理を見つけやすいソースコードは、わかりやすいソースコードにつながります。
data, process, utilityという役割に分けて、クラスを作るプログラミング
たぶん1998年頃に、Javaのクラス設計に関するウェブサイトの記事を読んでいました。
どこかのソフトウェア開発会社のウェブサイトの記事だった、と思います。
そのソフトウェア会社の社員の方が、当時、Java World雑誌に連載記事を執筆していました。
そのウェブサイトの記事では、Javaのクラスを
- データ
- プロセス
- ユーティリティ
という三つの役割に分けて作成しましょう、と解説されていました。
その当時、オブジェクト指向やクラスを使用するプログラミングについて、よくわからない点がありました。
なので一時期、クラスに対して、データ、プロセス、ユーティリティという役割を与えて、プログラミングしていました。
その時の影響によって、ワードプレスプラグインを作成するPHPプログラミングにおいても、ユーティリティクラスを作っています。
ちなみに、ユーティリティクラスについてネットで調べたところ、
ユーティリティクラスを使ってはいけない、という意見がありました。
もしかしたら近年のオブジェクト指向プログラミングでは、ユーティリティクラスを使用しないのかもしれません。
業務データ、業務フロー、業務フローで利用する処理みたいな感じ?
あと、先ほどのデータ、プロセス、ユーティリティという役割について、ざっくり言うと、
- データは、業務データ
- プロセスは、業務フロー
- ユーティリティーは、業務フローで利用する処理
みたいな感じだった、と思います。
Webアプリケーションのログイン処理で言うと、
LoginDataクラスで、ユーザーのIDやパスワードというデータを保持します。
LoginProcessクラスでは、ユーザーのIDやパスワードを検査して、正しいユーザーなら次の画面に遷移する処理をします。
LoginUtilsクラスでは、ユーザーのログイン処理に関係ある処理、
例えば、パスワードが正しいかどうかを判断するstaticメソッドなどを、用意します。
なお、LoginUtilsクラスのようなユーティリティクラスは、作成不要となる場合もありました。
必ず存在するクラスというわけでは、ないようです。
クラスのインスタンスを作るなら、makeでなくcreateが良いらしいです
makeShortcodeAttribute()関数では、ShortcodeAttributeクラスのインスタンスを作成します。
この記事を書いている時、プログラミングにおけるmakeとcreateの違いについて、ネット記事をちょっと調べてみました。
クラスのインスタンスを作るなら、makeでなくcreateが良いらしいです。
その意見を参考にすると、createShortcodeAttribute()関数というメソッド名が良いことになります。
createの意味は、創造する。何もないところから生み出す。
makeの意味は、材料から作り出す。
上記の意味を参考にしたら、
$shortcodeAttribute = new ShortcodeAttribute ();
このようにインスタンスを作るのは、クリエイトすることになるようです。
今まで、makeとcreateの使い分けを意識せずにプログラムを記述してきました。
過去に記述したソースコードについては、makeやcreateに関する修正を諦めました。時間と負担がかかるからです。
必須項目だから、ショートコードの検索キーワード属性が存在するか、確認する
if (trim ( $keyword ) === "") { // 0と””を区別するには ===(厳密な比較) を使います。
throw new IllegalArgumentException ( "検索キーワードが空です:[" . $keyword . "] number:[" . $numberToDisplay . "]" );
}
ショートコードの検索キーワード属性は、必須項目です。
なので、キーワード文字列が存在するか、確認します。
検索キーワードがない場合、アフィリエイト商品を表示するHTMLを作れないからです。
ショートコードの検索キーワード属性が未指定の場合、
検索キーワードが空文字です、という例外を通知しています。
比較演算子 === について、当初、よくわかりませんでした…
上記ソースコードのif文では、厳密な比較を行う比較演算子 === を用いて、空文字の判定をしています。
このイコール文字が三つ連なる演算子について、当初、よくわかりませんでした。
PHPでif文の条件文を書くのは、なんだか難しい、と今でもたまに思います。
任意項目だから、ショートコードの「商品名の表示文字数」属性が空文字なら、次の処理に移る
if (trim ( $keyword ) === "") { // 0と””を区別するには ===(厳密な比較) を使います。
throw new IllegalArgumentException ( "検索キーワードが空です:[" . $keyword . "] number:[" . $numberToDisplay . "]" );
}
if (trim ( $itemTitleLength ) === "") { // 0と””を区別するには ===(厳密な比較) を使います。
; // 任意指定の属性なので、正しい
} else {
ShortcodeAttributeUtils::isZeroOrMore ( $itemTitleLength, "無効な商品名の表示文字数" );
}
ショートコードの「商品名の表示文字数」属性は、任意項目です。
なので、$itemTitleLength変数が空文字であることは、未設定を意味します。
これは正しいです。
$itemTitleLength変数が空文字である場合、
何もせず、商品名の表示文字数が0以上か検査せず、次の処理に移ります。
if文では、肯定的な条件分岐を優先する書き方をしています
$itemTitleLength変数に関するif文では、肯定的な条件分岐を優先する書き方をしています。
肯定的な条件が成り立った場合、何もしません。
よって、; セミコロンだけ記述しています。
無駄と思える ; セミコロンを記述するわけは、
if文の条件において、「何々である」と、肯定文で条件を判断したいからです。
「何々でない」という否定文で条件を判断するのは、ちょっとわかりにくいです。
なので使いたくない、と考えています。
※関連記事:Javaソースコードにおいて、if文で肯定的な条件分岐を優先する書き方。
表示する商品数や文字数が0以上か、検査する
private static function isZeroOrMore($valueText, string $errorMessage) {
if (is_numeric ( $valueText ) && $valueText >= 0) { // ゼロ以上とした
; // is関数だから、本来は return true;。以下で例外通知しているので、何もしないことにした。
} else {
throw new IllegalArgumentException ( $errorMessage . ":" . $valueText ); // 本来は、return false;
}
}
isZeroOrMore()関数は、引数の$valueText変数が0以上か、検査します。
$valueText変数が0以上の数字でない場合、例外を通知します。
引数の$valueText変数の中身は、以下のショートコードの属性です。
- 表示する商品数
- 商品名の表示文字数
- 商品説明の表示文字数
Boolean型の値を返さないのに、 isから始まるメソッド名になっていました
isZeroOrMore()関数については、初めの頃、Boolean型の値を返す関数でした。
ですが、false値を返す場合に例外を通知することに仕様変更したので、Boolean型の値を返さない関数になりました。
このように仕様変更したため、メソッドの名前も変えるべきだったかもしれません。
例えば、isの代わりにcheckを使った名前にした方が、良いかもしれません。
メソッド名に、checkを使った名前の例。
checkZeroOrMore()関数。
ShortcodeAttributeUtils.phpのソースコード
<?php
namespace goodsmemo\shortcode;
use goodsmemo\exception\IllegalArgumentException;
require_once GOODS_MEMO_DIR . "exception/IllegalArgumentException.php";
class ShortcodeAttributeUtils {
public static function makeShortcodeAttribute($operation, $searchIndex, $keyword, $numberToDisplay, $itemTitleLength, $itemReviewLength): ShortcodeAttribute {
ShortcodeAttributeUtils::isZeroOrMore ( $numberToDisplay, "無効な表示件数" );
if (trim ( $keyword ) === "") { // 0と””を区別するには ===(厳密な比較) を使います。
throw new IllegalArgumentException ( "検索キーワードが空です:[" . $keyword . "] number:[" . $numberToDisplay . "]" );
}
if (trim ( $itemTitleLength ) === "") { // 0と””を区別するには ===(厳密な比較) を使います。
; // 任意指定の属性なので、正しい
} else {
ShortcodeAttributeUtils::isZeroOrMore ( $itemTitleLength, "無効な商品名の表示文字数" );
}
if (trim ( $itemReviewLength ) === "") { // 0と””を区別するには ===(厳密な比較) を使います。
; // 任意指定の属性なので、正しい
} else {
ShortcodeAttributeUtils::isZeroOrMore ( $itemReviewLength, "無効な商品説明の表示文字数" );
}
$shortcodeAttribute = new ShortcodeAttribute ();
$shortcodeAttribute->setOperation ( $operation );
$shortcodeAttribute->setSearchIndex ( $searchIndex );
$shortcodeAttribute->setKeyword ( $keyword );
$shortcodeAttribute->setNumberToDisplay ( $numberToDisplay );
$shortcodeAttribute->setItemTitleLength ( $itemTitleLength );
$shortcodeAttribute->setItemReviewLength ( $itemReviewLength );
return $shortcodeAttribute;
}
private static function isZeroOrMore($valueText, string $errorMessage) {
if (is_numeric ( $valueText ) && $valueText >= 0) { // ゼロ以上とした
; // is関数だから、本来は return true;。以下で例外通知しているので、何もしないことにした。
} else {
throw new IllegalArgumentException ( $errorMessage . ":" . $valueText ); // 本来は、return false;
}
}
}