当前位置: 首页 > 面试题库 >

用Java或C#反映工厂设计模式

逑翰翮
2023-03-14
问题内容

我遇到了一个叫做反射的术语。这是工厂设计模式中常用的功能。我很难理解这个概念,因为我仍在学习如何编程。如何在C#或Java的工厂设计模式中使用反射?谁能给我一个简单的例子,并向您展示使用反射实现工厂设计模式的代码

Microsoft提供了此反射代码示例,但我不知道如何将其用于工厂设计模式。

 // Using GetType to obtain type information: 
  int i = 42;
  System.Type type = i.GetType();
  System.Console.WriteLine(type);

  The Output is: System.Int32

问题答案:

除非有特殊情况,否则我绝不会使用反射来实现Factory设计模式。下面的代码是实现工厂设计模式的一种糟糕方法。但是由于您想知道“如何”将反射用于工厂设计模式,因此以下示例:

namespace NaiveFactory
{

    public interface Shape
    {
        void Draw();
    }

    public class Circle : Shape
    {
        public void Draw() { Console.WriteLine("Drawing Circle"); }
    }

    public class Rectangle : Shape
    {
        public void Draw() { Console.WriteLine("Drawing Rectangle"); }
    }

    public class ShapeFactory
    {
        public static Shape GetShape<T>() where T : Shape
        {
            return Activator.CreateInstance<T>();
        }

        public static Shape GetShape(string shapeName)
        {
            var assembly = Assembly.GetExecutingAssembly();
            var type = assembly.GetType(shapeName).FullName;
            return (Shape) Activator.CreateInstanceFrom(assembly.Location, type).Unwrap();
        }
    }
    class Program
    {
        static void Main(string[] args)
        {
            var shape = ShapeFactory.GetShape<Circle>();
            var shape2 = ShapeFactory.GetShape("NaiveFactory.Rectangle");
            shape.Draw();
            shape2.Draw();
            Console.ReadKey();
        }
    }
}

编辑 根据@AlexeiLevenkov的建议,我在依赖注入中添加了一些内容,并Shape使用构造函数注入以及方法来实例化对象:

namespace NaiveFactory
{
    public interface IBoard
    {
        void InternalDraw(string str);
    }

    public class ConsoleBoard : IBoard
    {
        public void InternalDraw(string str) { Console.WriteLine(str); }
    }

    public class DebugBoard : IBoard
    {
        public void InternalDraw(string str) { Debug.WriteLine(str); }
    }

    public interface Shape
    {
        IBoard Board { get; set; }
        void Draw();
        void SetBoard(IBoard board);
    }

    public class Circle : Shape
    {
        public IBoard Board { get; set; }

        public Circle()
        {

        }

        public Circle(IBoard board)
        {
            Board = board;
        }

        public void Draw() { Board.InternalDraw("Drawing Circle"); }

        public void SetBoard(IBoard board)
        {
            Board = board;
        }
    }

    public class Rectangle : Shape
    {
        public IBoard Board { get; set; }

        public Rectangle()
        {

        }

        public Rectangle(IBoard board)
        {
            Board = board;
        }

        public void Draw() { Board.InternalDraw("Drawing Rectangle"); }

        public void SetBoard(IBoard board)
        {
            Board = board;
        }
    }

    public class ShapeFactory
    {
        private static Dictionary<Type, Type> _configurationData = new Dictionary<Type, Type>();

        public static Shape GetShape<T>() where T : Shape
        {
            return Activator.CreateInstance<T>();
        }

        public static void ConfigureContainer<T, U>()
        {
            _configurationData.Add(typeof(T), typeof(U));
        }

        public static Shape GetShape_UsingConstructorInjection(string shapeName)
        {
            var assembly = Assembly.GetExecutingAssembly();
            var type = assembly.GetType(shapeName);
            var constructor = type.GetConstructor(_configurationData.Keys.ToArray());
            if (constructor != null)
            {
                var parameters = constructor.GetParameters();
                return (from parameter in parameters where _configurationData.Keys.Contains(parameter.ParameterType) 
                        select Activator.CreateInstance(_configurationData[parameter.ParameterType]) into boardObj 
                        select (Shape) Activator.CreateInstance(type, boardObj)).FirstOrDefault();
            }
            return null;
        }

        public static Shape GetShape_UsingSetBoardMethod(string shapeName)
        {
            var assembly = Assembly.GetExecutingAssembly();
            var type = assembly.GetType(shapeName);
            var shapeObj = (Shape) Activator.CreateInstance(type);
            if (shapeObj != null)
            {
                shapeObj.SetBoard((IBoard) Activator.CreateInstance(_configurationData[typeof (IBoard)]));
                return shapeObj;
            }

            return null;
        }
    }
    class Program
    {
        static void Main(string[] args)
        {
            ShapeFactory.ConfigureContainer<IBoard, ConsoleBoard>();
            var shape = ShapeFactory.GetShape_UsingSetBoardMethod("NaiveFactory.Circle");
            var shape2 = ShapeFactory.GetShape_UsingConstructorInjection("NaiveFactory.Rectangle");
            shape.Draw();
            shape2.Draw();
            Console.ReadKey();
        }
    }
}


 类似资料:
  • 本文向大家介绍C++设计模式之抽象工厂模式,包括了C++设计模式之抽象工厂模式的使用技巧和注意事项,需要的朋友参考一下 问题描述 之前讲到了C++设计模式——工厂方法模式,我们可能会想到,后期产品会越来越多了,建立的工厂也会越来越多,工厂进行了增长,工厂变的凌乱而难于管理;由于工厂方法模式创建的对象都是继承于Product的,所以工厂方法模式中,每个工厂只能创建单一种类的产品,当需要生产一种全新的

  • 本文向大家介绍Java设计模式之工厂模式分析【简单工厂、工厂方法、抽象工厂】,包括了Java设计模式之工厂模式分析【简单工厂、工厂方法、抽象工厂】的使用技巧和注意事项,需要的朋友参考一下 本文实例讲述了Java设计模式之工厂模式。分享给大家供大家参考,具体如下: 一、 简单工厂 先来思考一个问题。我们平时写程序时,会有这种情况,A对象里面需要调用B对象的方法,这时我们使用的一般是new关键字来创建

  • 本文向大家介绍java设计模式之简单工厂模式,包括了java设计模式之简单工厂模式的使用技巧和注意事项,需要的朋友参考一下 在编写一个计算器程序时,可以将业务逻辑和显示分离,业务逻辑封装为一个类(封装);如果要新添加一种运算,可以先创建一个Operation的基类,然后各种运算从Operation类继承,并实现GetResult()虚函数,这时添加新的运算只需要派生一个新的类,即不需要之前的运算参

  • 本文向大家介绍23种设计模式(2) java工厂模式,包括了23种设计模式(2) java工厂模式的使用技巧和注意事项,需要的朋友参考一下 23种设计模式第二篇:java工厂模式 定义: 工厂模式是 Java 中最常用的设计模式之一。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。 工厂模式主要是为创建对象提供过渡接口,以便将创建对象的具体过程屏蔽隔离起来,达到提高灵活性的目的。

  • 介绍 与创建型模式类似,工厂模式创建对象(视为工厂里的产品)时无需指定创建对象的具体类。 工厂模式定义一个用于创建对象的接口,这个接口由子类决定实例化哪一个类。该模式使一个类的实例化延迟到了子类。而子类可以重写接口方法以便创建的时候指定自己的对象类型。 这个模式十分有用,尤其是创建对象的流程赋值的时候,比如依赖于很多设置文件等。并且,你会经常在程序里看到工厂方法,用于让子类类定义需要创建的对象类型

  • 本文向大家介绍C++设计模式之简单工厂模式实例,包括了C++设计模式之简单工厂模式实例的使用技巧和注意事项,需要的朋友参考一下 问题描述 之前在公司做了一个windows 8平台的阅读器。首先,需要将电子书中的内容渲染到屏幕上,而电子书每一页都包含各种各样的内容,比如:图形、图像和文字等等;不同的内容,就是不同的对象;在将不同的内容渲染到屏幕上之前,就需要new操作,建立不同的对象,然后再在屏幕上