全知全能を目指す人のありがたい雑記

何かしら意味のあるありがた~い話か、意味のない雑念だらけの日記を書く予定です。

トップ

当ブログでは以下の内容を中心に更新する予定です。

  • 日記
  • プログラミング&開発
  • ゲーム
 
記事の方針として、
「プログラミング&開発」または「ゲーム」のカテゴリを
メインにしていく予定です。 
 
記事の内容としては
「備忘録」や「便利な物の紹介」などを
ありがた~く、独善的に、エゴイスティックに
書いていこうと思います。
(話半分に聞いてやってください*1
 
面白いゲームの紹介や、
プレイングのノウハウなども書けたら良いなぁ。
 
ご質問やご不明点、ご意見等ありましたら
コメントまたは「bluelightbleze@gmail.com」 にてご連絡ください。

*1:気をつけているつもりですが、誤った情報や古い情報を拡散する可能性があるかも。。

MVVMについて25%語る(その内5%は嘘かも)

MVVMは内部処理と画面の処理を分離させる設計。

Model View ViewModelの3つの要素に分ける。

その違いを備忘録としてまとめた。

Model View ViewModelの違い

View

  • 端的に言えば「システムにおける画面表示」
  • レイアウト定義
  • ユーザー操作の割り当て
  • 動的に変更したいコントロールや値はバインドする

ViewModel

  • 端的に言えば「システムにおける画面表示処理」
  • Viewにバインディングする情報をプロパティとして定義
  • Modelから受け取った内部データを、画面表示用のデータに変換する役割
  • 内部データは作らない。それはModelの債務
  • 外部とのやり取りはしない。それはModelの債務
  • Viewからユーザー操作を受け取ったら、対応する。また、DBのデータやシステム内部で保持しているデータが必要なら、Modelからもらう
  • Messenger(※1)を使うことでメッセージの登録を行い、Modelからメッセージが送信されたら受信時の処理を行い、画面へ結果を表示する

Model

  • 端的に言えば「システムにおける内部処理」
  • ViewModelから要求があればデータを作り、値をViewModelに渡す
  • 外部からの要求があればデータを作りViewModelへ通知
  • データを画面表示用に変換したりはしない。それはViewModelの責務
  • 複数のViewModelが同一のModelインスタンスを参照させるためにはModelをシングルトン(※2)にする

 

実際にModel・ViewModel・Viewの違いがわかる例

ユーザー操作時

  1. Viewをユーザが操作
  2. ViewModelはModelのインスタンスからデータを取得するメソッドを呼び出す
  3. 呼び出したメソッドの戻り値を、ViewModelのプロパティにバインディング
  4. ユーザー操作反映完了

外部からのデータ受信時

  1. ViewModelはインスタンス作成時にメッセージのコールバックを登録
  2. 外部からデータを受信
  3. Modelは受信したデータを、Modelで保持するデータに変換する
  4. Modelはメッセージを発行し、作成されているViewModelに対してメッセージを送信
  5. ViewModelは受け取ったメッセージ種別に対応する処理を行う

※1
Messengerパターン。
Messengerというクラスを使って
メッセージを送受信できる

  1. メッセージを受信するインスタンスはMessengerクラスへ「Messageの種類と受信時の処理を記述して」登録する
  2. メッセージを送信するインスタンスは該当するMessageのインスタンスを作成し、送信したいデータがあればそのインスタンスのメンバへ代入。
  3. Messageクラスが持つSendメソッドでメッセージを送信する。
  4. メッセージを受信するインスタンスは、2で送った種別のメッセージを受信し、対応する処理を行う。

 ※2
オブジェクト指向におけるデザインパターンの一つ。
簡単に言えば、インスタンスを2つ以上作らせないようにする。
staticクラスと類似しているが違いがある。
詳しくは考察記事があるので見てみよう。

takachan.hatenablog.com

 

支払い金額を設定し、支払いを終えるのに何枚の硬貨が必要かを算出するプログラム

#include <stdio.h>
int main(void){
    int price;
    scanf("%d",&price);
    
    int coins[6] = {500,100,50,10,5,1};
    
    for(int i = 0; i < 6; i++){
        printf("%d円が%d枚",coins[i],price/coins[i]);
        price = price % coins[i];
        if(i != 5)printf("、");
    }
}

入力

3333

出力

500円が6枚、100円が3枚、50円が0枚、10円が3枚、5円が0枚、1円が3枚

日付と曜日を表示するプログラム

javaでは一般的にカレンダークラスを使う。

今日からX日後の日付と曜日を出してほしいとのことなので
以下のコードを書いた

import java.util.*;

public class Main {
    public static void main(String[] args) throws Exception {
        Scanner s = new Scanner(System.in);
        int dayDelay = s.hasNext() ? s.nextInt() : 0;
        String[] week = {"日","月","火","水","木","金","土"};
        Calendar now = Calendar.getInstance(); 
        now.add(Calendar.DATE, dayDelay);
        System.out.println(now.get(now.YEAR)+"/"+(now.get(now.MONTH) + 1)+"/"+now.get(now.DATE)+"/" + week[now.get(now.DAY_OF_WEEK) -1]);
    }
}

入力

1

出力

2018/10/6/土

ハードコーディング恐怖症を患いました

ハードコーディング怖い

↓ハードコーディングしてるコード

import java.util.*;

public class Main {
    
    public static void main(String[] args) throws Exception {
        Scanner s = new Scanner(System.in);
        
        //ログインステータスは1が成功でぇ~、0が入力ミスでぇ~、-1がシステムエラーだよ!
        int loginStatus = login(s.nextLine());
        
        switch(loginStatus){
            case 1:
                System.out.println("ログイン成功");
                break;
            case 0:
                System.out.println("ユーザー名を正しく入力してください(8文字以上)");
                break;
            case -1:
                System.out.println("致命的なエラー(適当)");
                break;
        }
    }
    
    public static int login(String userName){
        if(userName.length() >= 8){
            return 1;
        }else if(userName != null){
            return 0;
        }
        return -1;
    }
    
}

enum使ってくれた女神のようなコード

import java.util.*;

public class Main {
    public enum loginStatus{
        Success,
        InvalidError,
        SystemError,
    }
    
    public static void main(String[] args) throws Exception {
        Scanner s = new Scanner(System.in);
        loginStatus ret = login(s.nextLine());
        
        switch(ret){
            case Success:
                System.out.println("ログイン成功");
                break;
            case InvalidError:
                System.out.println("ユーザー名を正しく入力してください(8文字以上)");
                break;
            case SystemError:
                System.out.println("致命的なエラー(適当)");
                break;
        }
    }
    
    public static loginStatus login(String userName){
        if(userName.length() >= 8){
            return loginStatus.Success;
        }else if(userName != null){
            return loginStatus.InvalidError;
        }
        
        return loginStatus.SystemError;
    }
    
}

サンプルだからログイン状態を3種類にとどめたけど、
これが10種類もあったら何の値かわからんこっちゃになっちゃうよ・・・。

頼む。みんな気を付けてくれ。
俺の目の前でハードコーディングを絶対にしないでくれ

プログラミングの質問(と回答)はこうあるべき

detail.chiebukuro.yahoo.co.jp

 

こういう質問があった。

 

最初はまったく内容が分からなかったんだけど、

きちんとご説明されていたし、

知識の照らし合わせが互いに出来たと感じた。

 

この切磋琢磨してる感じが良かった。

回答していて楽しいと感じられた。

 

課題を丸投げするな質問者さんより、

こういう質問者さんが増えると良いなぁ~。

 

良質な質問者でした。

 

おやすみなさい。

 

配列を使用して入力した数字から最大値・最小値・平均値を求めるプログラム

入力が一定ではないならリストの方が良いんだけどなぁ…
っていうのは学生の課題だから仕方ない?

とりあえず、配列の要素数は5にしています。
いつも通り、機能要件を満たす最低限のコードしか書いてません。

import java.util.*;

public class Main {
    public static void main(String[] args) throws Exception {
        Scanner s = new Scanner(System.in);
        int[] array = new int[5];
        int min = Integer.MAX_VALUE;
        int max = 0;
        int sum = 0;
        
        for(int element: array){
            element = s.nextInt();
            min = Math.min(min,element);
            max = Math.max(max,element);
            sum += element;
        }
        
        System.out.printf("Min=%d\n",min);
        System.out.printf("Max=%d\n",max);
        System.out.printf("Ave=%f\n",(float)sum/array.length);
    }
}

入力

3 6 7 9 12

出力

Min=3
Max=12
Ave=7.400000

.NETを使って「時間差」と「指定した時間が指定した時間帯か」を求めるプログラム

人のソース引用してます
C#で特定の時間帯に含まれるか判定
時間を表すTimeSpanオブジェクトを作成する、情報を取得する - .NET Tips (VB.NET,C#...)

using System;

public class HowToUseDateTime{
    public static void Main(){
        DateTime a = new DateTime(2018, 9, 28, 10, 05, 0);
        DateTime b = new DateTime(2018, 9, 28, 15, 10, 0);
        
        if(InRange(a,1000,1015)){
           Console.WriteLine("aのインスタンスは正しい時間帯");
        }
        else
        {
           Console.WriteLine("aのインスタンスは正しくない時間帯");
        }
        
        TimeSpan ts = a - b;
        
        Console.WriteLine("時間差は{0}です。",ts.ToString("c"));
    }
    
    public static bool InRange(DateTime dt, int from, int to){
        string stringhhmm = dt.ToString("HHmm");
        int inthhmm = Int16.Parse(stringhhmm);
        return inthhmm >= from && inthhmm <= to;
    }
}

出力

aのインスタンスは正しい時間帯
時間差は-05:05:00です。