首页 > 编程语言 >C# 工厂模式学习

C# 工厂模式学习

时间:2024-05-27 11:30:54浏览次数:19  
标签:IAnimal C# void 模式 工厂 class new public

工厂模式(Factory Pattern)是一种创建型设计模式,它提供了一种创建对象的接口,而不是通过具体类来实例化对象。工厂模式可以将对象的创建过程封装起来,使代码更具有灵活性和可扩展性。

工厂模式有几种常见的实现方式:

  1. 简单工厂模式(Simple Factory Pattern): 简单工厂模式通过一个工厂类来决定创建哪种具体类的实例。这个工厂类通常提供一个静态方法,根据传入的参数创建相应的对象。

  2. 工厂方法模式(Factory Method Pattern): 工厂方法模式定义了一个创建对象的接口,但由子类决定要实例化的类是哪一个。工厂方法使一个类的实例化延迟到其子类。

  3. 抽象工厂模式(Abstract Factory Pattern): 抽象工厂模式提供一个接口,用于创建相关或依赖对象的家族,而无需明确指定具体类。通过使用抽象工厂模式,一个类可以实例化一组相关对象,而不需要知道它们的具体类。

简单工厂模式示例

假设我们有一个动物园项目,需要创建不同的动物对象:

// 动物接口
public interface IAnimal
{
    void Speak();
}

// 具体的动物类
public class Dog : IAnimal
{
    public void Speak()
    {
        Console.WriteLine("Woof!");
    }
}

public class Cat : IAnimal
{
    public void Speak()
    {
        Console.WriteLine("Meow!");
    }
}

// 简单工厂类
public static class AnimalFactory
{
    public static IAnimal CreateAnimal(string animalType)
    {
        switch (animalType.ToLower())
        {
            case "dog":
                return new Dog();
            case "cat":
                return new Cat();
            default:
                throw new ArgumentException("Unknown animal type");
        }
    }
}

// 使用示例
class Program
{
    static void Main(string[] args)
    {
        IAnimal animal = AnimalFactory.CreateAnimal("dog");
        animal.Speak();  // 输出:Woof!
    }
}

工厂方法模式示例

假设我们有一个动物园项目,不同的子类需要创建不同的动物对象:

// 动物接口
public interface IAnimal
{
    void Speak();
}

// 具体的动物类
public class Dog : IAnimal
{
    public void Speak()
    {
        Console.WriteLine("Woof!");
    }
}

public class Cat : IAnimal
{
    public void Speak()
    {
        Console.WriteLine("Meow!");
    }
}

// 工厂接口
public interface IAnimalFactory
{
    IAnimal CreateAnimal();
}

// 具体工厂类
public class DogFactory : IAnimalFactory
{
    public IAnimal CreateAnimal()
    {
        return new Dog();
    }
}

public class CatFactory : IAnimalFactory
{
    public IAnimal CreateAnimal()
    {
        return new Cat();
    }
}

// 使用示例
class Program
{
    static void Main(string[] args)
    {
        IAnimalFactory factory = new DogFactory();
        IAnimal animal = factory.CreateAnimal();
        animal.Speak();  // 输出:Woof!
    }
}

抽象工厂模式示例

假设我们有一个动物园项目,需要创建一组相关的对象(例如,动物及其食物):

// 动物接口
public interface IAnimal
{
    void Speak();
}

// 具体的动物类
public class Dog : IAnimal
{
    public void Speak()
    {
        Console.WriteLine("Woof!");
    }
}

public class Cat : IAnimal
{
    public void Speak()
    {
        Console.WriteLine("Meow!");
    }
}

// 食物接口
public interface IFood
{
    void Get();
}

// 具体的食物类
public class DogFood : IFood
{
    public void Get()
    {
        Console.WriteLine("Dog food");
    }
}

public class CatFood : IFood
{
    public void Get()
    {
        Console.WriteLine("Cat food");
    }
}

// 抽象工厂接口
public interface IAnimalFactory
{
    IAnimal CreateAnimal();
    IFood CreateFood();
}

// 具体工厂类
public class DogFactory : IAnimalFactory
{
    public IAnimal CreateAnimal()
    {
        return new Dog();
    }

    public IFood CreateFood()
    {
        return new DogFood();
    }
}

public class CatFactory : IAnimalFactory
{
    public IAnimal CreateAnimal()
    {
        return new Cat();
    }

    public IFood CreateFood()
    {
        return new CatFood();
    }
}

// 使用示例
class Program
{
    static void Main(string[] args)
    {
        IAnimalFactory factory = new DogFactory();
        IAnimal animal = factory.CreateAnimal();
        IFood food = factory.CreateFood();
        animal.Speak();  // 输出:Woof!
        food.Get();      // 输出:Dog food
    }
}

 以上是三种工厂模式的基本示例,可以根据具体需求选择合适的工厂模式来实现代码的创建和管理。如果希望在增加新动物类型时尽量减少对现有类的修改,推荐使用工厂方法模式。工厂方法模式的设计使得每新增一种动物,只需增加一个对应的工厂类和具体的动物类,而无需修改已有的代码,从而符合开闭原则(即对扩展开放,对修改关闭)。

使用工厂方法模式

下面是一个更完善的工厂方法模式示例,展示了如何在增加新动物时,尽量减少对现有代码的修改。

// 动物接口
public interface IAnimal
{
    void Speak();
}

// 具体的动物类
public class Dog : IAnimal
{
    public void Speak()
    {
        Console.WriteLine("Woof!");
    }
}

public class Cat : IAnimal
{
    public void Speak()
    {
        Console.WriteLine("Meow!");
    }
}

// 新增的动物类
public class Bird : IAnimal
{
    public void Speak()
    {
        Console.WriteLine("Tweet!");
    }
}

// 工厂接口
public interface IAnimalFactory
{
    IAnimal CreateAnimal();
}

// 具体工厂类
public class DogFactory : IAnimalFactory
{
    public IAnimal CreateAnimal()
    {
        return new Dog();
    }
}

public class CatFactory : IAnimalFactory
{
    public IAnimal CreateAnimal()
    {
        return new Cat();
    }
}

// 新增的动物工厂类
public class BirdFactory : IAnimalFactory
{
    public IAnimal CreateAnimal()
    {
        return new Bird();
    }
}

// 使用示例
class Program
{
    static void Main(string[] args)
    {
        List<IAnimalFactory> factories = new List<IAnimalFactory>
        {
            new DogFactory(),
            new CatFactory(),
            new BirdFactory()  // 新增的工厂只需在这里添加
        };

        foreach (var factory in factories)
        {
            IAnimal animal = factory.CreateAnimal();
            animal.Speak();
        }
    }
}

在这个示例中,新增一种动物只需:

  1. 创建新的具体动物类,例如 Bird
  2. 创建对应的工厂类,例如 BirdFactory
  3. 在使用的地方添加新的工厂实例,例如在 factories 列表中添加 new BirdFactory()

这样做的好处是每增加一个新动物类型,不需要修改现有的工厂类或具体的动物类,只需要添加新的类和工厂即可,从而降低了代码修改的风险和复杂度。

使用反射和配置来进一步减少修改

如果希望在增加动物时连代码都不需要改动,可以考虑使用反射和配置文件的方式。通过配置文件定义动物类型和对应的工厂类,然后使用反射动态加载:

// 动物接口和具体的动物类(同上)

// 工厂接口和具体工厂类(同上)

// 使用反射加载工厂类
class Program
{
    static void Main(string[] args)
    {
        // 假设配置文件中定义了动物类型和对应的工厂类
        var factoryTypes = new List<string>
        {
            "DogFactory",
            "CatFactory",
            "BirdFactory"  // 配置文件中新增的工厂类
        };

        var factories = new List<IAnimalFactory>();

        foreach (var factoryType in factoryTypes)
        {
            var type = Type.GetType(factoryType);
            if (type != null && typeof(IAnimalFactory).IsAssignableFrom(type))
            {
                var factory = (IAnimalFactory)Activator.CreateInstance(type);
                factories.Add(factory);
            }
        }

        foreach (var factory in factories)
        {
            IAnimal animal = factory.CreateAnimal();
            animal.Speak();
        }
    }
}

接口与继承结合使用

工厂模式主要使用了接口、继承,在C#中,接口和继承是面向对象编程的重要概念。接口定义了一组方法和属性,而继承允许一个类从另一个类继承其成员。接口可以实现多重继承,而类只能继承一个基类。通常情况下,接口和继承可以结合使用,以充分利用它们各自的优点。通过这种方式,基类可以提供一些通用的实现,而接口可以定义特定的行为。

// 接口
public interface IAnimal
{
    void Speak();
    void Eat();
}

// 基类
public class Animal
{
    public void Sleep()
    {
        Console.WriteLine("Sleeping...");
    }
}

// 派生类实现接口
public class Dog : Animal, IAnimal
{
    public void Speak()
    {
        Console.WriteLine("Woof!");
    }

    public void Eat()
    {
        Console.WriteLine("Dog is eating.");
    }
}

public class Cat : Animal, IAnimal
{
    public void Speak()
    {
        Console.WriteLine("Meow!");
    }

    public void Eat()
    {
        Console.WriteLine("Cat is eating.");
    }
}

// 使用示例
class Program
{
    static void Main(string[] args)
    {
        IAnimal dog = new Dog();
        dog.Speak(); // 输出:Woof!
        dog.Eat();   // 输出:Dog is eating.

        IAnimal cat = new Cat();
        cat.Speak(); // 输出:Meow!
        cat.Eat();   // 输出:Cat is eating.

        // 使用基类方法
        Animal animalDog = (Animal)dog;
        animalDog.Sleep(); // 输出:Sleeping...

        Animal animalCat = (Animal)cat;
        animalCat.Sleep(); // 输出:Sleeping...
    }
}

总结

  • 接口:定义了一组必须实现的方法和属性,没有实现代码。支持多重继承,使得类可以实现多个接口。
  • 继承:用于从现有类创建新类,继承基类的成员。每个类只能有一个基类,但可以实现多个接口。
  • 结合使用:通过将接口和继承结合使用,可以实现代码的高复用性和灵活性。

通过上述示例,可以看到如何使用接口和继承来设计灵活且可扩展的应用程序结构。这样既能充分利用基类的通用功能,又能通过接口实现特定的行为。

 

标签:IAnimal,C#,void,模式,工厂,class,new,public
From: https://blog.csdn.net/qq_41861321/article/details/139231801

相关文章

  • 通过apisix访问k8s的service示例
    kind:IngressapiVersion:networking.k8s.io/v1metadata:labels:app:test-webname:test-webnamespace:testannotations:k8s.apisix.apache.org/enable-websocket:"true"kubernetes.io/ingress.class:apisixkubernetes.io/p......
  • 销讯通-CRM系统的功能远远不止于用来打卡
    在信息化的过程中,CRM系统其实很多企业都在用,最开始的设想是很好的,大家用着之后发现它可能最终只会沦为一个上班打卡考核或者是最基础的一个签到工具了,没有发挥它应有的一个功能。最基础的一个诉求我们正也科技在做医药企业营销管理的过程中也发现,使用CRM的打卡,是他们最基础的上......
  • CSP历年复赛题-P1096 [NOIP2007 普及组] Hanoi 双塔问题
    原题链接:https://www.luogu.com.cn/problem/P1096题意解读:汉诺双塔的移动次数,与经典汉诺塔的区间在于同一个尺寸盘子有两个。解题思路:可以直接用经典汉诺塔方法来计算,双塔的结果就最终乘以2即可。首先想到的是递归,但是由于数据量n最大200,递归会超时,但是50%的样例应该没问题,先......
  • C#访问或修改私有类、函数、变量、属性
    publicstaticclassTypeUtl{publicstaticType?GetType(stringassemblyName,stringtypePath){varassembly=Assembly.Load(assemblyName);if(assembly==null)returnnull;returnassembly.Ge......
  • 通过vconfig命令配置VLAN
    #yuminstallvconfig 安装vconfig命令包#modprobe8021q加载8021q模块,若不支持8021q模块,则不支持VLAN#lsmod|grep-i8021q #vconfigaddeth0100 在eth0上配置VLAN100#vconfigaddeth0200 在eth0上配置VLAN200#vconfigset_flageth0.10011设置VLAN的REO......
  • QC2.0 3.0 4.0 的区别
    在我们日常的手机配件市场中,QC2.0、3.0、4.0这些术语频繁出现。不过,在与客户深入交流后,我发现许多人对这些术语及其背后的区别并不十分清楚。今天,我将为大家系统地梳理一下这些知识点。首先,我们先来明确一下这些术语的概念。QC,即QuickCharge,是由美国高通公司专为搭载Qualc......
  • C# 工厂模式学习
    工厂模式(FactoryPattern)是一种创建型设计模式,它提供了一种创建对象的接口,而不是通过具体类来实例化对象。工厂模式可以将对象的创建过程封装起来,使代码更具有灵活性和可扩展性。工厂模式有几种常见的实现方式:简单工厂模式(SimpleFactoryPattern):简单工厂模式通过一个工厂类......
  • PD还是QC?快充协议全解析
    摘自:https://zhuanlan.zhihu.com/p/646357568 快充技术在现代生活中的重要性不言而喻,它大大提高了充电效率,使人们可以在短时间内为设备充满电,从而提高生活和工作效率。同时,快速充电技术的发展也推动了电池技术、半导体材料技术等相关领域的进步,为科技创新提供了可能。然而,我们......
  • 性能优化陷阱之hash真的比strcmp快吗
    最近网上冲浪的时候看到有人分享了自己最近一次性能优化的经验。我向来对性能是比较敏感的,所以就点进去看了。然而我越看越觉得蹊跷,但本着“性能问题和性能优化要靠性能测试做依据”,我不能凭空怀疑别人吧,所以我做了完整的测试并写下了这篇文章。可疑的优化方案分享者遇到的问题......
  • 『vulnhub系列』BEELZEBUB- 1 96692f0bce834b9f85ce4fb6710ae52d
    『vulnhub系列』BEELZEBUB-1下载地址:https://www.vulnhub.com/entry/beelzebub-1,742/信息搜集:使用nmap扫描存活主机,发现主机开启了22和80端口nmap192.168.0.*访问80端口的web服务,发现是apache的默认页面使用dirsearch扫描目录dirsearch-u"http://192.168.0.140/"......