【クリエイティブデザインパターン】 C#デザインパターンのファクトリパターンと、リフレクションによる動的なファクトリの実現。

トピックは次のとおりです。

假设你正在为一家汽车制造公司编写软件。公司生产多种类型的汽车,包括轿车、SUV和卡车。每种汽车都有不同的特点和功能。

请设计一个工厂模式,用于创建不同类型的汽车对象。该工厂模式应具有以下要求:

工厂类名为 CarFactory,包含一个静态方法 CreateCar,根据传入的参数类型,返回对应类型的汽车对象。
汽车类 Car 是一个抽象类,包含一个抽象方法 Drive,用于描述汽车的驾驶行为。
轿车类 Sedan 继承自 Car 类,实现了 Drive 方法,在 Drive 方法中输出“驾驶轿车”。
SUV 类继承自 Car 类,实现了 Drive 方法,在 Drive 方法中输出“驾驶SUV”。
卡车类 Truck 继承自 Car 类,实现了 Drive 方法,在 Drive 方法中输出“驾驶卡车”。
使用该工厂模式完成以下操作:

在程序入口处,向 CarFactory 的 CreateCar 方法传入参数 "sedan",并将返回的对象存储到 sedanCar 变量中。
在 sedanCar 上调用 Drive 方法,观察输出结果。
同样地,创建一个 SUV 对象,并调用其 Drive 方法。
创建一个 Truck 对象,并调用其 Drive 方法。
请根据以上要求实现该工厂模式,并编写相应的代码。

単純なファクトリー実装:

using System;
using System.Reflection;


namespace Factory
{
    
    
    internal class CarFactory
    {
    
    
        public static T CreateCar<T>() where T : Car, new()
        {
    
    
            if (typeof(T) == typeof(Sedan))
                return new Sedan() as T;
            if (typeof(T) == typeof(SUV))
                return new SUV() as T;
            if (typeof(T) == typeof(Truck))
                return new Truck() as T;

            throw new ArgumentException("无法创建该类型的汽车对象。");
        }

     

    }
}

namespace Factory
{
    
    
    public abstract class Car 
    {
    
    

        public abstract void Drive();      
    }
}

using System;


namespace Factory
{
    
    
    internal class Program
    {
    
    
        static void Main(string[] args)
        {
    
    
            Car sedanCar = CarFactory.CreateCar<Sedan>();
            sedanCar.Drive();

            Car suvCar = CarFactory.CreateCar<SUV>();
            suvCar.Drive();

            Car truckCar = CarFactory.CreateCar<Truck>();
            truckCar.Drive();




            Console.ReadLine();
        }
    }
}

上記のコードは、抽象基本クラスの基本定義、ジェネリック ファクトリの実装、および呼び出しメソッドを提供します。この条件はジェネリック型パラメーターに対する制約である
ことに注意してくださいこの制約は、ジェネリック型パラメーターが次の 2 つの条件を満たす必要があることを示しています。where T : Car, new()
where T : Car, new()TT

TCarクラスまたはその派生クラスである必要があります。つまり、クラスの型またはサブクラス (派生クラス)Tである必要があります。CarCar

T引数のないコンストラクターが必要: この制約により、は引数のないコンストラクターが必要、つまりのインスタンスを使用できることnew()を意味します。Tnew T() 创建 T

上記の制約の目的は、ジェネリック型パラメーターがT使用中に要件を満たしていることを確認することです。制約は、メソッドで作成されたオブジェクトがその型またはそのサブクラスのインスタンスであることを保証するために、型またはその派生型である必要がTあります。同時に、制約には、 のインスタンスが確実に実行できるようにするため、引数のないコンストラクターが必要です。によって作成されますCarCreateCarCarTnew T()T

CreateCarこのような制約により、メソッドを呼び出すときに、渡される型パラメーターがT指定された要件を満たしていることが保証され、T対応するオブジェクト インスタンスがメソッド内の型に基づいて作成されることが保証されます。

工厂模式适用于以下场景:

对象创建复杂:当对象的创建涉及到复杂的逻辑判断、依赖关系或者大量的初始化操作时,可以使用工厂模式来封装对象的创建过程。这样可以简化客户端代码,并提供一个统一的入口来创建对象。

对象类型不确定:当需要根据不同的条件或者配置来创建不同类型的对象时,可以使用工厂模式。通过工厂模式,可以将对象的创建逻辑从客户端代码中分离出来,降低代码的耦合性。

扩展性要求高:当系统中需要添加新的产品或者变化频繁时,使用工厂模式可以方便地扩展和修改代码。通过增加新的具体工厂和产品类,而无需修改已有代码,符合开闭原则。

隐藏对象创建细节:当需要隐藏对象创建的细节时,可以使用工厂模式。客户端只需要与工厂接口进行交互,无需关心具体的产品如何创建或实现。

总的来说,工厂模式适用于对象创建复杂、对象类型不确定、扩展性要求高以及隐藏对象创建细节的情况。它能够提供灵活、可扩展和易于维护的代码结构。

コードを見ると、このファクトリ クラスには欠点があることがわかりますCarFactory。たとえば、新しい車のオブジェクトを追加するたびに、CarFactoryクラスを変更しCreateCarて新しいオブジェクトを追加する必要があります。現時点では、動的ファクトリを使用して、リフレクションを通じてオブジェクトを作成できます。

using System;
using System.Reflection;


namespace Factory
{
    
    
    internal class CarFactory
    {
    
    

        public static T CreateCar<T>(string typeName) where T : Car, new()
        {
    
    
            Type type = GetTypeByName(typeName);
            if (type != null && typeof(T).IsAssignableFrom(type))  return Activator.CreateInstance(type) as T;

            throw new ArgumentException("无法创建该类型的汽车对象。");
        }

        private static Type GetTypeByName(string typeName)
        {
    
    
            return Assembly.GetAssembly(typeof(CarFactory)).GetType($"Factory.{
      
      typeName}");
        }

    }
}

using System;


namespace Factory
{
    
    
    internal class Program
    {
    
    
        static void Main(string[] args)
        {
    
    

            // 传递具体类的类型名称作为参数
            string typeName = "Sedan";
            Car sedan = CarFactory.CreateCar<Sedan>(typeName);
            sedan.Drive();
            // 可以根据需要创建不同类型的汽车对象
            typeName = "SUV";
            Car suv = CarFactory.CreateCar<SUV>(typeName);
            suv.Drive();
            typeName = "Truck";
            Car truck = CarFactory.CreateCar<Truck>(typeName);
            truck.Drive();

            Console.ReadLine();
        }
    }
}

この方法では、コア ファクトリ コードを変更する必要はありません。現在の型が配置されているアセンブリ
を渡すことにより、typeNameインスタンスを動的に生成します。また、現在の型が別の型に変換できるかどうか(基底クラスであるか T の派生クラスであるかなど) も意味します。インスタンスの作成に使用されます。Assembly.GetAssembly(typeof(CarFactory))Factory.{typeName} 为 命名空间.类typeof(T).IsAssignableFrom(type)TTypetypeActivator.CreateInstance(type) as T

おすすめ

転載: blog.csdn.net/csdn2990/article/details/132082222