《.NET程序员面试秘笈》---- 面试题11 举例说明简单工厂模式的作用

简介: 【考点】工厂模式的理解,工厂模式在实际应用中的编写。

本节书摘来自异步社区《.NET程序员面试秘笈》一书中的第1章,面试题11,作者: 张云翯, 更多章节内容可以访问云栖社区“异步社区”公众号查看。

面试题11 举例说明简单工厂模式的作用

.NET程序员面试秘笈
【考点】工厂模式的理解,工厂模式在实际应用中的编写。

【出现频率】

【解答】

在软件系统中,经常面临着“一系列相互依赖的对象”的创建工作;同时由于需求的变化,往往存在着更多系列对象的创建工作。为了绕过常规对象的创建方法(new运算符创建实例),工厂模式提供一种“封装机制”来减少使用程序和这种“多系列具体对象创建工作”的耦合性。

说明:
这里的程序指客户程序之类的使用者。
简单工厂模式可以用于封装创建实例的实现部分,在应用接口的程序中被广泛使用,其应用模型如图1.16所示。



image

为了处理更加复杂的情况,可以将图中的产品进行再次细分为多个大类,用抽象类进行归纳,完成同大类产品共用代码的复用。然后将工厂类也相应地分为多个大类,用抽象类进行归纳。将图1.16改良后如图1.17所示。



image

说明:

本图假设将A产品和B产品作为两大类产品(即将看作产品的具体实现类再次细分),每大类产品有两个产品,如A产品有A1和A2。
为了说明工厂模式在应用程序中的具体表现,在ch01目录下新建一个程序文件,并命名为Factory.cs,编写代码如程序1.12所示。


22edee24b34d6e18fe1e5fd913ad8dc2c9372829


27d127f6f75880242c5c3ea7605f08bfaa6cf4cb


e0a9c570c5894ac321a034f54aaf8125248d4907

在命令行下编译Factory.cs后,执行Factory程序,其效果如图1.18所示。


f0608310c0d65411f8fd6d682d052b8e289eb546

本例声明了多个类,代码略显复杂,但是只要理解了图1.17,其实也容易掌握。在代码中,首先声明了一个接口,即Ihuman,其中含有两个未实现的方法。实现接口的类是两个抽象类,即Children(孩子)类和Adult(成年人)类,这两个类分别归纳了Boy类和Girl类,以及Man和Woman类。接口的getstatus方法成员在抽象类中实现,而getfav方法则映射为抽象方法,被抽象类的派生类实现。最后通过HumanFactory抽象类的两个派生类,根据不同的参数传递,创建不同的实例引用,并返回接口类型。

在主程序中,分别创建Factory1类和Factory2类的实例(f1和f2),并调用其gethuman方法。根据用户的输入决定创建哪个类的实例引用,并返回一个接口类型引用变量(h1和h2)。接口类型的引用变量调用两个方法时,使用者无法知道方法如何实现、由谁来实现。

【分析】

前面讲解接口的时候,着重分析了Bridge模式,接口可以简单地完成意图与实现的分离,以实现Bridge模式。由于类可以实现多个接口,所以类可以通过多个接口向外界提供多组不同的功能。接口反映了面向对象编程的特征之一,即多态,多态指通过相同方法得到不同的表现。接口也反映了面向对象编程的另一个特征,即封装,使用者并不清楚接口成员实现的细节,如以下代码所示:

interface Ibook             //声明接口Ibook
{
 void read();             //声明未实现的read方法
}
class BookA : Ibook
{
  public void read()         //实现read方法
 {
  Console.WriteLine("你在看A书。");
 }
}
class BookB : Ibook
{
  public void read()         //实现read方法
  {
    Console.WriteLine("你在看B书。");
  }
}
//使用接口的程序代码部分:
 Ibook abc = new BookB();       //创建Ibook类的BookB实例引用
 abc.read();               //调用read方法

接口类型的abc可以引用不同类的实例,以致相同的read方法可以有不同表现。但是以上代码的程序部分中,使用者仍然需要用new运算符进行相应的实例化,同时,使用者还是知道read方法由哪个派生类实现。为了进一步分离意图和实现,并对实现部分更好地封装,简单工厂模式可以进行一定的改良,添加代码如下所示:

class Factory
{
  private Ibook _bka = new BookA();
  private Ibook _bkb = new BookB();
  public Ibook getbook(int i)
  {
    switch (i)
    {
      case 1:
        return _bka;
      case 2:
        return _bkb;        
      default:
        return _bka;
    }
  }
}
//使用接口的程序代码部分修改如下:
Factory f = new Factory();
Ibook abc = f.getbook(2);   //调用f的getbook方法,并传递参数2
abc.read();           //调用read方法

Factory类封装了将接口各个派生类实例化的代码,这样,使用者只需要创建Factory类的实例,并调用getbook方法即可。向getbook方法传递不同的整数类型参数,可以创建不同的实例引用,而这些实例都是Ibook接口类型。如本例中,传递1将创建BookA类的实例引用(Ibook接口类型),传递2将创建BookB类的实例引用(Ibook接口类型)。使用者只知道传递数字来使用接口提供的不同功能,对内部实现却一无所知。Factory类则用于实例化各种类,相当于生产产品的工厂,其产品供接口类型的实例引用,这也是称其为工厂模式的原因。

说明:
本例中工厂类的getbook方法使用switch条件分支判断,然后返回相应的实例引用,在实例种类很多的情况下不大适用。根据具体情况不同,可以考虑利用反射、泛型等方法进行改进。
本文仅用于学习和交流目的,不代表异步社区观点。非商业转载请注明作译者、出处,并保留本文的原始链接。

相关文章
|
4月前
|
数据库 开发者
.NET 异步编程之谜:async/await 模式究竟隐藏着怎样的神奇力量?
【8月更文挑战第28天】在当今注重效率和响应性的软件开发领域,.NET 的 async/await 模式如同得力助手,简化异步代码编写,使代码更易理解和维护。通过后台执行耗时操作,如网络请求和数据库查询,避免阻塞主线程,显著提升系统响应性。此模式不仅适用于网络请求,还广泛应用于数据库操作和文件读写。合理使用 async/await 可大幅优化性能,但需注意避免过度使用、正确处理调用链及异常,以确保系统稳定性和高效性。深入探索 async/await,助您构建更出色的应用程序。
53 0
|
6月前
|
算法 Java 调度
《面试专题-----经典高频面试题收集四》解锁 Java 面试的关键:深度解析并发编程进阶篇高频经典面试题(第四篇)
《面试专题-----经典高频面试题收集四》解锁 Java 面试的关键:深度解析并发编程进阶篇高频经典面试题(第四篇)
73 0
|
2月前
|
网络协议 大数据 网络架构
桥接模式和NET模式的区别
桥接模式和NET模式的区别
41 0
|
3月前
|
算法 程序员 Go
PHP 程序员学会了 Go 语言就能唬住面试官吗?
【9月更文挑战第8天】学会Go语言可提升PHP程序员的面试印象,但不足以 solely “唬住” 面试官。学习新语言能展现学习能力、拓宽技术视野,并增加就业机会。然而,实际项目经验、深入理解语言特性和综合能力更为关键。全面展示这些方面才能真正提升面试成功率。
57 10
|
4月前
|
敏捷开发 设计模式 开发者
【揭秘终极利器】AgileEAS.NET:服务定位器模式的魔法,如何让企业级软件开发瞬间提速?揭秘背后的技术奥秘与实战指南!
【8月更文挑战第16天】AgileEAS.NET是基于DotNet的企业级敏捷开发平台,其服务定位器模式助力构建高度解耦系统。通过全局服务目录动态查找服务,避免硬编码依赖。在AgileEAS.NET中,服务定位器以静态类形式封装服务注册与检索功能。示例展示了如何注册与获取服务实例,如在`UserController`中通过服务定位器使用`IUserService`。此模式整合到框架生命周期管理,便于各处获取服务实例,提升开发效率。然而,应适度使用并考虑依赖注入容器以增强代码可维护性和可测试性。
76 4
|
4月前
|
JavaScript 前端开发 小程序
CoderGuide 程序员前后端面试题库,打造全网最高质量题库
CoderGuide涵盖范围包括且不限于:前端面试题(Vue,React,JS,HTTP,HTML,CSS面试题等),后端面试题(Java,Python,Golang,PHP,Linux,Mysql面试题等),以及算法面试题,大厂面试题,高频面试题,校招面试题等,你想要的,这里都有!
70 2
|
4月前
|
负载均衡 前端开发 API
我希望在系统设计面试之前知道的 12 种微服务模式
我希望在系统设计面试之前知道的 12 种微服务模式
|
4月前
|
开发框架 监控 .NET
|
6月前
|
消息中间件 Kafka 程序员
Kafka面试必备:深度解析Replica副本的作用与机制
**Kafka的Replica副本是保证数据可靠性的关键机制。每个Partition有Leader和Follower副本,Leader处理读写请求及管理同步,Follower被动同步并准备成为新Leader。从Kafka 2.4开始,Follower在完全同步时也可提供读服务,提升性能。数据一致性通过高水位机制和Leader Epoch机制保证,后者更精确地判断和恢复数据一致性,增强系统容错能力。**
214 1
|
6月前
|
前端开发 应用服务中间件 程序员
老程序员分享:Nginx相关面试题
老程序员分享:Nginx相关面试题
59 2