データとそれを操作するメソッドは同じクラスにまとめる
■データを表現するデータクラスには、そのデータに対する処理(値変更)
を行うメソッドもセットで持つべき。
・データとメソッドが別クラスにあるのは、低凝集。
・このクラスのデータを変更するときは、必ずこのクラスで行われる
と整理されていれば(高凝集)、PG修正時や調査時など、このクラスだけを
見れば済むので、メンテナンス性が高い。
・ソリューション中の色んなクラスから同じデータに変更が行われる状態は
影響範囲が分かりにくいし、ソースの重複も発生する可能性がある。
(同じ処理を行うメソッドが、別々の場所に複数定義されている状態)
ファクトリメソッド
■クラスのコンストラクタは、なるべくそのクラス自身だけが
参照できることが望ましい。
・メソッドやプロパティも同様だが、無暗に公開すべきではない。
・特に引数を持つコンストラクタの場合、色んな場所で色んな引数で
初期化されることは、メンテナンス性を著しく下げる。
■クラス内にインスタンスを返すStaticメソッドを、目的別(引数の種類分)作る
・そうすれば、インスタンスがどんな引数で初期化されていても、
すべてのインスタンス生成ロジックが当該クラスに纏まっている為、
把握しやすい。
public class Ranking
{
private enum Ranks : int
{
GOLD=1, SILVER, BLONDS,NORMAL
}
private readonly int _MyRank = 0;
public int MyRank { get { return _MyRank; } }
//引数を持つPrivateなコンストラクタ
private Ranking(int createRank)
{
_MyRank = createRank;
}
/// 以下、目的別にこのクラスを生成するファクトリメソッド群
// GOLDランカーを生成
public static Ranking CreateGoldRanker()
{
return new Ranking((int)Ranks.GOLD);
}
// SILVERランカーを生成
public static Ranking CreateSilverRanker()
{
return new Ranking((int)Ranks.SILVER);
}
}
変数や引数は、基本的に不変(イミュータブル)にする
■インスタンス変数、プロパティや、メソッドの引数は、一度値をセットしたら
変更すべきではない。(引数の場合は、呼び出し元から渡された値
を変えるべきではない。
副作用を防ぐ為。
■readonly
readonly修飾子をつけ定義した変数は、コストラクタでのみ
値セットが可能になる。=値の変更が不可となる。
■値を変えたい場合
変数の値を変えるのではなく、新たにそのクラスのインスタンスを生成し、
それに対して新たな値をセットし返す設計がよい。
public class Goods
{
private readonly string _goodsName;
private readonly int _goodsAmount;
public Goods(string goodsName,int goodsAmount)
{
this._goodsName = goodsName;
this._goodsAmount = goodsAmount;
}
public Goods AddAmount(Goods tmpGoods )
{
// これは悪い例
/// _goodsAmount += tmpGoods.goodsAmount
// 新たにインスタンスを生成し、それに更新後の値をセットし返す
// 引数の型も、プリミティブ型(intとかstringとかデフォルトである型)ではなく、できるだけスコープを絞った型を
// 渡すことで、変な値を渡してしまうということを防ぐことができる。
return new Goods(tmpGoods._goodsName, tmpGoods._goodsAmount);
}
}
値を保持する
・AppState
Window.Xaml
■MainWindow.Xaml
<Window x:Class="WpfApp1.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:WpfApp1"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="800">
<Grid>
</Grid>
</Window>
■MainWindow.xaml.cs
namespace WpfApp1
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
}
}
MainWindow.xaml.csは、MainWindow.xamlのコードビバインド。
InitializeComponentは、xamlで定義した情報を呼び出すもので、必須。
App.Xaml
■App.Xaml
<Application x:Class="WpfApp1.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:WpfApp1"
StartupUri="MainWindow.xaml">
<Application.Resources>
</Application.Resources>
</Application>
・x:Class:App.Xamlのコードビバインド
他の画面も同様、x:Classでコードビバインドとなる
クラスが定義されている。
・StartupUri:アプリのエントリポイントとなるウィンドウを指定
子Componentから親に値を引き渡す
子側で引数付きのイベントを起こし、親はそのイベントを購読する。
●手順
<<Component側>>
①子側でイベントコールバックを定義
[Parameter]
public EventCallback<引き渡す値の型> 任意のイベント名 { get; set; }
②値を渡したいタイミングでイベントを起こす
イベントは、InvokeAsyncで起こしてもいいし、例えば子側の
ボタンクリックイベントでやるなら、onclick属性にイベントコールバックを
直接指定してもよい。
【Invokeする場合】
・await this.任意のイベント名.InvokeAsync(引き渡す値);
【onclickイベントなどで起こす場合】
・<button @onclick="任意のイベント名" />
<<親側>>
コンポーネント呼び出し時、イベントコールバック名と、イベント
呼び出し時に実行するメソッド名を紐づける。
<子Component 任意のイベント名="@実行するメソッド名" />
@code{
private void 実行するメソッド名(引き渡す値 変数名)
}