信頼はずっと、挑戦はもっと。

お問い合わせ
TEL:03-3496-3888

BLOG コアテックの社員ブログ (毎週月曜~金曜更新中)

LIST OF ARTICLES

記事一覧

  • 画像:ブログサムネイル

    テクログ

    オブジェクト指向は因数分解だ!!

    どうも!先月に入社二年目を迎え、とうとうパイセンと化したわいです。自粛期間中ということで、かなり暇なので長編に挑みます。暇な人はぜひ最後まで読んでみてください。「うわあ、暇だあ…」ってより実感すると思います。今回、またもやプログラミングを他の概念にこじつけるシリーズです。この一年間、新人プログラマーとしていろいろ苦戦しました。その中のひとつが、『オブジェクト指向とは』の理解です。オブジェクト指向に関する記事はたくさんあります。それこそ、「オブジェクト指向はもう古い」とされていたりします。ただ温故知新という言葉があるように、オブジェクト指向について学ぶことは決して意味のないことではないと思います。むしろ、プログラミングをする上での基本的な考え方が詰まっているように思えます。詳しく、そして正確に知りたい場合は、他の記事をおすすめします。https://www.google.com/search?q=%E3%82%AA%E3%83%96%E3%82%B8%E3%82%A7%E3%82%AF%E3%83%88%E6%8C%87%E5%90%91%E3%81%A8%E3%81%AF今回はオブジェクト指向のイメージを掴むために少しでもお役に立てればと思い、あえて変な角度からアプローチしてみます。その名も、「オブジェクト指向は因数分解だ!!」です。因数分解とは、「足し算・引き算で表されている数式をかけ算の形に変形する」ことです。例えば、cx^2+acx+bcx+abc = (x+a)(x+b)c となります。(中学数学でやりましたね?)ここで、下図のようなWebページについて考えてみましょう。(私自身、最初に車の例えを見たときピンとこなかったので…)犬の情報は、売られている犬がリストで表示されているとします。猫も同様です。店舗の情報は、住所、電話番号などが表示されているとしましょう。(ちなみに、私はペットショップに行くと悲しい気持ちになるので、基本的に中には入りません)かなり簡略化しているのでわかりやすいと思いますが、ペットショップのWebサイト = 犬の情報 × 猫の情報 × 店舗の情報という式が成り立つはずです。複雑なWebサイトでもこのように各パーツの組み合わせで成り立っています。これを先ほどの因数分解と合わせて考えてみます。ペットショップのWebサイト= cx^2+acx+bcx+abc (一見複雑だが…)=  (x+a)  ×  (x+b)  ×  c = 犬の情報 × 猫の情報 × 店舗の情報このようにWebサイトを因数分解することができました。「だから、なんだ?」という話なのですが、ここでオブジェクト指向について考えたいと思います。なぜわざわざ小難しいオブジェクト指向で書くかというと、それは変更に対して柔軟に対応するためです。どういうことかというと、「爬虫類も売ることにしたから、サイトに爬虫類の情報も表示したい」や、「犬を売るのをやめて、鳥を売ることにしたから変えてくれ」などという要望に、瞬時にそしてバグを出すことなく対応することがオブジェクト指向を用いると容易になるということです。適切にオブジェクト指向を使えば、似たような機能の追加が容易になり(再利用性)、たった一か所の変更のために他のパーツにバグが出ていないかページ全体をテストし直す必要がありません(疎結合性)。しかし、このオブジェクト指向の難しいところはどのように機能(クラス)を分割するかというところにあると思います。大雑把に分割しても効力は発揮しないし、かといって細かすぎても保守が大変になります。ここで、今回私が提案するのは「因数分解のように考えてみたら意外と上手くいくんじゃね?w」ってやつです。まず、「犬の情報」を「鳥の情報」に変えるということを因数分解で見てみましょう。これは、仮に a → d とすることで実現するとします。そうすると、ペットショップのWebサイト=  (x+d)  ×  (x+b)  ×  c = 鳥の情報 × 猫の情報 × 店舗の情報となり、(x+b)やc の値に何ら影響を与えることなく変更することが出来ました。ここで勘のいい人は、「おめえさん、x を変えたら『猫の情報 (x+b)』に影響を与えるだら?」と思うかもしれません。そうです。そして、この x がオブジェクト指向の要です。「犬の情報」も「猫の情報」も、『売られている動物がリストで表示される』という共通点があります。この共通点を規格として、インターフェースや抽象クラスにまとめ上げることで再利用性が高まり、さらに各々のクラスの役割がはっきりします。そして、ここで注意しないといけないのがなんでもかんでもこの x にまとめてしまうことです。各ペットの情報欄に年齢や性別のほかに、仮に「1日に〇回散歩に行かないといけない」という項目があったとします。これを x にまとめてしまうと『犬の情報 (x+a)』ではいいんですが、関係のない『猫の情報 (x+b)』に影響を与えてしまいます。だから、この場合は各ペットの情報欄の項目までは共通化せず、『売られている動物がリストで表示される』という根本機能だけを共通化することがいいように思えます。(犬と猫だけだと差異がわかりにくいですが、変わった動物を追加するとなると変な項目も増えそうです)かといって、ペットショップのWebサイトということなので、『売られている動物がリストで表示される』という機能の共通化を疑う必要はないでしょう。それだと、オブジェクト指向の意味がなくなります。次に、f(a) = x+a とすると、ペットショップのWebサイト=  f(a)  ×  f(b)  ×  c = 犬の情報 × 猫の情報 × 店舗の情報となり、 犬(a)  や  猫(b)  を f に与えるだけで欲しい情報が得られるということです。この f こそが、『売られている動物をリストで表示する』という機能であり、インターフェースです。この『動物』という抽象に対してプログラミングしていくことが、ポリモーフィズムです。最後に、カプセル化について考えます。f はインターフェースや抽象クラスで、 f(a) は『売られている犬をリストで表示する』という具象クラスです。実際にペットショップのWebサイトを構築する際は、この f(a) を使います。そして、この f(a) を利用するとき、『売られている犬をリストで表示する』という具象クラスであるということだけを知っていればよくて、f(a) = x+a だという具体的な中身を知っている必要は全くありません。実は、『売られている犬を「人気順に」リストで表示する』ということをやっていて、中身が f(a) = 3x+1+a と多少複雑になっているかもしれません。ただ、このように具体的な中身を知らずとも、 f(a) を使えばWebサイトは構築できます。クラスを外部から利用するとき、 f(a) のような簡素な見た目で提供し、影響範囲をクラス内にとどめておくことをカプセル化といいます。いかがでしたか?「オブジェクト指向は因数分解だ!!」理論は。あなたのソース、c(x^2+ax+bx+ab) や x^2(1+a/x)(1+b/x)c になっていないでしょうか?「うわあ、暇だあ…」最後まで読んでくださり、私としてはうれしい限りですが、相当お暇なんですね。なにか自粛期間にできる趣味をお探しになることをお勧めします。以上、わいでした。健闘を祈る!!
  • テクログ

    LINE Notify APIを試してみました

    初めまして。1月からお世話になっておりますJGです。最近LINE Notify APIを使い、毎朝自分のLINEに通知させました。それについて触れたいと思います。下記URLからLineIDでログインし、必要事項を入力します。その後、アクセストークン発行をクリックし、発行されたトークンをコピーして保存してください。https://notify-bot.line.me/ja/天気予報を取得する処理は下記のlivedoorを使用しました。http://weather.livedoor.com/weather_hacks/webservicePHPで処理を書き、作成したものをHerokuに上げ、毎朝通知するようにHerokuのスケジューラを設定しました。下記ソースのTOKENに、LINEのアクセストークンを指定すれば動きます。自分の住んでいる東京と出身地の神奈川の天気を通知するために、$city_listを下記のように指定しています。興味がある方は、是非試してみてください。<?php define('TOKEN', ''); define('MESSAGE_NOTIFY_API_URL', 'https://notify-api.line.me/api/notify'); define('WEATHER_API_URL', 'http://weather.livedoor.com/forecast/webservice/json/v1?city='); $city_list = [   130010,   140010,   140020 ]; foreach ($city_list as $city) {   //天気予報を取得   $weather_data = get_weather_data($city);   if (empty($weather_data)) {     $msg = "天気予報取得失敗です。";   } else {     //通知メッセージを作成     $msg = create_message($weather_data);   }   //通知   send_msg($msg); }   function get_weather_data($city) {   $ch = curl_init();   curl_setopt($ch, CURLOPT_URL, WEATHER_API_URL.$city);   curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'GET');   curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);   $response = curl_exec($ch);   $http_code = curl_getinfo($ch, CURLINFO_RESPONSE_CODE);   if ($http_code != 200) {     return false;   }   if (curl_error($ch)) {     return false;   }   $weather_data = json_decode($response, true);   curl_close($ch);   return $weather_data; } function create_message($arr) {   $msg = '';   $title = $arr['title'] ?? '';   $msg .= $title."\n\n";   for ($i = 0; $i < 2; $i++) {     $date = $arr['forecasts'][$i]['date'] ?? '';     $date_label = $arr['forecasts'][$i]['dateLabel'] ?? '';     $weather = $arr['forecasts'][$i]['image']['title'] ?? '';     $min = $arr['forecasts'][$i]['temperature']['min']['celsius'] ?? '';     $max = $arr['forecasts'][$i]['temperature']['max']['celsius'] ?? '';     $msg .= $date_label.'('.$date.')'."\n";     $msg .= '天気: '.$weather."\n";     $msg .= '最高気温: '.$max."\n";     $msg .= '最低気温: '.$min;     if ($i < 1) {       $msg .= "\n\n";     }   }   return $msg; } function send_msg($msg) {   $post_data = http_build_query(['message' => $msg]);   $ch = curl_init(MESSAGE_NOTIFY_API_URL);   curl_setopt($ch, CURLOPT_POST, true);   curl_setopt($ch, CURLOPT_POSTFIELDS, $post_data);   curl_setopt($ch, CURLOPT_HTTPHEADER, [     'Content-Type: application/x-www-form-urlencoded',     'Authorization: Bearer '.TOKEN,     'Content-Length: '.strlen($post_data)   ]);   curl_exec($ch);   $http_code = curl_getinfo($ch, CURLINFO_RESPONSE_CODE);   if ($http_code != 200) {     return false;   }   if (curl_error($ch)) {     return false;   }   curl_close($ch);   return true; }
  • テクログ

    RESTAPIの社内勉強会

    つい昨日RESTAPIの勉強会があり参加しました!チャットボット導入の際に開発したとのことで導入の際に注意したことや必要になったことなど実際の業務で使ったポイントだったので具体的で分かりやすかったです。RESTの発表会とのことでしたが個人的には認証まわりの話がかなりためになりました。アクセストークンを使用した認証についてもある程度理解が深まったし業務時間中の勉強会だったのでいい息抜きになったしでかなり有意義な勉強会だったと思います!発表者の方ありがとうございますSPAなども増えてるのでWEBサイト開発でもRESTAPIの知識は必要になりますね個人的にも勉強するようにします!クライアント側の話もあったらまた勉強会参加したいです
  • テクログ

    cURLのメモリリーク

    こんにちは、kaiです。最近新作ゲームをプレイ中に自宅PCのメモリ使用率が95%まで上がったことがあって(windows defenderの問題でした)、メモリリークって怖いな…と思う今日この頃ですが、それに関連して今回は担当していた案件で遭遇した問題について紹介します。取得したURLにPHPのcURL関数を用いてアクセスするプログラムを作成したところ、実行中、時間を追うごとにサーバーのメモリ消費量が増大していく現象が発生しました。プログラム側ではスタックし続けるような処理を実装していないので、調査したところ、curlの古いバージョンにはキャッシュを蓄積し続けるバグが存在しておりプログラム実行中にはメモリが解放されずに消費されていくことが分かりました。そこで暫定の対応ではありますが、curl利用部分を個別のプログラムとして切り出し、そこにURLを分割して渡すことでメモリ消費を抑える形に改修しました。追々バージョンアップや別の方法に変えたいところですね…まだ記事作成時点でテスト中ですが、結果や追加対応などはまた報告できればと。外部要因の不具合はなかなか出くわさなかったので個人的には良い経験になったと思います。ではまた。・参考URLhttps://qiita.com/digitalpeak/items/4b39fdcb8fae7d09f406https://blog.eviry.com/entry/2019/07/23/160715_1
  • 画像:ブログサムネイル

    テクログ

    NetBeansを使ってのちょっとした便利機能

    お久しぶりです。まーくんです。複数のプロジェクトファイルを同時並行で開いていると、どのファイルがどのプロジェクトのかわからなくなることありませんか。まーくんは最近ありました。その時に便利なNetBeansの便利な機能があったので紹介します。▼デフォルトの状態だとこんな感じの横一列(別々のプロジェクトで1ファイルを開いている状態)▼便利な機能を使うとこんな感じでそれぞれのプロジェクトごとに複数行でファイルがわかれてくる。やり方はツールタブ→オプションのモーダルを開く→外観選択→複数行タブにチャック→1プロジェクトにチェック→ついでに同じプロジェクトのファイルと同じ背景色を選択をするだけ。これだけでとてもみやすくなるので、ぜひ試してみてください。
  • テクログ

    FuelPHPでのクーロンログ

    FuelでのログはView側では、大本(言い方)try {} catch () {}でくくられているため、基本全てのエラーが吐き出されるようになっています。そして、タスク(cron)実行する際にもログが出てほしいな~と思い、調べた結果です。タスクの場合Fuelの本体とは別のロジックとなっており、ログに吐き出すようにするには、コーダーさんが処理内にtry {} catch () {}などでくくらなければエラーを明示的に吐き出すことができませんでした。(なぜ・・・)参考サイトとしてリンクを貼りますが(https://qiita.com/notona/items/b821ed0ad04ac3ef8f80)以下のようなことが書かれておりました~~~~~php7 では一部のエラーが Error例外 として throw されるようになりました。そのため Error と ErrorException がどちらも実装しているインターフェースになっている Throwable でキャッチする~~~~~ざっくりいうと、エラーを拾う(出力させる)ためには、タスク処理をごっそりと「try {} catch (\Throwable $e) {}」でくくる必要がある。もしくは、エラー出力としcronに設定する際に0 0 1 * * [php path] [oil path] refine [task name] 2>> [output file name]`date +\%Y\%m\%d`.logのように、cronを設定する必要がある(この場合は try {} catch () {}の必要はない)ただ、oil深くまで潜ると。。。。ありました!!エラー時には、コンソールに表示させる記述が。こいつを、オーバライドして、ログに吐き出されるようにすれば、タスクが実行されて、try {} catch () {}でくくらなくても、うまくいく(はず)※やって見る方は自己責任でお願いします。