。  工厂模式同样是项目中最常用的设计模式,工厂模式中又分为简单工厂,工厂方法,抽象工厂。下面我们由简单的开始逐一介绍。

1.简单工厂模式

  简单工厂又被称为静态工厂,在设计模式中属于创建型模式。主要解决的问题是封装了实例化的过程,通过传入参数来获不同实例。下面我们举一个项目中可能会用到的例子。

  假设我们程序的数据保存在几个不同的数据库中,有MySql,SQLServer和MongoDB。数据库都有增删改查的操作,我们就声明一个接口定义这些操作。

     public interface IDatabase
{
void Insert();
void Delete();
}

  然后我们让三个数据库类分别实现这个接口。

     public class SqlServer : IDatabase
{
public void Delete()
{
Console.WriteLine("delete data from sqlserver");
} public void Insert()
{
Console.WriteLine("insert data to sqlserver");
}
} public class MySql : IDatabase
{
public void Delete()
{
Console.WriteLine("delete data from mysql");
} public void Insert()
{
Console.WriteLine("insert data to mysql");
}
} public class MongoDB : IDatabase
{
public void Delete()
{
Console.WriteLine("delete data from mongoDb");
} public void Insert()
{
Console.WriteLine("insert data to mongoDb");
}
}

  之后我们再声明一个工厂类,这个类中的静态方法可以根据传入不同的参数来创建不同的实例。

     public static class DatabaseFactory
{
public static IDatabase CreateDatabase(string dbType)
{
IDatabase db = null; switch (dbType)
{
case "MySql":
db = new MySql();
break;
case "SqlServer":
db = new SqlServer();
break;
case "MongoDB":
db = new MongoDB();
break;
default:
break;
} return db;
}
}

  最后我们再Main函数里声明三个接口,然后给工厂类传入不同的参数来创建三个不同的实例,再分别调用接口中声明的方法。

         static void Main(string[] args)
{
IDatabase db1 = DatabaseFactory.CreateDatabase("MySql");
db1.Insert();
db1.Delete(); IDatabase db2 = DatabaseFactory.CreateDatabase("SqlServer");
db2.Insert();
db2.Delete(); IDatabase db3 = DatabaseFactory.CreateDatabase("MongoDB");
db3.Insert();
db3.Delete();
}

  来看一些控制台的输出:

  这就是简单工厂模式。

  我们可以看到简单工厂模式的优点:

  1.拓展性好,如果这时候我们又添加了一个Oracle数据库,只需要再添加一个新的类并实现IDatabase这个这个接口就行了。

  2.我们只需要关注接口中的方法,不需要关注具体类的实现。

  缺点:只适用于工厂需要创建比较少的具体类这样的情况。如果具体类多,代码的复杂程度会增加。

2.工厂模式

  工厂模式在简单工厂模式的基础上进行了更加全面的面向对象封装,可以让我们不要单独的工厂方法就能创建出具体的实例。做法就是为每一个具体的类创建单独的工厂。接下来我们对刚刚几个类稍加改造。

  首先发DatabaseFactory修改成一个接口,接口中定义一个用来创建实例的方法。

     interface IDatabaseFactory
{
IDatabase CreateDatabase();
}

  然后我们然后我们为每个具体类单独创建一个工厂类,工厂类实现刚刚定义的接口。

     public class MongoDbFactory : IDatabaseFactory
{
public IDatabase CreateDatabase()
{
return new MongoDB();
}
} public class MySqlFactory : IDatabaseFactory
{
public IDatabase CreateDatabase()
{
return new MySql();
}
} public class SqlServerFactory : IDatabaseFactory
{
public IDatabase CreateDatabase()
{
return new SqlServer();
}
}

  最后我们在main函数中创建工厂的实例。

        static void Main(string[] args)
{
IDatabaseFactory dbFactory1 = new MySqlFactory();
IDatabase db1 = dbFactory1.CreateDatabase();
db1.Insert();
db1.Delete(); IDatabaseFactory dbFactory2 = new SqlServerFactory();
IDatabase db2 = dbFactory1.CreateDatabase();
db2.Insert();
db2.Delete(); IDatabaseFactory dbFactory3 = new MongoDbFactory();
IDatabase db3 = dbFactory3.CreateDatabase();
db3.Insert();
db3.Delete();
}

  结果输出是和刚刚一模一样的。工厂模式的好处便是它符合开闭原则(对扩展开放,对修改封闭)。在刚刚的简单工厂模式中,如果我们扩展一个新的类,除了添加一个新的类之外,我们还需要去修改CrateDatabase(string dbType)这个方法,这是违反开闭原则的。在工厂模式中我们就不需要修改CreateDatabase这个方法,只需要实现工厂类这个接口便能完场扩展。缺点便是我们需要写更多的代码。

3.抽象工厂模式

  有了前面工厂模式的铺垫,抽象工厂应该不难理解吧。我看到过很多的博客都写着很多概念,什么产品层级,产品族,抽象产品等等,感觉不是特别容易理解。我的理解是这样的:把多个不同的工厂再抽象出来,再用一个抽象工厂(超级工厂)来创建这些工厂。也就是说抽象工厂是工厂的工厂。为了说明这个模式我想出了一个例子(其实我在工作中没有遇到过使用抽象工厂的例子):

  操作系统有Windows操作系统,Linux操作系统。每个操作系统都可以启动关闭。于是我们就创建一个操作系统工厂,用来创建(安装)这些操作系统,方法和上面的创建数据库工厂是一样的。

    // 操作系统具有的操作
public interface IOpSystem
{
void Start();
void Shutdown();
} // 操作系统工厂
public interface IOpSystemFactory
{
IOpSystem InstallSystem();
} // windows操作系统
public class WindowsSystem : IOpSystem
{
public void Shutdown()
{
Console.WriteLine("windows shutdown");
} public void Start()
{
Console.WriteLine("windows start");
}
} // linux操作系统
public class LinuxSystem : IOpSystem
{
public void Shutdown()
{
Console.WriteLine("linux shutdown");
} public void Start()
{
Console.WriteLine("linux start");
}
} // windows操作系统工厂,用来创建windows系统实例
public class WindowsFactory : IOpSystemFactory
{
public IOpSystem InstallSystem()
{
return new WindowsSystem();
}
} // linux操作系统工厂,用来创建linux系统实例
public class LinuxFactory : IOpSystemFactory
{
public IOpSystem InstallSystem()
{
return new LinuxSystem();
}
}

  我们可以看到操作系统工厂和数据库工厂是完全两个不同的工厂。假设一台服务器上需要安装操作系统和数据库,我们便可以用一个超级工厂来把这两个不同的工厂抽象出来。

    public interface ISuperFactory
{
IDatabaseFactory InstallDB();
IOpSystemFactory InstallOpSystem();
}

  然后我们定义一个具体的服务器类来实现这个超级工厂,在接口的实现中我们让这个服务器类安装windows system和mysql db。

    public class ServerWithWindowsAndMySql : ISuperFactory
{
public IDatabaseFactory InstallDB()
{
return new MySqlFactory();
} public IOpSystemFactory InstallOpSystem()
{
return new WindowsFactory();
}
}

  最后在Main函数中调用看看。

        static void Main(string[] args)
{
ISuperFactory server1 = new ServerWithWindowsAndMySql();
server1.InstallDB().CreateDatabase().Delete();
server1.InstallDB().CreateDatabase().Insert();
server1.InstallOpSystem().InstallSystem().Start();
server1.InstallOpSystem().InstallSystem().Shutdown();
}

  下面是运行结果。

  我们可以看到实现了超级工厂的服务器类同时拥有了创建数据库和安装操作系统的功能。这就是抽象工厂的用法。我们来看看抽象工厂的优缺点。优点:

  1.实现了不同工厂之间的解耦。

  缺点:

  1.代码量成倍的增加

  2.抽象工厂并不符合开闭原则。如果这个时候我们需要在超级工厂中添加一个新的工厂,那么具体类也必须要作出修改。

4.总结

  工厂模式同样是设计模式中比较常用而且比较容易理解(抽象工厂除外)的设计模式。同时也能加深我们对面向对象中“多态”这个概念的理解:我们只需要关注接口中方法的声明,不用知道具体类有什么方法方法如何实现。换句话说我们只需要声明了一个接口,便可以直接调用接口的方法,当然前提是接口必须由实现该接口的具体类来实例化。同时我们在工作中也必须对设计模式的使用稍加思考,只有我们需要去使用这个设计模式的时候才去使用,如果我们为了使用设计模式而去使用设计模式,我们反而会得到糟糕的效果。

C#设计模式 —— 工厂模式的更多相关文章

  1. .NET设计模式: 工厂模式

    .NET设计模式: 工厂模式(转) 转自:http://www.cnblogs.com/bit-sand/archive/2008/01/25/1053207.html   .NET设计模式(1): ...

  2. 【设计模式】Java设计模式 -工厂模式

    [设计模式]Java设计模式 -工厂模式 不断学习才是王道 继续踏上学习之路,学之分享笔记 总有一天我也能像各位大佬一样 一个有梦有戏的人 @怒放吧德德 分享学习心得,欢迎指正,大家一起学习成长! 目 ...

  3. [Head First设计模式]饺子馆(冬至)中的设计模式——工厂模式

    系列文章 [Head First设计模式]山西面馆中的设计模式——装饰者模式 [Head First设计模式]山西面馆中的设计模式——观察者模式 [Head First设计模式]山西面馆中的设计模式— ...

  4. javascript 设计模式-----工厂模式

    所谓的工厂模式,顾名思义就是成批量地生产模式.它的核心作用也是和现实中的工厂一样利用重复的代码最大化地产生效益.在javascript中,它常常用来生产许许多多相同的实例对象,在代码上做到最大的利用. ...

  5. JavaScript设计模式——工厂模式

    工厂模式:是一种实现“工厂”概念的面上对象设计模式.实质是定义一个创建对象的接口,但是让实现这个接口的类来决定实例化哪个类.工厂方法让类的实例化推迟到子类中进行.创建一个对象常常需要复杂的过程,所以不 ...

  6. 10.Java设计模式 工厂模式,单例模式

    Java 之工厂方法和抽象工厂模式 1. 概念 工厂方法:一抽象产品类派生出多个具体产品类:一抽象工厂类派生出多个具体工厂类:每个具体工厂类只能创建一个具体产品类的实例. 即定义一个创建对象的接口(即 ...

  7. 学习:java设计模式—工厂模式

    一.工厂模式主要是为创建对象提供过渡接口,以便将创建对象的具体过程屏蔽隔离起来,达到提高灵活性的目的. 工厂模式在<Java与模式>中分为三类: 1)简单工厂模式(Simple Facto ...

  8. 设计模式——工厂模式 (C++实现)

    软件领域中的设计模式为开发人员提供了一种使用专家设计经验的有效途径.设计模式中运用了面向对象编程语言的重要特性:封装.继承.多态,真正领悟设计模式的精髓是可能一个漫长的过程,需要大量实践经验的积累. ...

  9. Java设计模式---工厂模式(简单工厂、工厂方法、抽象工厂)

    工厂模式:主要用来实例化有共同接口的类,工厂模式可以动态决定应该实例化那一个类.工厂模式的形态工厂模式主要用一下几种形态:1:简单工厂(Simple Factory).2:工厂方法(Factory M ...

  10. 设计模式——工厂模式(Factory)

    要想正确理解设计模式,首先必须明白它是为了解决什么问题而提出来的. 设计模式学习笔记 --Shulin 转载请注明出处:http://blog.csdn.net/zhshulin 1.概念 工厂模式定 ...

随机推荐

  1. CSS属性之relative

    0.相对定位relative特点 相对定位relative元素总是会占据位置,所占据的位置是在relative元素没有设置left/top/right/bottom属性时的位置: 相对定位relati ...

  2. 简析 Tomcat 、Nginx 与 Apache 的区别

    简析 Tomcat .Nginx 与 Apache 的区别 本文讲的是简析 Tomcat .Nginx 与Apache的区别, 经常在用 apache 和 tomcat 等这些服务器,可是总感觉还是不 ...

  3. Vue小案例(一)

    案例需求: 创建一个品牌展示表格,表头有编号(id),品牌名称(name),创建时间(time)和操作,需要实现的功能是对数据的增删操作,和时间的格式化. 思路分析:在开发之前需要想清楚要用到Vue中 ...

  4. BIEE总结

    一,数据仓库,BI涉及到的相关概念  1.DW:    即数据仓库(Data Warehouse),是一个面向主题的(Subject Oriented).集成的(Integrated).相对稳定的(N ...

  5. select server

    server with select #include<stdio.h> #include<sys/types.h> #include<sys/socket.h> ...

  6. Linux下调节CPU使用的几种方法

    一,使用taskset充分利用多核cpu,让cpu的使用率均衡到每个cpu上 #taskset-p,    设定一个已存在的pid,而不是重新开启一个新任务-c,    指定一个处理,可以指定多个,以 ...

  7. TMG 2010 使用脚本来导入URL集和域名集

    作为一个网管,相信有领导叫你限制员工上网的情况,例如只限制员工访问某些网站.在禁止的网站数量少的时候,添加URL集或者域名集是一件很简单的事情,如果禁止的网站数量多达1500个呢?如果再使用ISA S ...

  8. 6 Dockerfile指令详解 && ENTRYPOINT 指令

    ENTRYPOINT 的格式和 RUN 指令格式一样,分为 exec 格式和 shell 格式. ENTRYPOINT 的目的和 CMD 一样,都是在指定容器启动程序及参数. ENTRYPOINT 在 ...

  9. 转贴:如何学好C++语言.docx

    不知道哪里转的.呵呵 抱歉 C++是最难的语言.这个世界上最难的编程语言可能非C++莫属了.你千万不要以为几天就可以学好C++,C++的学习曲线是相当BT的,你可以看看这篇文章.C++是一门很自由的语 ...

  10. iOS测试基础(命令篇)-iPhone型号及其他信息

    首先安装libimobiledevice和ideviceinstaller brew uninstall ideviceinstaller brew uninstall libimobiledevic ...