スポンサーサイト

上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。

ナベアツリファクタリング2

引き続き「世界のナベアツにJavaで挑戦」

前回リファクタリングをしたクラス図を元にソースに落とし込んでみました。

まずは、ナベアツクラスを以下のようにしました。


import java.util.ArrayList;

public class WorldOfNabeatsu {
 private ArrayList netacho;
 
 public WorldOfNabeatsu(){
  this.netacho= new ArrayList();
  // 数字読みネタをネタ帳に追加しておく
  this.netacho.add(new CountNumberNeta());
 }
 
 public static void main(String[] arg){
  
  // ナベアツオブジェクト作成
  WorldOfNabeatsu nabe = new WorldOfNabeatsu();
  
  // ねたを開始
  nabe.doPerformance();
  
 }
 public void doPerformance(){
  System.out.println("はーい 世界のナベアツです");
  
  // ネタ帳からネタを1つ取り出す
  Neta neta = (Neta) netacho.get(0);
  // ネタの説明をする
  System.out.println(neta.getName());
  
  // ネタを実行
  neta.execute();
  
  System.out.println("オモロー!");
 }
}



前よりナベアツがすっきりしました。

WorldOfNabeatsuメソッドはコンストラクタで初期化をしています。
ここでネタ帳に数字読みネタを書き込んでおきます。

doPerformanceメソッドを呼び出すことでナベアツがネタをし始めます。

ここでネタ帳から取り出すNetaインターフェースを見てみます。


public interface Neta {
 public void execute();
 public String getName();
}



インターフェースはメソッドの定義をするだけで、実装はしていません。

ナベアツはNetaのメソッド名さえ知っていれば中身をしる必要はないですから。
要は「どんなネタかを理解しなくてもネタが出来る」ということです。

・・・いいのかそれで(笑


んで、そのネタとして数字読みネタクラスを作ってみました。


import java.util.ArrayList;


public class CountNumberNeta implements Neta {
 
// Private変数で数字の読みを定義
private String[] kazu ={"","いち","に","さん","よん",
   "ご","ろく","なな","はち","きゅう","じゅう"};

// 数字のアホな読みを定義
private String[] ahokazu={"","いぃぃ~ち","にぃ","さぁぁん",
   "よぉぉん","ごぅ","ろぉくぅ","なぁなぁぁ",
   "はぁちぃぃ","きゅう~","じゅぅぅう"};

// 数字パターンリスト
private ArrayList patternlist;

public CountNumberNeta(){
 // パターンリストにパターンを追加
 this.patternlist=new ArrayList();
 
 // 3の倍数
 this.patternlist.add(new MultiplePattern(3));
 // 3が含まれる時
 this.patternlist.add(new IncludePattern(3));
 // 5の倍数
 this.patternlist.add(new MultiplePattern(5));
}

 public void execute() {
  // ネタを実行
  for (int i=1;i<=40;i++){
   // 数字をチェック
   if (checkNum(i)){
    // アホの読み
    System.out.println(parseNihonYomi(i,ahokazu));
   }else{
    // 普通の読み
    System.out.println(parseNihonYomi(i,kazu));
   }
  }
  
 }

 public String getName() {
  // ネタ名を返す
  return "1から40まで数えて、" +
   this.getPatternName() +
   "の時にアホになります。";
 }
 // パターンの説明を取得します
 private String getPatternName(){
  StringBuilder str = new StringBuilder();
  for (int i=0;i   Pattern pt =(Pattern) this.patternlist.get(i);
   if (str.length()>0){
    str.append("と" +pt.getName());
   }else{
    str.append(pt.getName());
   }
    
  }
  return str.toString();
 }
 // 数字をチェックします
 private boolean checkNum(int num){
  boolean ret=false;
  for (int i=0;i   Pattern pt =(Pattern) this.patternlist.get(i);
   ret = pt.check(num);
   if (ret){
    break;
   }
  }
  return ret;
 }
 // 数字を読みに変換します
 private String parseNihonYomi(int num,String[] yomis){
  String ret;
  // 数字の大きさをチェック
  if (num <10){
   // 10より小さいの場合
   ret=yomis[num];
  }else if (num >=10 & num <20){
   // 10以上20より小さい場合
   if (num==10){
    ret = yomis[10];
   }else{
    ret = yomis[10] + yomis[num-(int)Math.floor((num)/10)*10];
   }
  }else{
   // 20以上
   ret = yomis[(int)Math.floor((num)/10)] + yomis[10] +
       yomis[num-(int)Math.floor((num)/10)*10];
  }
  return ret;
 }
} 



長い・・・・・

中身は前回作ったナベアツクラスとほとんど変わらないですけど、
CountNumberNetaコンストラクタで初期化してるときに
3の倍数と3の数字を含む時と5の倍数のパターンをリストに追加しています。

あとはNetaインターフェースから実装したナベアツがexecuteメソッドを実行することで
数字読みネタを行います。

最後に数字の読みパターンクラス


public abstract class Pattern {
 
 public abstract boolean check(int i);
 public abstract String getName();
 
 
 protected String convertString(int num){
  return String.valueOf(num); 
 } 
}




public class MultiplePattern extends Pattern {
 private int num;
 
 public MultiplePattern(int num){
  this.num = num;
 }
 public boolean check(int i) {
  return (i % num == 0)?true:false;
 }
 public String getName() {
  return num + "の倍数";
 }
}




public class IncludePattern extends Pattern {

 private int num;
 public IncludePattern(int num){
  this.num=num;
 }
 public boolean check(int i) {
  return (this.convertString(i).indexOf(convertString(this.num))>=0)?true:false;
 }
 public String getName() {
  return num + "が含まれる数字";
 }
}



一気に3つ!

Patternクラスは数字読みパターンの親クラスでメソッドの定義と共通メソッドを持っています。

MultiplePatternクラスとIncludePatternクラスはPatternクラスを継承して
同じメソッド名を持っています。

また、この2つのクラスはコンストラクタに数値を引数で引き取っていて
「3の倍数」や「5の倍数」など数字を引数に渡してやることで色んな数字に対応できるように
なっています。

ですのでパターンを増やしたい場合は、MultiplePatternクラスとIncludePatternクラスの
どちらかを作ってCountNumberNeta クラスの初期化時にリストに追加してやるだけになります。


これで変更する箇所も少なくなり、少ない修正でネタのパターンを増やしてあげることができました。

ここまで作るほうが面倒くさいとか言わない(笑

最初は面倒くさいけど、一度作ったプログラムを修正することなんて結構あるので
後々になって助かるんですよ、これが。

このソースもまだまだ荒く保守性も低いですけど、もっとリファクタリングしていくと
さらに色んなネタができると思います。


今後は気が向いた時に手を入れていこうかと思います。



疲れた・・・・・
スポンサーサイト

コメントの投稿

非公開コメント

プロフィール

DJコーク

Author:DJコーク
地方で細々とSEまがいの仕事をしています。

楽天ブック
最近の記事
Feed
月別アーカイブ
スポンサードリンク
グラビス|gravis ノーマディック|nomadic ヴィブラム|vibram ロープロ|lowepro
MoMA STORE
MoMAstore
MoMAstore
MoMAstore
MoMAstore
MoMAstore
リンク
カテゴリ
サイト
ランキング
上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。