设计模式:工厂
概述
定义
执行
示例代码 - 创建书籍
哟哟!这是我开始学习设计模式以来写的第二篇文章。我的第一篇文章讲的是单例模式,你可以在这里找到。这次我们将探讨另一种创建型模式——工厂模式。我们先来看一下它的定义,然后是它的实现,最后来看一些示例代码。
概述
定义
工厂:用于生产商品的建筑物或建筑物群。正如我之前所说,工厂模式是一种创建型模式,它使我们能够灵活地创建继承自同一类的不同类型的对象,并在同一段代码中使用这些对象。
我们使用工厂和产品的关系来构建此模式。工厂负责实例化它想要生产的产品,而产品只需要知道它们需要遵循哪些规则才能成为产品。
执行
为了实现工厂模式,我们需要实现4种类型的类:
- 抽象工厂类。
- 定义一个抽象的 Create 方法。在某些情况下,这可能包含一个默认实现。
- 具体工厂类。
- 实现 Create 方法(这将实例化工厂的产品对象)。
- 抽象产品。
- 定义产品属性和方法。
- 具体产品类(这将由工厂对象实例化)。
- 继承自Product类,定义唯一的Product。
这种模式允许我们将 Product 对象的创建推迟到 Factory 的子类,使其成为一种为我们的代码提供灵活性的创建模式。
使用 C# 时,模式如下所示:
using System;
public class Program
{
public static void Main()
{
}
}
abstract class Factory
{
public abstract Product Create();
}
class FactoryA : Factory
{
public override Product Create()
{
return new ProductA();
}
}
class FactoryB : Factory
{
public override Product Create()
{
return new ProductB();
}
}
abstract class Product
{
public string Name;
}
class ProductA : Product
{
public ProductA()
{
this.Name = "Pepsi";
}
}
class ProductB : Product
{
public ProductB()
{
this.Name = "Coke";
}
}
Output:
FactoryA created Pepsi
FactoryB created Coke
您可以在.NET Fiddle上使用此代码
示例代码 - 创建书籍
现在让我们看一个现实世界的例子。也许我们想创建一个程序,帮助用户创建不同类型的书籍。目前,该程序将帮助用户创建一本小说或一本历史书。小说由以下页面组成:标题页、事件和作者简介。历史书由以下页面组成:致谢、单元和词汇表。然后,程序将打印出他们决定创建的书籍的页面(无论用户选择哪种书籍类型,都使用相同的代码)。
using System;
using System.Collections.Generic;
public class Program
{
public static void Main()
{
Console.WriteLine("Welcome to Book creator!");
Console.WriteLine("Would you like to make a Novel or History book?");
string bookType = Console.ReadLine();
BookFactory bookFactory = new CoolBookFactory(bookType);
Book userBook = bookFactory.Create();
// The magic of the pattern is below:
Console.WriteLine("PAGES -----");
foreach (var page in userBook.pages)
{
Console.WriteLine(page.GetType().Name);
}
}
}
abstract class BookFactory
{
public abstract Book Create();
}
class CoolBookFactory : BookFactory
{
public string BookType { get; private set; }
public CoolBookFactory(string bookType)
{
this.BookType = bookType;
}
public override Book Create()
{
if (this.BookType == "Novel")
return new NovelBook();
if (this.BookType == "History")
return new HistoryBook();
return null;
}
}
abstract class Book
{
public List<Page> pages = new List<Page>();
}
class NovelBook : Book
{
public NovelBook()
{
this.pages.Add(new TitlePage());
this.pages.Add(new EventPage());
this.pages.Add(new AboutTheAuthorPage());
}
}
class HistoryBook : Book
{
public HistoryBook()
{
this.pages.Add(new AcknowledgmentsPage());
this.pages.Add(new UnitsPage());
this.pages.Add(new GlossaryPage());
}
}
abstract class Page {}
class TitlePage : Page {}
class EventPage : Page {}
class AboutTheAuthorPage : Page {}
class AcknowledgmentsPage: Page {}
class UnitsPage : Page {}
class GlossaryPage : Page {}
Output:
Welcome to Book creator!
Would you like to make a Novel or History book?
Novel
PAGES -----
TitlePage
EventPage
AboutTheAuthorPage
您可以在.NET Fiddle上使用此代码
可以看到,现在我们可以灵活地添加其他书籍和页面,而无需修改主类中编写的创建代码。要添加其他书籍,我们只需要让 Factory 类处理其他书籍类型即可。