俺の新 Git コース見てよ! おーい!俺の新 Git コース見てよ! おーい!GitByBit.com に俺の新 Git コースあるよ、見てみ! おーい!Git をサクッと復習したい?GitByBit.com の俺の新コース見てみ!
Factory Method

Factory Method を C# で

Factory Method は、 生成に関するデザインパターンの一つで、 具象クラスを指定することなく、 プロダクト (訳注: 本パターンでは、 生成されるモノのことを一般にプロダクトと呼びます) のオブジェクトを生成することを可能とします。

Factory Method では、 オブジェクトの生成において、 直接のコンストラクター呼び出し (new 演算子) 代わりに使用すべきメソッドを定義します。 サブクラスにおいてこのメソッドを上書きすることにより、 生成されるオブジェクトのクラスを変更します。

もし各種ファクトリー系のパターンやコンセプトの違いで迷った場合は、 ファクトリーの比較 をご覧ください。

複雑度:

人気度:

使用例: Factory Method パターンは、 C# コードでは広く使われます。 コードに高度の柔軟性を持たせたい時にとても役に立ちます。

見つけ方: 具象クラスで具象オブジェクトを作成し、 それを抽象型またはインターフェースのオブジェクトとして返すような生成メソッドの存在により、 Factory Method を識別できます。

概念的な例

この例は、 Factory Method デザインパターンの構造を説明するためのものです。 以下の質問に答えることを目的としています:

  • どういうクラスからできているか?
  • それぞれのクラスの役割は?
  • パターンの要素同士はどう関係しているのか?

Program.cs: 概念的な例

using System;

namespace RefactoringGuru.DesignPatterns.FactoryMethod.Conceptual
{
    // The Creator class declares the factory method that is supposed to return
    // an object of a Product class. The Creator's subclasses usually provide
    // the implementation of this method.
    abstract class Creator
    {
        // Note that the Creator may also provide some default implementation of
        // the factory method.
        public abstract IProduct FactoryMethod();

        // Also note that, despite its name, the Creator's primary
        // responsibility is not creating products. Usually, it contains some
        // core business logic that relies on Product objects, returned by the
        // factory method. Subclasses can indirectly change that business logic
        // by overriding the factory method and returning a different type of
        // product from it.
        public string SomeOperation()
        {
            // Call the factory method to create a Product object.
            var product = FactoryMethod();
            // Now, use the product.
            var result = "Creator: The same creator's code has just worked with "
                + product.Operation();

            return result;
        }
    }

    // Concrete Creators override the factory method in order to change the
    // resulting product's type.
    class ConcreteCreator1 : Creator
    {
        // Note that the signature of the method still uses the abstract product
        // type, even though the concrete product is actually returned from the
        // method. This way the Creator can stay independent of concrete product
        // classes.
        public override IProduct FactoryMethod()
        {
            return new ConcreteProduct1();
        }
    }

    class ConcreteCreator2 : Creator
    {
        public override IProduct FactoryMethod()
        {
            return new ConcreteProduct2();
        }
    }

    // The Product interface declares the operations that all concrete products
    // must implement.
    public interface IProduct
    {
        string Operation();
    }

    // Concrete Products provide various implementations of the Product
    // interface.
    class ConcreteProduct1 : IProduct
    {
        public string Operation()
        {
            return "{Result of ConcreteProduct1}";
        }
    }

    class ConcreteProduct2 : IProduct
    {
        public string Operation()
        {
            return "{Result of ConcreteProduct2}";
        }
    }

    class Client
    {
        public void Main()
        {
            Console.WriteLine("App: Launched with the ConcreteCreator1.");
            ClientCode(new ConcreteCreator1());
            
            Console.WriteLine("");

            Console.WriteLine("App: Launched with the ConcreteCreator2.");
            ClientCode(new ConcreteCreator2());
        }

        // The client code works with an instance of a concrete creator, albeit
        // through its base interface. As long as the client keeps working with
        // the creator via the base interface, you can pass it any creator's
        // subclass.
        public void ClientCode(Creator creator)
        {
            // ...
            Console.WriteLine("Client: I'm not aware of the creator's class," +
                "but it still works.\n" + creator.SomeOperation());
            // ...
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            new Client().Main();
        }
    }
}

Output.txt: 実行結果

App: Launched with the ConcreteCreator1.
Client: I'm not aware of the creator's class, but it still works.
Creator: The same creator's code has just worked with {Result of ConcreteProduct1}

App: Launched with the ConcreteCreator2.
Client: I'm not aware of the creator's class, but it still works.
Creator: The same creator's code has just worked with {Result of ConcreteProduct2}

他言語での Factory Method

Factory Method を C++ で Factory Method を Go で Factory Method を Java で Factory Method を PHP で Factory Method を Python で Factory Method を Ruby で Factory Method を Rust で Factory Method を Swift で Factory Method を TypeScript で