レガシーコードも年末に向けて大掃除! - jMockitを使おう

さて、今年もあと僅かになりましたが、この1年間で溜まりに溜まったコードの負債を大掃除してみませんか?

レガシーコードだから書くのが大変? プロダクト側を改修したいけどそもそもテストが無いから改修が怖い? ですよねー。 なのでjMockitを使って既存のコードにテストを書く方法を紹介します。

まず、想定するレガシーコードですが検証したいメソッドの内部で現在時刻を取得してるケースを考えます。 普通にクラスやメソッドから日付をインジェクションできるように作るのが正しいコードですが、結構ありがちなのがこんなコード。

    public class MyCalendar {
        public Date nextDay() {
            Calendar calendar = SystemDate.getDate();
            calendar.add(Calendar.DATE, 1);
            return calendar.getTime();
        }
    }

SystemDateは検証環境なんかで結合テストしやすいように、設定ファイルやDBの値を読み込むことが多いでしょうけど、今回はシンプルに現在時刻だけ。

    public class SystemDate {
        public static Calendar getDate() {
            return Calendar.getInstance();
        }
    }

このようなケースでMyCalendar#nextDayにテストを書こうとしても日付が変更出来ないので、月またぎや年またぎ、うるう年のテストが出来ません。検証環境にデプロイして何らかの方法でシステム日付を変更し、手でポチポチと検証しながら画面のスクリーンショットを取る簡単なお仕事が待っていそうですね。

ユニットテストをする気がちっとも無い素敵な感じですが、残念なことにしばしば見かけるタイプのコードです。

jMockitを使うことで、こんな残念な設計に対しても、比較的低コストでUTを書くことが可能です。

    public class MyCalendarTest {

        String $(Date date) {
            SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd");
            return df.format(date);
        }

        Calendar getCalendar(int y, int m, int d) {
            Calendar cal = Calendar.getInstance();
            cal.set(y, m - 1, d);
            return cal;
        }

        @Test
        public void test01() {
            new Expectations() {
                @Mocked
                SystemDate systemDate;

                {
                    SystemDate.getDate();
                    result = getCalendar(2013, 12, 13);
                    result = getCalendar(2013, 12, 31);
                    result = getCalendar(2013, 12, 13);
                }
            };

            MyCalendar myCalendar = new MyCalendar();
            assertThat($(myCalendar.nextDay()), is("2013-12-14"));
            assertThat($(myCalendar.nextDay()), is("2014-01-01"));
            assertThat($(myCalendar.nextDay()), is("2013-12-14"));
        }
    }

Expectationsブロックの中にMockとして戻り値を差し替えたい内容を記述します。 MyCalendar#nextDay()の中で利用される"SystemDate.getDate()"の戻り値は直下に記載したresultのものに差し替えられます。 今回はstaticメソッドを置き換えましたが、もちろん同様にインスタンスメソッドも置き換え可能です。

また、重要なのはこれがクラス全てではなく部分差し替えとなっていることです。 これにより、対象クラス全体の振る舞いを書き直す手間やリスク無く、モックを作成することが可能です。

ちなみにこのコードで

    MyCalendar myCalendar = new MyCalendar();
    assertThat($(myCalendar.nextDay()), is("2013-12-14"));
    assertThat($(myCalendar.nextDay()), is("2014-01-01"));
    assertThat($(myCalendar.nextDay()), is("2013-12-14"));
    assertThat($(myCalendar.nextDay()), is("2013-12-14"));

とすると

    mockit.internal.UnexpectedInvocation: Unexpected invocation of:
    SystemDate#getDate()

という例外が発生してテストが失敗します。これは、resultの数以上呼び出されるのは期待値と異なるためです。 差し替える値自体は固定で良いが複数回呼びたいケースというのもありますよね? その場合にはExpectaionsの代わりにNonStrictExpectationsを使うことで解決します。

       @Test
        public void test01() {
            new NonStrictExpectations() {
                @Mocked
                SystemDate systemDate;

                {
                    SystemDate.getDate();
                    result = getCalendar(2013, 12, 13);
                    result = getCalendar(2013, 12, 31);
                    result = getCalendar(2013, 12, 13);
                }
            };

            MyCalendar myCalendar = new MyCalendar();
            assertThat($(myCalendar.nextDay()), is("2013-12-14"));
            assertThat($(myCalendar.nextDay()), is("2014-01-01"));
            assertThat($(myCalendar.nextDay()), is("2013-12-14"));

            // 最後のresultとinstanceが同じなので12/14の更に翌日になる
            assertThat($(myCalendar.nextDay()), is("2013-12-15"));
        }

ね、簡単でしょ? これで、今まで初期化が大変過ぎて二の足を踏んでいたコード群にもガンガンテストを書いていくことが出来ます。 それではみなさんも良い年末を! Happy Hacking!

参考:

Keynote風のプレゼンテーションをMarkdownで作ってみた

最近ちょっと英語の練習がてら上のような英語プレゼンを作ろうと思い立ちました。 目的なく写経的なの苦手なので、目的作る方式。

ただ、OpenOfficeなりKeynoteなりPowerPointなりで毎回作るのも面倒だし、JS系のプレゼンツールだとslideshareに上げれないし、良い方法無いかな、と調べてみることに。 Markdown + pandocでの変換が一番自分の好みにマッチしたので、そのやり方を記載します。 以下、内容的には上のプレゼン資料の和訳 + α。そこ、αが多いとか言っちゃダメですよ?

PowerPointKeynoteじゃダメなの?

どちらもめちゃくちゃいいツールですが、ちょっと問題があります。

  1. 同じレイアウトにするのがめんどい
  2. オフィスアプリケーションが必要.
  3. バイナリフォーマット。gitやSVNとの相性が残念

まず1ですがテンプレートを使っても少し面倒です。ブラウザや別なエディタからコピペしようものならそこだけフォントが変わるとかザラですね。 あと、GUI系のエディタだと自分の場合どうしても見た目指向になりがちで、論理構造が変になったりしてる時があるので、あとからスタイル切り替えで苦しみます><

続いて2なんですが、当たり前ですが編集にオフィス系アプリが必要です。立ち上げるのがめんどいのです。エディタが好きなのです。

最後に3。実はコレが一番大きくてまっとうな理由。バージョン管理しづらいんですよね。バイナリフォーマットなので。 修正の差分がわからないです。プラグインとか入れまくればなんとかなるかもですが、ちょっとねえ?

そこでMarkdown + Pandoc

Markdown と Pandocの簡単な説明はこんな感じ。

Markdown

  • シンプルテキストフォーマット。だからgitとの相性もバッチリ!
  • 人間が簡単に読める、そして書ける!
  • HTML風のシンプルな論理文章構造を提供

Pandoc

  • マルチドキュメントトランスレータ(HTML, PDF, docx, markdown, LaTex, reStructuredText...)
  • Markdownからスライドを作成可能
  • しかもs5とかHTML形式のものだけではなく、PDFにできる

大変自分のニーズにあっております。特にMarkdownはgithubとかでも人気ですし、資料が多いのが良い所。 wiki記法みたいなもんですが、謎の方言よりある程度標準化されてるのが良いですね。pandocは他にもwordとかにも変換できるので、マニュアル作りとか社内資料に便利そうです。

なにはともあれ使い方

インストール Pandoc.

こちらの公式から落とせます。linux系の場合は各種パッケージマネージャですかね。 haskellのパッケージ管理ツール入れてやるのも良いかもです。 http://code.google.com/p/pandoc/downloads/

PDF用にTexのインストール

PDFの作成はTex経由で行っているのでインストールが必要です。なんか色々モジュールが居るみたいですが、MacならMacTex入れれば全部揃うようです。http://tug.org/mactex/

Run コマンド

$ pandoc -t beamer test.md -o test.pdf

ね、簡単でしょ? 実行するとこんな感じのスライドが出来ます。

f:id:pascal256:20131028190551p:plain

カスタマイズ

 

テンプレートの適用

ちゃんと、スライドが出来たのは良いですが、ちょっとシンプル過ぎですね。というか気に入らないです(ぉ というわけでKeynoteのグラデーション風の奴に変更しようと思います。 まずは、Texのカスタムスタイルをダウンロード。幸い、同じようなことをしてる人がすでにいらっしゃったので、こちらを使わせてもらいます。 beamerthemeKeynoteLikeGradient.sty.

で、ダウンロードできたら、そのファイルを下記ディレクトリにコピーします。MacTex以外を入れてる方は適宜読み替えで。

$ sudo cp ./beamerthemeKeynoteLikeGradient.sty /usr/local/texlive/2013/texmf-dist/tex/latex/beamer/themes/theme/

次に、インデックス情報の更新です。残念ながらこれだけだと、テンプレートを指定しても見つからないと怒られれます。 おそらく適切な更新方法があるのですが、良くわからなかったので、直接「Tex Live Utility」を起動して、適当なパッケージを再インストールしてインデックスを更新するという荒業にw 誰か、やり方ご存知でしたら教えて下さい。

テンプレートの指定は下記のように "-V theme:"で指定します。これで、晴れてkeynote風のデザインに。

$ pandoc -V theme:KeynoteLikeGradient -t beamer test.md -o test.pdf

コードブロックのカスタマイズ

この状態だとコードブロックが背景色が透明なため少し見づらいです。そのため、ちょっとカスタマイズしたいと思います。この変換の仕組みは裏側はTexなんですが、Texでコードを綺麗に出すためにはlistingというモジュールを使うようです。

$ pandoc --listings -t beamer test.md -o test.pdf

これで、コードブロックがlistingになります。なるんですが、このままだとカスタマイズされて無くて特に見た目変わらないんで、下記のようにヘッダーにフォーマットをしています。 ここにフォント種類やサイズ、背景色やラインもろもろを記載することが出来ます。ヘッダーの書き方はこんな感じ。

\usepackage{listings}
\lstset{%
 %language={sh},
 backgroundcolor={\color[rgb]{0.1, 0.1, 0.1}},%
 basicstyle=\footnotesize,%
 commentstyle=\textit,%
 classoffset=1,%
 keywordstyle=\bfseries,%
 frame=tRBl,framesep=5pt,%
 breaklines=true,
 showstringspaces=false,%
 %numbers=left,stepnumber=1,numberstyle=\footnotesize%
}

利用するには "-H"オプションを使います。

$ pandoc -H header.tex --listings -t beamer test.md -o test.pdf

これでいい感じに出力されました。

まとめ

MarkdownとPandocはシンプルな典型的なプレゼン資料を作るのに向いています。 派手な見た目や画像の多様をした資料を作りたい時はPowerPoitとかKeynoteが確実に良いです。 ただ、おんなじような紋切型で文字多めドキュメントの時は軽量なMarkdown + Pandocはかなり有りです。

今回作成したサンプルはこちら。下記コマンドで冒頭のプレゼン資料が出来上がります。

$ pandoc --listings -H header.tex -V theme:KeynoteLikeGradient -t beamer test.md -o test.pdf

今後の課題としては画面いっぱいのデカ文字とか結構多用するので、その辺の作り方ですね。あと、コマンド毎回打つのも面倒なので、rakeベースのFWというかテンプレートを作ってみました。 それはこちらにおいてあります。良ければ試してみてください。

それでは、Happy Hacking!

参考:

電子書籍ストアのランキングを比較したよ[Book☆Walker, Kindle, Kobo]

ふと思い立って、電子書籍ストアのランキングを比較してみたら、それなりにカラーが違って面白かったのでブログにまとめてみる。

 

まずは、Book☆Walker。最近大合併したKADOKAWAの直轄ストアだけあって、やはり萌系が多い。

新刊や、アニメ化した作品がランキング反映されてる感じなので、わかりやすいですね。

一般書籍も売れてるとのことでしたが、ランキング見る限りはやはり消費者としてはアニメイト的な専門店の位置づけっぽいです。

Book☆Walker

1 ハイスクールD×D16 課外授業のデイウォーカー ¥600
2 週刊アスキー 2013年 10/29号 ¥350
3 新約 とある魔術の禁書目録(8) ¥683
4 週刊ファミ通 2013年10月31日号 ¥350
5 艦これ白書 -艦隊これくしょん オフィシャルブック- ¥1,995
6 東京レイヴンズ10 BEGINS/TEMPLE ¥600
7 艦隊これくしょん -艦これ- 鎮守府生活のすゝめ Vol.1 ¥600
8 おまえをオタクにしてやるから、俺をリア充にしてくれ!8 ¥600
9 落第騎士の英雄譚<キャバルリィ> 【電子特装版】 ¥473
10 ストライク・ザ・ブラッド1 聖者の右腕 ¥599
平均単価   ¥685

 

続いてKobo。文芸作品というか一般作品が多いですね。漫画ランキングとかも見てみたんですが、進撃の巨人が多かったです。同じ漫画というジャンルに絞っても、Book☆Walkerとは明らかに違う傾向ですね。

楽天Kobo

1 ロスジェネの逆襲 ¥1,200
2 キングダム 31 ¥368
3 マリアビートル ¥740
4 成功者に学ぶ時間術 ¥99
5 東京喰種トーキョーグール[JACK] ¥100
6 人生がときめく片づけの魔法 ¥762
7 あなたの仕事に革命を起こす!「つたえることリスト」 ¥100
8 オレたちバブル入行組 ¥690
9 宮本武蔵 完全版 ¥100
10 人類資金IV ¥525
平均単価   ¥468

 

KindleKoboと同じような傾向に見えますが、小説よりもビジネス書が多いですね。

なんとなく意識高い系?の社会人が使ってそうなラインナップですね。

Amazon Kindle

1 下半身で覚えるビジネス英会話-下ネタは世界の共通語!- (ビジネスファミ通) ¥95
2 ソニーをダメにした「普通」という病 ¥200
3 種まきガールズコレクション ¥300
4 宮本武蔵 完全版 ¥350
5 あなたの仕事に革命を起こす!「つたえることリスト」 ¥200
6 人類資金IV (講談社文庫) ¥525
7 仕事ができる人できない人 ―「あの人はできる!」と納得させる20のルール ¥200
8 しゃべれないあなたは悪くない! 英語力が伸びるホントの方法 ¥200
9 20代は勉強に狂いなさい! ¥300
10 30分で一流の仕事をマスターする方法 ¥200
平均単価   ¥257

 

参考までに紙の本を売ってる楽天ブックス楽天市場の利用者とかぶるせいか、主婦向けのラインナップが上位に来てます。

あとは、ジャンル無差別に入ってるので、傾向というほどはなく売れてるものが売れてるって感じですかね。

 

楽天ブックス(参考)

1 【バーゲン本】新干し野菜レシピ ¥480
2 ロスジェネの逆襲 ¥1,575
3 【予約】レシピブログmagazine Vol.1 ¥515
4 【予約】ポケットモンスター X・Y公式ガイドブック 完全ストーリー攻略ガイド ¥1,260
5 【予約】フェフェ2013-2014Winter fafa‘s Universe ¥1,680
6 オレたち花のバブル組 ¥690
7 【入荷予約】乃木坂派 ¥1,995
8 オレたちバブル入行組 ¥690
9 極北ラプソディ ¥735
10 艦これ白書 ¥1,995
平均単価   ¥1,162

 

比較したのはあくまでランキング内容で、売れてる絶対数は不明なので一概には言えませんが

Book☆Walker => 萌系の専門店としてオタク層が利用

Kindle => ビジネス書籍を購入するような層が利用

Kobo => 比較的広い範囲の層が利用

 

という傾向が言えるんじゃないでしょうか。たぶん。

あと、単価が圧倒的に違うのが特色だと思います。

紙を売ってる楽天ブックスは1,162円、ラノベ・コミックが中心のBook☆Walkerが685円、Koboが468円、Kindleにいたっては257円です。

KoboKindleは200円台も目立つのでそのせいでしょう。逆に言えば、萌え系は価格をそれなりに高くしても維持できるコンテンツと消費者の関係が気づけてるという話かもしれないです。

もともと、デジタルデータには慣れてる層でしょうし。Kindleが1強なイメージでしたが、売れてる価格比率を考えると、一人勝ちというほどでもなく、他社にも十分チャンスがある状態なのかなー、とおもいました。

 

それでは、Happy e-Book Life!

playframework2のHTML出力が汚すぎるのでJsoupで整形してみた

最近、playframework2に手を出し始めました。

このフレームワーク、フォームヘルパーが結構色々HTMLを生成してくれるみたいで、まだ慣れてないせいもあって結構頻繁に生成されたHTMLの中身を見ています。

で、テンプレートエンジンの例に漏れず、出力されるHTMLが超絶汚い...

 

こんな感じのテンプレートが

gist6964461

こんな感じのHTMLに出力されます。

gist6964400

 

見辛すぎるよ!!

 

for文とかテンプレートのインクルードでぐちゃっとなるんですよね。

ということで、こちらの記事を参考にjsoupで整形してみました。

scalaの標準機能だけでできるかとも最初思ってたんですが、生成されたHTMLがXHTMLではなかったので無理でした><

jsoupで変換後はこんな感じに!

gist6964381

かなり見やすくなりましたね。下記のようなコードで対応しています。

gist6964539

gist6964553

 

本当はフィルタとかのレイヤで対応した方がいいと思うんですが、Playのフィルタがどういう動きをするのかを、まだ理解してないので、一旦こんな感じに。

当然パフォーマンスは落ちるので、場合によってはプロダクション時はオフにするとかのオプションも考慮が必要かもです。

まあ、少なくとも開発中はこれで幸せになれそうかな。

 

それでは、Happy Hcking!

 

参考:

Java Mission Control + Flight RecorderをGlassFish4で使ってみた

Java SE 7 Update 40が先日でました。なんとこの子はついに待望のFlight Recorder(ちゃんとした版)が実装されたのですよ!

本番環境の障害調査用にと個人的にはJRockitの機能がHotspotに統合されるHotRockitプロジェクトで一番注目してた機能でした。

一応、JDK7u4あたりからコマンド自体は移植されてたんですが、中身は全然移植されてなかったので、今か今かと待ってた次第です。

 

というわけで早速入れてみました。まずは通常利用しているGlassFish3.1.2に下記のオプションを追加。

<jvm-options>-XX:+UnlockCommercialFeatures</jvm-options>
<jvm-options>-XX:+FlightRecorder</jvm-options>

そしてstart-domain。

Error: To use 'FlightRecorder', first unlock using -XX:+UnlockCommercialFeatures.
Error: Could not create the Java Virtual Machine.
Error: A fatal exception has occurred. Program will exit.
launchctl bsexec failed: Inappropriate ioctl for device

Command start-domain failed.

動かない!? なんぞバグのようです。とりあえずGlassFish4では直ってるらしいので仕切りなおし。

GlassFish4 だと無事起動しました。ちなみに管理コンソールから変えるならこの辺を変更。

f:id:pascal256:20130924162004p:plain

 

 

続いてFlight Recoderを起動させます。

まず、jcmdコマンドを実行してglassfishのプロセスIDを確認

9131 /usr/local/bin/../Cellar/play/2.1.3/bin/../libexec/framework/sbt/sbt-launch.jar run
30363 bin/../glassfish/lib/client/appserver-cli.jar start-domain --verbose true
8887 
30639 sun.tools.jcmd.JCmd
30365 com.sun.enterprise.glassfish.bootstrap.ASMain -domainname domain1 -asadmin-args --host,,,localhost,,,--port,,,4848,,,--secure=false,,,--terse=false,,,--echo=false,,,--interactive=true,,,start-domain,,,--verbose=true,,,--watchdog=false,,,--debug=false,,,--domaindir,,,/Users/koduki/Downloads/glassfish4/glassfish/domains,,,domain1 -instancename server -verbose true -debug false -asadmin-classpath /Users/koduki/Downloads/glassfish4/glassfish/lib/client/appserver-cli.jar -asadmin-classname com.sun.enterprise.admin.cli.AdminMain -upgrade false -type DAS -domaindir /Users/koduki/Downloads/glassfish4/glassfish/domains/domain1 -read-stdin true

つづいて、プロセスIDを引数にして実行できるコマンド一覧を表示

jcmd 30365 help                                           
30365:
The following commands are available:
JFR.stop
JFR.start
JFR.dump
JFR.check
VM.native_memory
VM.commercial_features
ManagementAgent.stop
ManagementAgent.start_local
ManagementAgent.start
Thread.print
GC.class_histogram
GC.heap_dump
GC.run_finalization
GC.run
VM.uptime
VM.flags
VM.system_properties
VM.command_line
VM.version
help

For more information about a specific command use 'help '.

JFRなんたらがFlightRecerder関連です。まずは起動させます。

JFR.start

 続いて、適当に動かしたあとにdumpを取ります。

jcmd 30365 JFR.dump recording=1 filename=/tmp/dump.jfr

これで稼働データの取得はOK. 続いて、JMCでの分析です。

まずは、JMCを起動。

/Library/Java/JavaVirtualMachines/jdk1.7.0_40.jdk/Contents/Home/bin/jmc

EclipseベースのオサレなUIが立ち上がります。VisualVM と同等のJMXのリアルタイム分析も出来ますが、今回はパス。

File -> OpenFile で先ほどのdumpしたファイルを開きます。すると、いい感じに解析されたデータが!

 

 普通にシステムサマリはもちろん。

f:id:pascal256:20130924163020p:plain

 

 

オブジェクトの利用頻度をしかも時間を絞りながら確認可能。

f:id:pascal256:20130924163048p:plain

 

 

スレッドダンプとかロックしたスレッドの分析とかも可能。

f:id:pascal256:20130924163133p:plain

 

ファイルやsocketのI/Oも分析可能。

f:id:pascal256:20130924163330p:plain

 

どんなイベントに時間がかかってるかの分析だって出来ます。

f:id:pascal256:20130924163433p:plain

 

とりあえず、なにこれ、すごすぎない!? ってのが感想です。

プロファイラで取得するレベルの情報が、本番稼動システムに対して、たかだか4%から10%程度の性能ダウンで手に入るなら安いもんですね。障害分析の超強い味方になってくれそうです。

 

さすがに、本番運用は商用ライセンス買ってね☆ ってことみたいですが、これはお金払ってでも使いたいなぁ。まじめにいくら位なんだろ。その辺は後日要確認して導入を検討しよう、と。

 

 参考:

 

それではHappy Hacking!

なぜコピペはダメなのか?

コードレビューをしているとコピペしたと思わしきコードが持ち込まれることがあります。その度に指摘をするわけですが、よく指摘する内容をまとめてみました。

 

1).  記述内容を理解していない

Google検索の結果をそのまま貼りました」「以前のコードがそうなってたので真似しました」

特に後者はよくある回答ですね。既存コードだろうとWebにあるコードだろうとOSSの何かであろうと参考にするのは悪いことではありません。

しかしそれはあくまで参考です。自分たちが満たすべき要件と100%一致するとは限りません。

もちろん、記述内容をすべて理解し、その上で自分たちが書くべきだと思ったコードとたまたま一致する分には問題はありませんが、真似しただけだから分かりません、という回答だと大問題。

自分の記述範囲は真似てようがなんだろうが内容を理解してることが大事。

 

2). 重複したロジックが生まれる

俗にいうクローンコード。

同じロジックを自分のモジュールでも使いたいからと既存コードをコピペしたりして発生する。

これの問題は保守コストの増大。作った瞬間は問題ないのだけど、いざ、そのロジックを直す必要があるときに2倍の作業が必要になる。

しかも、例えばvalidate関数の内容をコピって別な場所に移植、とか変なことしてると、通常使ってるvalidate関数しか直さないとかあるだろうからバグを生む可能性が非常に高いです。

対処方法としてはちゃんと共通の関数やクラスに切り出すこと。どうしても保守性を下げてでも、ハードコピーをする必要があるならば、コード管理してるか責任持ってる人に相談しましょう。

 

3). 命名規則がおかしい

これは2つのパターンがあって、スタンダードな命名規則(Javaのコーディング規約とか)に対しておかしい場合と、そのシステム内で統一が取れてない場合。

単純に変だよね、直そうですむ場合は良いのだけど、結構やっかいなケースも多い。

たとえば、明らかに標準と違う名前だけど、このシステム内あるいはこのクラス内ではこうなってる、ってケース。

べき論としてはおかしいところ全部直せ、なんだけどコスト的にペイしないことも多いのが現実。

こういった場合、周りと合わせてどこかで一気に直すか、発生ベースでちょこちょこ直すかはコード管理の方針によるので、管理してるか責任持ってる人に相談しましょう。

 

まとめ

基本的には1は論外。新人ならきちんと叱って、それなりの経験者ならマイナス評価ってレベルですね。
2, 3は容易に実施できないケースもあるので最後は要相談なんだけど、深く考えてないケースが結構多いが問題ですね。
いずれにしても、コピペコードがダメと言われるのは考えてないからです。考えた結果コピペしたのと同じ結果になるけど、打つのが面倒だからコピーアンドペーストで貼り付けたってのは問題にはならないので、よく考えて使いましょうー

 

それではHappy Hacking!

MANGAで英語のお勉強? Kindleで読める英語のMANGAまとめ

NAVERまとめだと、amazonリンクはNGのようなので、こっちに作り直し。

 

英語の勉強には多読が必須と言われて久しいですが、そうは言ってもなかなか厳しいもの。SSS英語学習法の教材はイマイチ面白く無くて続かないし、かと言って有名小説なんかは、まだ難しくて読むんが大変で挫折しちゃう。

そういう経験はありませんか? 私はあります!

という訳で、なんか良い方法はないかと考えた結果、MANGAを読んでみることにしました。 イラスト付いてるから読みやすいですし、何より作品自体が面白い! 

なので、飽きずに読み進められそうです。 ペーパーブック版でも良いですが、持ちはこびの利便性を考えてKindle版で入手できるものをまとめてみました。

なんだか、妙に講談社が多いです。力入れてるのかな? ちなみに私は今「Fairy Tail」を読んでます。立ち読みとかで一度は読んだことある話が多いこともあって、多少知らない単語でもなんとなく分かって良いですね。