简单工厂:
是由一个工厂对象决定创建出哪一种产品类的实例。
A实例调用B实例的方法,称为A依赖于B。如果使用new关键字来创建一个B实例(硬编码耦合),然后调用B实例的方法。一旦系统需要重构:需要使用C类来代替B类时,程序不得不改写A类代码。而用工厂模式则不需要关心B对象的实现、创建过程。
//抽象产品
public abstract class Car
{
public abstract void Drive();
}
//具体产品
public class Benz : Car
{
public override void Drive()
{
Console.WriteLine("开奔驰");
}
}
//具体产品
public class Bmw : Car
{
public override void Drive()
{
Console.WriteLine("开宝马");
}
}
//简单工厂
public class Driver
{
public static Car DriveCar(string carName)
{
Car cc;
if (carName == "奔驰")
{
cc = new Benz();
}
else
{
cc = new Bmw();
}
return cc;
}
}
//客户
public class Boss
{
Car cars = Driver.DriveCar("奔驰");
cars.Drive();
Car cars2 = Driver.DriveCar("宝马");
cars2.Drive();
}
使用简单工厂模式的优势:
让对象的调用者和对象创建过程分离,当对象调用者需要对象时,直接向工厂请求即可。从而避免了对象的调用者与对象的实现类以硬编码方式耦合,以提高系统的可维护性、可扩展性。工厂模式也有一个小小的缺陷:当产品修改时,工厂类也要做相应的修改,违反了开-闭原则。如上例,需要增加 奥迪 时,需要修改工厂类 Driver
简单工厂模式适用于业务简单的情况下或者具体产品很少增加的情况。而对于复杂的业务环境可能不太适应了。这就应该由工厂方法模式来出场了!!
工厂方法:
不在工厂类中进行逻辑判断,程序可以为不同产品类提供不同的工厂,不同的工厂类和产不同的产品。当使用工厂方法设计模式时,对象调用者需要与具体的工厂类耦合
//抽象产品
public abstract class Car
{
public abstract void Drive();
}
//具体产品
public class Benz : Car
{
public override void Drive()
{
Console.WriteLine("开奔驰");
}
}
//具体产品
public class Bmw : Car
{
public override void Drive()
{
Console.WriteLine("开宝马");
}
}
//抽象工厂
public abstract class Driver
{
public abstract Car DriveCar();
}
//具体工厂
public class DriverBenz: Driver
{
public override Car DriveCar()
{
Car c = new Benz();
return c;
}
}
//具体工厂
public class DriverBmz : Driver
{
public override Car DriveCar()
{
Car c = new Bmw();
return c;
}
}
//客户
public class Boss
{
Driver dbenz = new DriverBenz();
Car c = dbenz.DriveCar();
c.Drive();
}
使用开闭原则来分析下工厂方法模式。当有新的产品产生时,只要按照抽象产品角色、抽象工厂角色提供的合同来生成,那么就可以被客户使用,而不必去修改任何已有的代码。(即当有新产品时,只要创建基础抽象产品;新建具体工厂继承抽象工厂;而不用修改任何一个类)工厂方法模式是完全符合开闭原则的!
抽象工厂模式:
先来认识下什么是产品族: 位于不同产品等级结构中,功能相关联的产品组成的家族。
图中的BmwCar和BenzCar就是两个产品树(产品等级结构);而如图所示的BenzSportsCar和BmwSportsCar就是一个产品族。他们都可以放到跑车家族中,因此功能有所关联。同理BmwBussinessCar和BenzBusinessCar也是一个产品族。
可以这么说,它和工厂方法模式的区别就在于需要创建对象的复杂程度上。而且抽象工厂模式是三个里面最为抽象、最具一般性的。抽象工厂模式的用意为:给客户端提供一个接口,可以创建多个产品族中的产品对象。
而且使用抽象工厂模式还要满足一下条件:
1.系统中有多个产品族,而系统一次只可能消费其中一族产品
2.同属于同一个产品族的产品以其使用。
来看看抽象工厂模式的各个角色(和工厂方法的如出一辙):
抽象工厂角色: 这是工厂方法模式的核心,它与应用程序无关。是具体工厂角色必须实现的接口或者必须继承的父类。它由抽象类或者接口来实现。
具体工厂角色:它含有和具体业务逻辑有关的代码。由应用程序调用以创建对应的具体产品的对象。
抽象产品角色:它是具体产品继承的父类或者是实现的接口。一般有抽象类或者接口来实现。
具体产品角色:具体工厂角色所创建的对象就是此角色的实例。由具体的类来实现。
//抽象产品
public abstract class BenzCar
{
public abstract void Drive();
}
//具体产品
public class BenzSportCar : BenzCar
{
public override void Drive()
{
Console.WriteLine("开奔驰跑车");
}
}
//具体产品
public class BenzBusinessCar : BenzCar
{
public override void Drive()
{
Console.WriteLine("开奔驰商务车");
}
}
//抽象产品
public abstract class BmwCar
{
public abstract void Drive();
}
//具体产品
public class BmwSportCar : BmwCar
{
public override void Drive()
{
Console.WriteLine("开宝马跑车");
}
}
//具体产品
public class BmwBusinessCar : BmwCar
{
public override void Drive()
{
Console.WriteLine("开宝马商务车");
}
}
//抽象工厂
public abstract class Driver
{
public abstract BenzCar DriveBenzCar();
public abstract BmwCar DriveBmwCar();
}
//具体工厂
public class SportDriver : Driver
{
public override BenzCar DriveBenzCar()
{
BenzSportCar benzsport = new BenzSportCar();
return benzsport;
}
public override BmwCar DriveBmwCar()
{
BmwSportCar bmwsport = new BmwSportCar();
return bmwsport;
}
}
//具体工厂
public class BusinessDriver : Driver
{
public override BenzCar DriveBenzCar()
{
BenzBusinessCar benzbusiness = new BenzBusinessCar();
return benzbusiness;
}
public override BmwCar DriveBmwCar()
{
BmwBusinessCar bmwbusiness = new BmwBusinessCar();
return bmwbusiness;
}
}
//客户
public class Boss
{
Driver dbenz = new SportDriver();
BenzCar c = dbenz.DriveBenzCar();
c.Drive();
}
所以抽象工厂模式一般用于具有产品树和产品族的场景下。
抽象工厂模式的缺点:
如果需要增加新的产品树,那么就要新增三个产品类,比如VolvoCar,VolvoSportCar,VolvoBusinessCar,并且要修改三个工厂类。这样大批量的改动是很丑陋的做法。
所以可以用简单工厂配合反射来改进抽象工厂。
首先记住,他们的目的都是靠工厂生成对象。
简单工厂:一个工厂,生成各种不同class的对象。一般来说这些对象应该某一基类或接口关联的,除非你牛就声明返回Object。
工厂方法:多种工厂,按需选择一工厂生成对象。这些工厂之间靠拥有同一接口方法关联,所以叫“工厂方法”模式。
抽象工厂:多种工厂协作,生成多种class关系不大的对象。常见的处理是把这些对象整体打包提供给你。后两者主要区别在一个生成某一基类下的对象,另一个可以根据不同基类生成对象,关注点在“不同基类”。
区别
简单工厂 : 用来生产同一等级结构中的任意产品。(对于增加新的产品,无能为力)
工厂方法:用来生产同一等级结构中的固定产品。(支持增加任意产品)
抽象工厂:用来生产不同产品族的全部产品。(对于增加新的产品,无能为力;支持增加产品族)