1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 |
namespace ConsoleApplication2 { /* Interpreter 規則のあるフォーマットを解析し処理する。 */ public interface Operand { //処理対象を表す文字列を返す string GetOperandString(); } //処理対象クラス public class Ingredient : Operand { //処理対象を表す文字列 private string OperandString = ""; public Ingredient(string operandString) { this.OperandString = operandString; } //処理対象を表す文字列を返す。 public string GetOperandString() { return this.OperandString; } } //処理結果クラス public class Expression : Operand { private Operator operate = null; //処理内容を表すOperatorを引数にとる public Expression(Operator operate) { this.operate = operate; } //処理の結果得られるOperandの文字列表現を返す。 public string GetOperandString() { return operate.Execute().GetOperandString(); } } public interface Operator { Operand Execute(); } //処理の実行 public class Plus : Operator { private Operand operand1 = null; private Operand operand2 = null; public Plus(Operand operand1, Operand operand2) { this.operand1 = operand1; this.operand2 = operand2; } public Operand Execute() { return new Ingredient(this.operand1.GetOperandString() + " + " + this.operand2.GetOperandString() + ""); } } class Program { static void Main(string[] args) { Expression expression1 = new Expression(new Plus(new Ingredient("1"),new Ingredient("2"))); System.Console.WriteLine(expression1.GetOperandString()); Expression expression2 = new Expression(new Plus(expression1, new Ingredient("2"))); System.Console.WriteLine(expression2.GetOperandString()); System.Console.ReadKey(); } } } |
C# デザインパターン Command
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 |
namespace ConsoleApplication2 { class Program { static void Main(string[] args) { Command command = new ConcreateCommand(); Receiver receiver = new ConcreateReceiver(); command.SetReceiver(receiver); Invoker invoker = new Invoker(command); invoker.execute(); } } /* Command 他のオブジェクトへのメソッド呼び出しとパラメータをオブジェクト化する。 */ public class Invoker // Commandの呼び出し { private Command command; public Invoker(Command command) { this.command = command; } public void execute() { this.command.Execute(); } } public interface Command //命令 { void SetReceiver(Receiver receiver); void Execute(); } public class ConcreateCommand: Command // 具体的な命令 { Receiver receiver; public void SetReceiver(Receiver receiver) { this.receiver = receiver; } public void Execute() { receiver.Action(); } } public interface Receiver //Commandの受信者 { void Action(); } public class ConcreateReceiver : Receiver //具体的な受信者 { public void Action() { } } } |
ざっくりまとめると、commandにreceiverを渡す。(commandがreceiverを保持)
渡し方は、Command cmd = new ConcreateCommand(receiver)
あるいは、上記のようなSetReceiver(receiver)とか。
そして、commandのExecute()の中でreceiverのAction()を呼ぶ。
Invokerは呼び出しで、そこからcommandのExecute()を呼ぶ。
処理の実体はreceiverのAction()の中。
C# Proxy
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 |
namespace ConsoleApplication2 { class Program { static void Main(string[] args) { Subject subject = new Proxy(); subject.Request1(); subject.Request2(); } } /* Proxy 代理人 */ interface Subject//ProxyとRealSubject共通のインターフェース { void Request1(); void Request2(); } public class Proxy : Subject //Clientからの処理を実行。 { public void Request1() { System.Console.WriteLine("this is proxy1"); } public void Request2() { //代理人に処理を任せる。 RealSubject realsubject = new RealSubject(); realsubject.Request2(); } } public class RealSubject : Subject //Proxyで処理できない場合処理。 { public void Request1() { System.Console.WriteLine("this is real proxy1"); } public void Request2() { System.Console.WriteLine("this is real proxy2"); } } } |
C# Flyweight
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 |
namespace ConsoleApplication2 { class Program { static void Main(string[] args) { } } /* Flyweight イミュータブルなクラス(フィールド値が不変のような)を再利用する。 */ public class Flyweight{ } public class FlyweightFactory { private FlyweightFactory f = new FlyweightFactory(); private FlyweightFactory(){ } private System.Collections.Generic.Dictionary<int,Flyweight> dic = new System.Collections.Generic.Dictionary<int, Flyweight>(); public FlyweightFactory GetInstance() { return f; } public Flyweight GetFlyweight(int key) { Flyweight f = dic[key]; if(f == null) { f = new Flyweight(); dic.Add(key, f); } return f; } } } |
C# State
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 |
namespace ConsoleApplication2 { class Program { static void Main(string[] args) { } } /* State 状態管理のクラス */ public class Context//具体的な状態(ConcreateState)を保持する。 { public State state; public void ChangeState(State state) { this.state = state; } public void Action() { this.state.Action(); } } public interface State//状態を表すクラス { void Action(); } public class ConcreateState1: State//具体的な状態 { public void Action() { //状態1 } } public class ConcreateState2 : State//具体的な状態 { public void Action() { //状態2 } } } |
C# Memento
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 |
namespace ConsoleApplication2 { class Program { static void Main(string[] args) { new caretaker(); System.Console.ReadKey(); } } /* Memento インスタンスのスナップショット */ public class Memento//記念品 { public int param = 1; public Memento(int p) { this.param = p; } } public class caretaker { System.Collections.Generic.Dictionary<string, Memento> dic = new System.Collections.Generic.Dictionary<string, Memento>(); public caretaker() { Originator o = new Originator(); o.CalcSum(1,2); dic.Add("first snapshot", o.CreateMemento()); o.CalcSum(3, 2); dic.Add("second snapshot", o.CreateMemento()); o.SetMemento(dic["first snapshot"]); System.Console.WriteLine(o.param.ToString()); } } public class Originator//作成者 { public int param; public void CalcSum(int x,int y) { this.param = x + y; } public Memento CreateMemento() { return new Memento(param); } public void SetMemento(Memento m) { this.param = m.param; } } } |
C# Observer
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 |
namespace ConsoleApplication2 { class Program { static void Main(string[] args) { } } /* Observer インスタンスの状態が変化した場合観察者に通知*/ public interface Observer { void Update(Subject subject); } public interface Subject { void AddObserver(); void NotifyObserver(); } public class ConcreateObserver: Observer { public void Update(Subject subject) { } } public class ConcreateSubject: Subject { System.Collections.Generic.List<Observer> ObserverList = new System.Collections.Generic.List<Observer>(); ConcreateObserver co = new ConcreateObserver(); public void AddObserver() { ObserverList.Add(co); } public void NotifyObserver() { co.Update(this); } } } |
C# Mediator
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 |
namespace ConsoleApplication2 { class Program { static void Main(string[] args) { } } /* Mediator 複数のオブジェクトから問合せを受け、相互の調整をし、指示を出す。 */ public interface Mediator { bool Consult(Colleague c); } public interface Colleague { void Inquiry(); } public class ConcreateMediator: Mediator { public bool Consult(Colleague c) { if (true) // ここで問合せに対する条件分岐 { return true; } else { return false; } } } public class ConcreateColleague: Colleague { public void Inquiry() { Mediator m = new ConcreateMediator(); if (m.Consult(this)) { //問合せ結果 } } } } |
C# Facade
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 |
namespace ConsoleApplication2 { class Program { static void Main(string[] args) { } } /* Facade 個別クラスへの処理を割り振るための窓口 */ public class client { Facade f = new Facade(); } public class Facade { public Facade() { ModuleA a = new ModuleA(); //aでの何かしらの処理 ModuleB b = new ModuleB(); //bでの何かしらの処理 } } public class ModuleA { //サブシステム } public class ModuleB { //サブシステム } } |
C# 継承実験
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 |
namespace ConsoleApplication2 { class BaseClass { public int var = 1; public void BaseMethod() { this.var = 10; } } class SubClass : BaseClass { public int var = 2; public void SubMethod() { this.var = 20; } } class Program { static void Main(string[] args) { SubClass s = new SubClass(); // SubClassでの public int var = 2 をコメントアウトした場合 System.Console.WriteLine(s.var.ToString()); // 1 BaseClass.varが呼ばれる。 s.BaseMethod(); System.Console.WriteLine(s.var.ToString()); // 10 BaseClass.BaseMethodでBaseClass.varの値が変わる。 // コメントアウトしない場合 System.Console.WriteLine(s.var.ToString()); // 2 SubClass.varが呼ばれる。 s.BaseMethod(); System.Console.WriteLine(s.var.ToString()); // 2 BaseMethodではSubClass.varを変更できない。 // SubClassでの public int var = 2 をコメントアウトした場合 System.Console.WriteLine(s.var.ToString()); // 1 BaseClass.varが呼ばれる。 s.SubMethod(); System.Console.WriteLine(s.var.ToString()); // 20 BaseClass.varの値はSubMethodで変更している。 // コメントアウトしない場合 System.Console.WriteLine(s.var.ToString()); // 2 SubClass.varが呼ばれる。 s.SubMethod(); System.Console.WriteLine(s.var.ToString()); // 20 SubClass.varの値をSubMethodで変更している。 /* 継承しても内部でそれぞれクラスの有効範囲がある。 メソッドもフィールドも保有している。 BaseMethodではSubClass.varを変更できないが、SubMethodはBaseClass.varもSubClass.varも変更できる。 */ System.Console.ReadKey(); } } } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 |
namespace ConsoleApplication2 { class BaseClass { public int var = 1; public void BaseMethod() { this.var = 10; } } class SubClass : BaseClass { public int var = 2; public void SubMethod() { this.var = 20; } } class Program { static void Main(string[] args) { //変数の型を基底クラスにした場合。 BaseClass s = new SubClass(); // SubClassでの public int var = 2 をコメントアウトした場合 System.Console.WriteLine(s.var.ToString()); // 1 BaseClass.varが呼ばれる。 s.BaseMethod(); System.Console.WriteLine(s.var.ToString()); // 10 BaseClass.BaseMethodでBaseClass.varの値が変わる。 // コメントアウトしない場合 System.Console.WriteLine(s.var.ToString()); // 1 BaseClass.varが呼ばれる。 s.BaseMethod(); System.Console.WriteLine(s.var.ToString()); // 10 BaseClass.BaseMethodでBaseClass.varの値が変わる。 // SubClassでの public int var = 2 をコメントアウトした場合 System.Console.WriteLine(s.var.ToString()); // 1 BaseClass.varが呼ばれる。 //s.SubMethod(); 呼ぶことができない // コメントアウトしない場合 System.Console.WriteLine(s.var.ToString()); // 2 SubClass.varが呼ばれる。 //s.SubMethod(); 呼ぶことができない。 /* 変数の型を基底クラスとすると派生クラスのメソッドが呼べない */ System.Console.ReadKey(); } } } |
インスタンスを入れる変数の型 = 派生
フィールドは
基底を派生で上書きした場合、派生が呼ばれる
基底を派生で上書きしない場合、基底が呼ばれる。
基底クラスメソッドでは
基底クラスのフィールドのみ変更できる。
派生クラスメソッドでは
基底クラスのフィールドが変更でき、
派生クラスのフィールドも変更できる。
(Virtula-Overrideしていても挙動は同じ)
インスタンスを入れる変数の型 = 基底
フィールドは
基底を派生で上書きしても、常に基底が呼ばれる。
基底クラスメソッドでは
基底クラスのフィールドのみ変更できる。
派生クラスメソッドは
呼べない。
Virtual-Override
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 |
namespace ConsoleApplication2 { class BaseClass { public void Method() { System.Console.WriteLine(1); } } class SubClass : BaseClass { public void Method() { System.Console.WriteLine(2); } } class Program { static void Main(string[] args) { SubClass s = new SubClass(); s.Method(); //virtual-overrideを付けないと 2 //つけると 2 BaseClass b = new SubClass(); b.Method(); //virtual-overrideを付けないと 1 //つけると 2 /* virtual-overrideを付けるとインスタンスの型で呼んでいる。 派生クラスインスタンスからは派生クラス.メソッドしか呼べないので、事実上の上書きと同じ。*/ System.Console.ReadKey(); } } } |