Skip to content

Instantly share code, notes, and snippets.

@takunoko
Last active January 20, 2017 08:44
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save takunoko/734e4f5b52cf14b62fcdeb7b4c274ad6 to your computer and use it in GitHub Desktop.
Save takunoko/734e4f5b52cf14b62fcdeb7b4c274ad6 to your computer and use it in GitHub Desktop.
TuT 授業課題 共有用

コーディング規約 まとめ

用語説明

参考: http://qiita.com/moaible/items/134329123074337913fb

単語 意味
丸括弧 ()
角括弧 []
波括弧 {}
山括弧 <>
キャメルケース cordingGuideLine
パスカルケース CordingGuideLine
スネークケース cording_guide_line
チェインケース coding-guide-line

重要そうな部分の抜粋

Javaコーディング標準: http://objectclub.jp/community/codingstandard/CodingStd.pdf

  • ファイル名 パブリックなクラス名はファイル名と同じ
  • クラス名 先頭大文字、区切りを大文字
  • 定数 大文字を _ でつないだもの UPPER_CASE_WITH_UNDERSCORES
  • メソッド名 最初大文字、あとは区切りを大文字 hogeMogeFuga
  • 属性取得メソッド
    • X()
    • getX()
    • isEnabled()
  • 属性設定メソッド
    • void setX(X value)
  • boolean変数を返すメソッド[is+形容詞, can+動詞, has+過去分詞, 三単現動詞+名詞]
    • boolean isEmpty()
    • ✗ boolean empty() //空にするという意味に間違う
    • boolean canGet()
    • boolean hasChanged()
    • boolean contains(Object)
    • boolean containsKey(Key) 理由としては、if,whileに使うときに条件がわかりやすいから。trueを返すのがどちらなのか、見て分かる。
  • 名前の対称性
    • add/remove
    • get/set, release
  • ループカウンタ スコープが狭いカウンタ、イテレータにはi,j,kをこの順番で使う。
  • スコープが狭い名前は型名を略したものでOK
    • HogeMogeFuga HMF = なんちゃら()
  • 意味が取れる名前 変数名から役割が読み取れる名前を使おう。
  • 無意味な名前を避ける tmp, data, info, str, buf などなど…。
  • 大文字小文字 大文字、小文字でプログラムは区別されるが、それのみで区別される名前は使わない。

コーディングスタイル

  • ファイル先頭のコピーライトは /* で始まるコメントとする。

  • package の次の行はあける

  • クラス定義の直前にクラスに関する**/****から始まるコメント

    • authorは必ず入れる。
  • クラス定義やメソッド定義の{の前の改行は入れない public class hoge みたいな感じ

  • if とか while とかの後の()の前後にはスペースを入れる if (hoge == 0) { みたいな

  • 字下げはタブ1つorスペース4つ

  • 80桁以上の行は適当な場所で改行

  • import はなるべく * を使わない。3つ以上なら * を使う。

  • インスタンス変数は極力publicを使わない。

  • 初期化をあてにしない。

  • 配列宣言は Type[] arrayName とせよ。 Type arrayName[] はただのCの名残で推奨されない。

  • 便宜を考えたつもりでの return this はしない。エラーの元。

  • 引数のタイプによるメソッドのオーバーロードはなるべく避ける 引数の数が異なるものはOK

  • 可能なら、常にデフォルトコンストラクタを用意する。

  • ローカル変数は初期化と共に宣言せよ。 プログラム中のへんなところで変数をぼこぼこ宣言するとわかりにくくなる

  • ローカル変数の再利用は悪。 悪い例

int i;
for (i=0; i<HOGE; i++) {...}
for (i=5; i>0; i--) {...}

いい例

for (int i=0; i<HOGE; i++) {...}
for (int i=5; i>0; i--) {...}
  • if, while の条件中の "=" はだめ バグのもと。さらにエラーが出ないからわかりにくい。
  • 大小比較は "<", "<=" を好んで使う。 "<", "<="を常に使い、右側を大きいほうにすることで混乱を避ける。
  • メソッド内部で引数の状態を変更するメソッドを呼ばない。
  • メソッド引数の名前 thisを活用してint _x みたいなことは避けよう。 悪い例
void reset(int x_, int y_) {
  x = x_;
  y = y_;
}

良い例

void reset(int x, int y) { // x_とかy_とかは使わない。
  this.x = x;
  thix.y = y;
}
  • toString()はできるだけ実装する。 println(Object) でプリントできると便利

コメント

  • コメントの種類にきをつける。 /** コメント */ コメントを活用する。

    • /** ... */ javadocコメント。html形式でドキュメント出力される
    • /* */ 通常のコメント、内部でき
    • // 通常のコメント、内部的
    • publicクラス、メソッド、フィールドには必ず /** */ コメントをつける。
  • javadocタグ

    • /** */ コメント内では、@ から始まるキーワード(javadocタグ)
    • @author author-name
    • @param paramName description /**
      @param n 要素サイズ(確保するメモリサイズを指定)
      
      */
    • @return description of return valuse
    • @exception exceptionName description
    • @see string
    • @see URL
    • @see classname#methodname
  • 1行コメントは /* */ よりも //

その他

  • トリッキーなコードは悪。 カッコ()を使ってわかりやすくしようね〜

  • ここに書かれたコーディング規則が100%正しいわけじゃない。理由によってはルールから外れる事が正しいこともある。理由があるなら考えて相談しよう。

// package edu161216;
public class MainShopCharger {
public static void main (String [] args) {
// カードの定義(2枚)
StudentCard S0 = new StudentCard(163399, "hoge");
S0.setAccountBalance(100);
System.out.println(S0);
StudentCard S1 = new StudentCard(163398, "moge");
S1.setAccountBalance(200);
System.out.println(S1);
// 学生証枚数
System.out.println("発行学生証枚数:" + StudentCard.getStudentCardList_().size());
// レジの定義
ShopCharger SC1= new ShopCharger();
ShopCharger SC2= new ShopCharger();
// 未挿入時の操作
SC1.chargeMoney(1000);
// カード0に対する処理
SC1.insertStudentCard(S0);
SC1.payMoney(500);
SC1.payMoney(50);
System.out.println(SC1);
// カード1に対するテスト
SC1.insertStudentCard(S1);
SC1.chargeMoney(10000);
SC1.chargeMoney(1000);
System.out.println(SC1);
// カード0に対するテスト
SC1.insertStudentCard(S0);
SC1.chargeMoney(1000);
SC1.chargeMoney(1400);
SC1.payMoney(333);
// 一度ログを表示
ShopCharger.printChargeLog();
SC2.insertStudentCard(S1);
SC2.chargeMoney(1000);
SC2.chargeMoney(30);
SC2.chargeMoney(1400);
SC2.chargeMoney(14);
SC2.chargeMoney(24);
ShopCharger.printChargeLog();
}
}
// package edu161216;
import java.util.*; // 3つ以上利用するため * を用いる
import java.text.SimpleDateFormat; // 日付文字列整形
/**
* レジを想定するクラス
* 挿入された学生証に対して操作を行う。
*
* ログの記録はレジ間で共有すると仮定する。
*
*/
class ShopCharger {
private StudentCard incertedStudentCard;
private static final int LOG_SIZE = 5; // ログサイズ
private static int logID = 0;
private static List<HashMap> chargeLog = new LinkedList<HashMap>();
public ShopCharger() {
incertedStudentCard = null; // 初期化時はnull
}
public void insertStudentCard(StudentCard C) {
incertedStudentCard = C;
}
// カードがレジに挿入しているかを確認する関数。クラス内でのみもちいるため、private関数
/**
* カードが機械に挿入されているかを調べる
*
* @return カードが挿入されていればtrueを返す
*/
private boolean checkInsertedCard() {
// カード未挿入時はエラー
if(incertedStudentCard == null){
System.out.println("カード未挿入");
return false;
}
return true;
}
/**
* 挿入されたに対してチャージを行う
* 正常にチャージを行った場合にはログに記録する
*
* @param money チャージ金額
* @return boolean型 チャージを行った場合にtrue 失敗でfalse
*/
public boolean chargeMoney(int money) {
// カード未挿入時はエラー
if (!checkInsertedCard()){ return false; }
// カード残高
int cardBalance = incertedStudentCard.getAccountBalance();
if ((cardBalance + money) > 10000) {
System.out.println("上限額オーバー");
return false;
}
// 正常な処理
incertedStudentCard.setAccountBalance(cardBalance + money);
// 格納するログデータの作成
HashMap cLog = new HashMap();
cLog.put("logID", logID);
cLog.put("userID", incertedStudentCard.getStudentID());
Calendar c = Calendar.getInstance();
// SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd"); // 課題の指示は年月日形式
SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
cLog.put("date", sdf.format(c.getTime()));
cLog.put("chargeMoney", money);
cLog.put("AccountBalance", incertedStudentCard.getAccountBalance());
// ない場合はaddある場合はset
if (logID < LOG_SIZE) {
chargeLog.add(logID, cLog);
} else {
chargeLog.set(logID % LOG_SIZE, cLog);
}
logID++;
return true;
}
/**
* 挿入されたカードで金額を支払う
*
* @param money 支払い金額
* @return 支払いできない場合にfalse, 支払い完了でtrueを返す。
*/
public boolean payMoney(int money) {
// カード未挿入時はエラー
if(!checkInsertedCard()){ return false; }
// カード残高
int cardBalance = incertedStudentCard.getAccountBalance();
if ((cardBalance - money) < 0) {
System.out.println("残高不足");
return false;
}
// 正常な処理
incertedStudentCard.setAccountBalance(cardBalance - money);
return true;
}
/**
* 最新5件分のチャージログを表示
*
* 上のデータの方が新しいデータ
* 5件以内の場合はそれらを表示
* staticなため、インスタンスが生成されていなくても呼び出す事ができる
*/
public static void printChargeLog(){
System.out.printf("\n\t--チャージログ(最新5件)--\n");
HashMap cLog;
for(int i=1; i<=LOG_SIZE && (logID - i) >= 0; i++){
cLog = chargeLog.get((logID - i)%LOG_SIZE);
System.out.println("----------------------------------------");
System.out.printf("%15s : %d\n", "logID", cLog.get("logID"));
System.out.printf("%15s : %d\n", "userID", cLog.get("userID"));
System.out.printf("%15s : %s\n", "date", cLog.get("date"));
System.out.printf("%15s : %d\n", "chargeMoney", cLog.get("chargeMoney"));
System.out.printf("%15s : %d\n", "AccountValance", cLog.get("AccountBalance"));
}
}
public String toString(){
String SCData;
SCData = "-------レジ-------\n"
+"ログ番号 : " +logID+ "\n"
+"ログサイズ: " +LOG_SIZE+ "\n";
if (checkInsertedCard()) {
SCData += "# カード有り\n";
SCData += "# Name : " +incertedStudentCard.getStudentName()+ "\n"
+"# Balance : " +incertedStudentCard.getAccountBalance();
} else {
SCData = SCData +"# カード無し";
}
return SCData;
}
public static void main (String [] args) {
// カードの定義(2枚)
StudentCard S0 = new StudentCard(163399, "hoge");
S0.setAccountBalance(100);
System.out.println(S0);
StudentCard S1 = new StudentCard(163398, "moge");
S1.setAccountBalance(200);
System.out.println(S1);
// レジの定義
ShopCharger SC = new ShopCharger();
System.out.println(SC);
// 未挿入時の操作
SC.chargeMoney(1000);
// カード0に対する処理
SC.insertStudentCard(S0);
SC.payMoney(500);
SC.payMoney(50);
System.out.println(SC);
// カード1に対するテスト
SC.insertStudentCard(S1);
SC.chargeMoney(10000);
SC.chargeMoney(1000);
System.out.println(SC);
ShopCharger.printChargeLog();
}
}
// package edu161216;
import java.util.ArrayList;
/**
* 学生証を表現するクラス
* 基本的には学生証1枚のデータを表す。
* 内部に学生証のリストをstaticで保持する。
*
*/
public class StudentCard {
private int studentID;
private String studentName;
private int accountBalance;
public static ArrayList<StudentCard> studentCardList_ = new ArrayList<StudentCard>();
public StudentCard(int studentID, String studentName) {
this.studentID = studentID;
this.studentName = studentName;
this.accountBalance = 0; // カード作成時は常に0円
studentCardList_.add(this); // カードリストに自分を追加
}
public int getStudentID() {
return studentID;
}
public String getStudentName() {
return studentName;
}
public int getAccountBalance() {
return accountBalance;
}
public static ArrayList<StudentCard> getStudentCardList_() {
return studentCardList_;
}
public boolean setAccountBalance(int accountBalance) {
this.accountBalance = accountBalance;
return true; // とりあえず現状ではなんでもtrue
}
// 現在のカードの状態を表示する関数
@Override
public String toString() {
return "ID : " +studentID+ "\n"
+"Name : " +studentName+ "\n"
+"AcBa : " +accountBalance+ "\n"
+"Size : " +studentCardList_.size();
}
public static void main (String [] args) {
StudentCard S0 = new StudentCard(163399, "hoge");
S0.setAccountBalance(100);
System.out.println(S0);
StudentCard S1 = new StudentCard(163398, "moge");
S1.setAccountBalance(200);
System.out.println(S1);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment