包你懂设计模式之:抽象工厂

今天我们来到三大工厂设计模式的最后一个抽象工厂模式,之前我们聊过简单工厂工厂方法两种设计模式,感兴趣的同学可以点进去看看,可以更快的了解今天要讲的内容。

抽象工厂模式:提供一个创建一系列相关或相互依赖对象的接口,而无需指定他们具体的类。这一点有别于我们之前的两种工厂,首先三种工厂模式都属于创建型的设计模式,他关注对象的创建,而前面介绍的两种都是关注单个对象的创建,而这一种则是关注的多个相关的或相互依赖的对象的创建。这是一种比较复杂的创建型设计模式,不但工厂是抽象的,产品时抽象的,而且有多个产品需要创建,因此,这个抽象工厂会对应到多个实际工厂,每个实际工厂负责创建多个实际产品。

这边举一个简单的例子来说明,并用代码实现,然后再聊一下抽象工厂的优点和缺点。我们码代码离不开电脑,今天就用电脑举例,我们假设就用到三个部件:处理器执行代码、存储器记录过程和结果、显示器显示结果。那我们认为这三个对象是相关联的对象,我们围绕这三个来演示抽象工厂。

抽象工厂也像是工厂的工厂,而每个工厂又有许多的提供商,如cpu、存储器的厂商,拿到产品,组装成电脑。首先我们定义一个抽象工厂,将我们上面相关联的三个对象包含在里面:

//抽象工厂
interface IComputerProvider
{
    IHardDisk GetHardDisk();//拿到存储器

    ICentralProcessingUnit GetCPU();//拿到cpu

    IMonitor GetMonitor();//显示器
}

上面的这个接口约束了他的实现类要能够拿到存储器、cpu和显示器,而这三种也没有具体的实现,意味着我们可以用不同的存储器,cpu和显示器,现在有一家工厂戴尔(dell),实现了这个接口:

public class DellComputer : IComputerProvider
    {
        public ICentralProcessingUnit GetCPU()
        {
            return new InterI58500();
        }

        public IHardDisk GetHardDisk()
        {
            return new Samsung960EVO();
        }

        public IMonitor GetMonitor()
        {
            return new Dell2418t();
        }
    }

而我们就可以使用dell电脑写代码了:

static void Main(string[] args)
{
    IComputerProvider computer = new DellComputer();

    ICentralProcessingUnit cpu = computer.GetCPU() ;
    IHardDisk hd = computer.GetHardDisk();
    IMonitor monitor = computer.GetMonitor();

    cpu.ExecutionProgram();
    hd.LoadProgram();
    monitor.PrintResult();

    Console.ReadLine();
}

         运行结果如下:

                                  

突然有一天贸易战升级了,dell电脑不能用了,但是码农还得写代码啊,所以我们用国产的吧。创建一个国产电脑类(ChinaComputer)继承抽象工厂(IComputerProvider),电脑的主要零部件厂商都选用国产的,Cpu咱用龙芯,存储用华为和赛门铁克共同研发推出的华赛系列存储,显示器当然京东方,这三个零部件只要符合通用标准(代码中则实现对应的接口)就可以被使用。这样我们就将电脑替换掉了,客户端的代码只需要修改IComputerProvider 的实现类,就可以了,十分方便。

在.net中有很多运用到这个设计模式的地方,比如数据库链接部分和日志部分,框架提供一系列的接口,这些都是和数据库或日志相关的,第三方的厂商,比如oracle数据库,它有自己成熟的数据库产品,但是我们用不了,只有官方或者个人按照.net提供的接口,写一套完整的实现,这样我们才可以用上oracle。我们使用者只要下载对应的类库,修改一下引用就好,非常方便。拓展性非常的强,日志也是五花八门,我们可以按照自己的喜好,下载类库,修改调用就可以使用对应的日志方案。

抽象工厂的优点固然很诱人,能提供很好的拓展性,但是也有其需要注意的事项。比如上面的这个例子,假设我们现在已经有很多的实现了(惠普、索尼、联想、苹果等等),现在我们需要给我们的抽象工厂加上一个功能,比如鼠标,这个改动一旦产生,对现有代码的影响是毁灭性的,每一个都会因为没有实现鼠标这个新特性而报错。所以抽象工厂类一定要稳定,设计完善,不能改动!

抽象工厂对于产品簇的拓展非常的方便,且不会违反开闭原则,不影响现有代码,但是对产品职责的修改非常不友好,所以抽象工厂是一种倾斜的可拓展设计。

欢迎大家留言交流,如有错误,请帮忙指正,希望大家多多关注我其他文章。

重要补充:上面的例子我发现有的地方可能会误导大家,这边特别再给大家梳理一下。首先我们要清楚抽象工厂模式用于创建一系列相关联的对象(cpu/存储器/显示器),也只有在需要创建多个相关对象的时候才适合这个模式,创建出来的对象也都各有自己的用处。

同样的例子讲解建造者设计模式,去看看 ==> 建造者模式(Builder Pattern)

 

猜你喜欢

转载自blog.csdn.net/maaici/article/details/108146211