C#设计模式之工厂模式,抽象工厂

简单工厂,工厂方法,抽象工厂的进阶之路


前言

工厂方法和抽象工厂都是创建型设计模式,工厂模式在父类中提供一个创建对象的接口,允许子类决定实例化对象的类型。
抽象工厂能创建一系列相关的对象,而无需指定其具体类。

但简单工厂模式不是 23 种里的一种,简而言之,就是有一个专门生产某个产品的类。


一、抛出问题

1.我们为什么要使用简单工厂?

2.简单工厂遇到了什么困难要让我们使用工厂模式?

3.工厂模式遇到的困境,抽象工厂是如何解决的?

4.抽象工厂的缺点

这四个问题是我们在使用这三种之前所要思考清楚的,什么时候该用,如何改进,如何在改进的基础上进一步改进。


二、回答问题


1.我们为什么要使用简单工厂?

简单工厂的优点和使用场景:
  • 工厂类中包含了必要的逻辑判断,根据客户端的选择条件动态实例化相关的类,对于客户端来说,去除了与具体产品的依赖。

  • 想要隔离具体实现,让客户端只通过接口操作。想要把创建对象的职责集中管理和控制。

简单工厂的出现,让客户端可以更好的面向接口编程,降低了耦合性。但是每次添加子类的时候,则是非常之麻烦,十分不方便。


2.简单工厂遇到了什么困难要让我们使用工厂模式?

A.简单工厂的解决方法

首先,我们先设想一下:

你有两部手机需要生产,而你只有一个工厂,客户发什么订单,你就按订单生产。

using System;

namespace ConsoleApplication4
{
    public class SimplePhoneFactory
    {
        public Phone GetFactory(string a)
        {
            if (a=="苹果")
            {
                return new ApplePhone();
            }
            return new XiaoMiPhone();
        }
        
    }

    public interface Phone
    {
        void call();
        void look();
    }

    public class ApplePhone:Phone
    {
        public void call()
        {
            Console.WriteLine("苹果手机给你打电话了");
        }

        public void look()
        {
            Console.WriteLine("苹果手机要给你视频通话");

        }
    }

    public class XiaoMiPhone:Phone
    {
        public void call()
        {
            Console.WriteLine("小米手机给你打电话了");
        }

        public void look()
        {
            Console.WriteLine("小米手机要给你视频通话");

        }
    }
}

客户端调用代码:

			//客户端调用
			SimplePhoneFactory phoneFactory=new SimplePhoneFactory();
            Phone aPhone=phoneFactory.GetFactory("苹果");
            aPhone.call();
            aPhone.look();

在这里,客户端调用的时候,完全不用知道工厂类的内部结构和实现逻辑,也能制造一个有效的product。
这个就是简单工厂的优点,那就是客户端无需了解内部类。

在这里插入图片描述

让我们想一下, 如果我们需要更多的手机,那就意味着需要在SimplePhoneFactory的GetFactory里重复添加更多的return 方法用来获得对象。而且这里只提供了两个手机品牌,if-else完全就可以解决,但是就像之前说的,如果提供更多手机,庞大的if-else会让维护者感到十分头痛,新手程序员们(当然也包括我)很难做到一开始就使用设计模式或者是字典来代替if-else。

那么我们现在应该做的事情,就是尽可能减少多个商品类对于工厂类的影响。

B.工厂模式的解决方法:

现在我们扩大了生产线,在之前的基础上加盖了XiaoMi工厂和Apple工厂并且拥有了两家家全新的工厂——HUAWEI工厂和OnePlus工厂。那么我们需要如何做呢?

  1. 创建总厂
  2. 创建具体厂
  3. 创建商品接口
  4. 创建商品类
using System;

namespace ConsoleApplication4
{
    public interface IFactory
    {
        IPhone GetPhone();
    }

    public class ApplePhoneFactory : IFactory
    {
        public IPhone GetPhone()
        {
            return new ApplePhone();
        }
    }
    public class XiaoMiPhoneFactory : IFactory
    {
        public IPhone GetPhone()
        {
            return new XiaoMiPhone();
        }
    }
    
    public interface IPhone
    {
        void call();
        void look();
    }

    public class ApplePhone:IPhone
    {
        public void call()
        {
            Console.WriteLine("苹果手机给你打电话了");
        }

        public void look()
        {
            Console.WriteLine("苹果手机要给你视频通话");
        }
    }

    public class XiaoMiPhone:IPhone
    {
        public void call()
        {
            Console.WriteLine("小米手机给你打电话了");
        }

        public void look()
        {
            Console.WriteLine("小米手机要给你视频通话");
        }
    }
}

客户端调用:

            IFactory factory=new ApplePhoneFactory();
            IPhone phone = factory.GetPhone();
            phone.call();
            phone.look();

在这里我们清晰可见,具体生产哪个商品,无需在工厂类中提供各种可能的返回对象,只需要在客户端中调用就行了。


3.工厂模式遇到的困境,抽象工厂是如何解决的?

为了回答这个问题,我们首先要思考一下,工厂模式遇到了什么困难,以至于让我们需要将工厂模式升级为抽象工厂模式呢?

很简单,就是你没那么多时间精力去创建并且管理工厂的时候,你会渴望有个足够抽象的工厂,能将产品类集中起来。而不是像工厂模式那样,创建比较具体的工厂比如:桌子——桌子工厂。

using System;

namespace ConsoleApplication4
{
    public interface abstractFactory
    {
        Pad createPad();
        Phone createPhone();
    }

    public interface Pad
    {
        void PlayPad();
    }

    public interface Phone
    {
        void PlayPhone();
    }

    
    public class Apple : abstractFactory
    {
        public Pad createPad()
        {
            return new ApplePad();
        }

        public Phone createPhone()
        {
            return new ApplePhone();
        }
    }

    public class ApplePad : Pad
    {
        public void PlayPad()
        {
            Console.WriteLine("hello ipad");
        }
    }
    public class ApplePhone : Phone
    {    
        public void PlayPhone()
        {
            Console.WriteLine("hello iphone");
        }
    }
}

//客户端

namespace ConsoleApplication4
{
    internal class Program
    {
        public static void Main(string[] args)
        {
            abstractFactory _abstract=new Apple();
            Pad pad = _abstract.createPad();
            pad.PlayPad();
        }
    }
}

每个产品虽然不尽相同,但是它们都有一部分相同的特质,完成的任务也可能有相同。所以将这些“相同的特质”抽象出来,就完成了抽象工厂模式的第一步。

实例 -> 类 -> 类工厂
实例 -> 类 -> 类工厂 -> 抽象工厂
抽象工厂模式和工厂模式的区别? - 徐大肉的回答 - 知乎
https://www.zhihu.com/question/20367734/answer/44379717

4.抽象工厂的缺点

难以支持新种类的产品。因为抽象工厂接口确定了可以被创建的产品集合,所以难以扩展抽象工厂以生产新种类的产品。

简单的说,就是扩展性差。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值