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(); } } } |
C# Chain of Responsibility
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 |
namespace ConsoleApplication1 { class Program { static void Main(string[] args) { //Handler h = new ConcreateHandler1().SetNext(new ConcreateHandler2()).SetNext(new ConcreateHandler3()); //これだとダメ。インスタンスがネストされない。 Handler h = new ConcreateHandler1(); h.SetNext(new ConcreateHandler2()).SetNext(new ConcreateHandler3()); /* hを生成した時点で、1,2,3コンストラクタが呼ばれている。*/ h.Request(1); System.Console.ReadKey(); } } /* Chain of Responsibility */ abstract class Handler { protected Handler next; protected int level; public Handler SetNext(Handler handler) { this.next = handler; return this.next; } public void Request(int mask) { System.Console.WriteLine(this.ToString()); /* このコンテキストのthisは、 Request(1)とすると、 > ConcreateHandler1 だけ。 Request(2)とすると、 > ConcreateHandler1 > ConcreateHandler2 Request(3)とすると、 > ConcreateHandler1 > ConcreateHandler2 > ConcreateHandler3 */ if (this.level == mask) { System.Console.Write(mask); } else { if (next != null) next.Request(mask); } } } class ConcreateHandler1 : Handler { public ConcreateHandler1() { this.level = 1; } } class ConcreateHandler2 : Handler { public ConcreateHandler2() { this.level = 2; } } class ConcreateHandler3 : Handler { public ConcreateHandler3() { this.level = 3; } } } |
C# Visitor
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 |
namespace ConsoleApplication1 { class Program { static void Main(string[] args) { } } /* Visitor 訪問者であるVisitorに処理を記述する。 処理対象はAcceptorでVisitorを受け入れる必要がある。 */ interface Visitor { void Visit(Acceptor acceptor); } class ConcreateVisitor : Visitor { public void Visit(Acceptor acceptor) { } } interface Acceptor { void Accept(Visitor visitor); } class ConcreateAcceptor: Acceptor { public void Accept(Visitor visitor) { visitor.Visit(this); } } } |
C# Decorator
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 |
namespace ConsoleApplication1 { class Program { static void Main(string[] args) { } } /* Decorator */ interface Component { void Operation(); } class ConcreateComponent: Component { public void Operation() { } } class Decorator: Component { private Component component; public Decorator(Component c) { this.component = c; } public void Operation() { } public void Operation2() { //拡張機能 } } } |
C# Composite
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 |
namespace ConsoleApplication1 { class Program { static void Main(string[] args) { } } /* Composite ファイルとフォルダのような複数の要素に共通のインターフェース。*/ interface Component { void operation(); } class Leaf: Component { public void operation() { } } class Composite: Component { public void operation() { } //再帰構造の場合、compositeにadd,removeなど定義 } } |
C# Strategy
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 |
namespace ConsoleApplication1 { class Program { static void Main(string[] args) { Context c = new Context(new ConcreateStrategy1()); c.Method(); } } /* Strategy アルゴリズムだけ抜き出してアルゴリズムを切り替えやすくする。*/ class Context { private Strategy strategy = null; public Context(Strategy strategy) { this.strategy = this.strategy = strategy; } public void Method() { this.strategy.Method(); } } interface Strategy { void Method(); } class ConcreateStrategy1: Strategy { public void Method() { //アルゴリズム1 } } class ConcreateStrategy2 : Strategy { public void Method() { //アルゴリズム2 } } } |
C# Bridge
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 |
namespace ConsoleApplication1 { class Program { static void Main(string[] args) { //abstraction生成時にConcreateImplementorのインスタンスを渡す。 Abstraction abstraction = new Abstraction(new ConcreateImplementor()); } } /* Bridge 機能と実装の分離 機能実装の度の継承をなくため、機能実装専用のインターフェースを利用。 */ public class Abstraction { private Implementor implementor; public void function() { //コンストラクタで保持したオブジェクトに処理を任せる。 this.implementor.implementation(); } public Abstraction(Implementor i) { this.implementor = i; } } public class RefinedAbstraction: Abstraction { public RefinedAbstraction(Implementor i) : base(i) { } public void RefinedMethod1() { //追加機能 } } //機能実装クラスの抽象と具象。 public abstract class Implementor { public abstract void implementation(); } public class ConcreateImplementor: Implementor { public override void implementation() { //実装 } } } |