新しくなった Visual Studio 2019 で気になったことを書きながら GoF デザインパターンの Abstract Factory を作ってみます。
- 新機能は Visual Studio 2019 の新機能 | Microsoft Docs に記載されています
- もっと詳しい情報は Visual Studio 2019 リリース ノート | Microsoft Docs に記載されています
- 各エディションは Visual Studio 製品の比較 | Visual Studio に記載されています
- GoF デザインパターンは .NET Design Patterns in C# and VB.NET - Gang of Four (GOF) - doFactory.com からの引用になります
- 書籍からデザインパターンを学びたい場合は結城浩の 増補改訂版 Java 言語で学ぶデザインパターン入門 がおすすめです
気になったこと
- C# 8.0 は (デフォルト状態だと) まだです
- .NET Core 3.0 もまだです
- プロジェクトの LangVersion を自分で変更するか、 .NET Core 3.0 プレビューを使用すれば使えるようになります
- リリースに備えて C# 8.0 の新機能 - C# によるプログラミング入門 | ++C++; // 未確認飛行 C で勉強しましょう
- 色んな新しいプロジェクトを作るときに .NET Core を優先するようになりました
- 2017 の頃から思っていたことで、 Windows の GUI アプリじゃない限り .NET Framework は使わなくてもよい考えが加速しました
- Community と Professional が殆ど同じものになりました
- CodeLens が Community 版でも使用できるようになっています
- ただし Community 版のライセンス条項は 2017 と変わらないので、エンタープライズの人達はきちんと買ってね ♡
- Ctrl+Q (新しい検索エクスペリエンス) はとても便利になりました
- 2017 のときはワンテンポ遅くてどうしても使いづらかったのですが、爆速になっています
- Ctrl+. がパワーアップしました。それと未使用の変数とかも教えてくれるようになりました (これは 2017 から?)
- でもやっぱり ReSharper (Alt+Enter) のほうが頭がよいので ReSharper を入れたほうがよいです
- if とか for とかの statement とか method の色が変わりました
- 2017 のときは string とか int の基本型と同じ青色だったり、普通の黒色でした
- Color theme (Blue) は 2017 より全体的に薄いので、白文字が少し見づらくなっています
GoF デザインパターン - Abstract Factory
簡単なコンソールアプリのコードを書いても 2017 からの進化はよくわかりませんでした。
UML class diagram
Output
Code
Program.cs
class Program
{
static void Main(string[] args)
{
AbstractFactory factory1 = new ConcreteFactory1();
var client1 = new Client(factory1);
client1.Run();
AbstractFactory factory2 = new ConcreteFactory2();
var client2 = new Client(factory2);
client2.Run();
}
}
AbstractFactory.cs
abstract class AbstractFactory
{
public abstract AbstractProductA CreateProductA();
public abstract AbstractProductB CreateProductB();
}
ConcreteFactory1.cs
class ConcreteFactory1 : AbstractFactory
{
public override AbstractProductA CreateProductA()
{
return new ProductA1();
}
public override AbstractProductB CreateProductB()
{
return new ProductB1();
}
}
ConcreteFactory2.cs
class ConcreteFactory2 : AbstractFactory
{
public override AbstractProductA CreateProductA()
{
return new ProductA2();
}
public override AbstractProductB CreateProductB()
{
return new ProductB2();
}
}
AbstractProductA.cs
abstract class AbstractProductA
{
}
AbstractProductB.cs
abstract class AbstractProductB
{
public abstract void Interact(AbstractProductA a);
}
ProductA1.cs
class ProductA1 : AbstractProductA
{
}
ProductA2.cs
class ProductA2 : AbstractProductA
{
}
ProductB1.cs
class ProductB1 : AbstractProductB
{
public override void Interact(AbstractProductA a)
{
Console.WriteLine($"{GetType().Name} interacts with {a.GetType().Name}");
}
}
ProductB2.cs
class ProductB2 : AbstractProductB
{
public override void Interact(AbstractProductA a)
{
Console.WriteLine($"{GetType().Name} interacts with {a.GetType().Name}");
}
}
Client.cs
class Client
{
private readonly AbstractProductA _abstractProductA;
private readonly AbstractProductB _abstractProductB;
public Client(AbstractFactory factory)
{
_abstractProductB = factory.CreateProductB();
_abstractProductA = factory.CreateProductA();
}
public void Run()
{
_abstractProductB.Interact(_abstractProductA);
}
}