工厂模式和抽象工厂模式之间的基本区别是什么?
当前回答
根据定义,我们可以拖出两者的差异:
工厂:接口用于创建对象,但子类决定实例化哪个类。对象的创建是在需要时完成的。
抽象工厂:抽象工厂模式充当一个超级工厂,它可以创建其他工厂。在抽象工厂模式中,接口负责创建一组相关对象或依赖对象,而不指定它们的具体类。
所以,在上面的定义中,我们可以强调一个特定的区别。也就是说,工厂模式负责创建对象,抽象工厂负责创建一组相关的对象;显然都是通过一个接口。
工厂模式:
public interface IFactory{
void VehicleType(string n);
}
public class Scooter : IFactory{
public void VehicleType(string n){
Console.WriteLine("Vehicle type: " + n);
}
}
public class Bike : IFactory{
public void VehicleType(string n) {
Console.WriteLine("Vehicle type: " + n);
}
}
public interface IVehicleFactory{
IFactory GetVehicleType(string Vehicle);
}
public class ConcreteVehicleFactory : IVehicleFactory{
public IFactory GetVehicleType(string Vehicle){
switch (Vehicle){
case "Scooter":
return new Scooter();
case "Bike":
return new Bike();
default:
return new Scooter();
}
}
class Program{
static void Main(string[] args){
IVehicleFactory factory = new ConcreteVehicleFactory();
IFactory scooter = factory.GetVehicleType("Scooter");
scooter.VehicleType("Scooter");
IFactory bike = factory.GetVehicleType("Bike");
bike.VehicleType("Bike");
Console.ReadKey();
}
}
工厂模式:
interface IVehicleFactory{
IBike GetBike();
IScooter GetScooter();
}
class HondaFactory : IVehicleFactory{
public IBike GetBike(){
return new FZS();
}
public IScooter GetScooter(){
return new FZscooter();
}
}
class HeroFactory: IVehicleFactory{
public IBike GetBike(){
return new Pulsur();
}
public IScooter GetScooter(){
return new PulsurScooter();
}
}
interface IBike
{
string Name();
}
interface IScooter
{
string Name();
}
class FZS:IBike{
public string Name(){
return "FZS";
}
}
class Pulsur:IBike{
public string Name(){
return "Pulsur";
}
}
class FZscooter:IScooter {
public string Name(){
return "FZscooter";
}
}
class PulsurScooter:IScooter{
public string Name(){
return "PulsurScooter";
}
}
enum MANUFACTURERS
{
HONDA,
HERO
}
class VehicleTypeCheck{
IBike bike;
IScooter scooter;
IVehicleFactory factory;
MANUFACTURERS manu;
public VehicleTypeCheck(MANUFACTURERS m){
manu = m;
}
public void CheckProducts()
{
switch (manu){
case MANUFACTURERS.HONDA:
factory = new HondaFactory();
break;
case MANUFACTURERS.HERO:
factory = new HeroFactory();
break;
}
Console.WriteLine("Bike: " + factory.GetBike().Name() + "\nScooter: " + factory.GetScooter().Name());
}
}
class Program
{
static void Main(string[] args)
{
VehicleTypeCheck chk = new VehicleTypeCheck(MANUFACTURERS.HONDA);
chk.CheckProducts();
chk= new VehicleTypeCheck(MANUFACTURERS.HERO);
chk.CheckProducts();
Console.Read();
}
}
其他回答
我认为我们可以通过查看Java8示例代码来理解这两者之间的区别:
interface Something{}
interface OneWhoCanProvideSomething {
Something getSomething();
}
interface OneWhoCanProvideCreatorsOfSomething{
OneWhoCanProvideSomething getCreator();
}
public class AbstractFactoryExample {
public static void main(String[] args) {
//I need something
//Let's create one
Something something = new Something() {};
//Or ask someone (FACTORY pattern)
OneWhoCanProvideSomething oneWhoCanProvideSomethingOfTypeA = () -> null;
OneWhoCanProvideSomething oneWhoCanProvideSomethingOfTypeB = () -> null;
//Or ask someone who knows soemone who can create something (ABSTRACT FACTORY pattern)
OneWhoCanProvideCreatorsOfSomething oneWhoCanProvideCreatorsOfSomething = () -> null;
//Same thing, but you don't need to write you own interfaces
Supplier<Something> supplierOfSomething = () -> null;
Supplier<Supplier<Something>> supplierOfSupplier = () -> null;
}
}
现在的问题是你应该使用哪种创造方式以及为什么: 第一种方式(没有模式,只是普通的构造函数):自己创建不是一个好主意,你必须做所有的工作,你的客户端代码绑定到特定的实现。
第二种方式(使用Factory模式):为您提供了可以传递任何类型的实现的好处,这些实现可以基于某些条件(可能是传递给创建方法的参数)提供不同类型的东西。
第三种方法(使用抽象工厂模式):这为您提供了更多的灵活性。您可以根据某些条件(可能是传递的参数)找到不同类型的创建者。
请注意,您总是可以通过将两个条件组合在一起来摆脱工厂模式(这稍微增加了代码的复杂性和耦合),我想这就是为什么我们很少看到抽象工厂模式的实际用例。
这些工厂的主要区别是什么时候你想用工厂做什么,什么时候你想使用它。
有时候,当你在做IOC(控制反转,例如构造函数注入)时,你知道你可以创建固体对象。如上面的水果示例所述,如果准备创建水果对象,可以使用简单的工厂模式。
但是很多时候,你不想创建实体对象,它们会在程序流的后面出现。但是配置告诉你你想在开始时使用什么样的工厂,而不是创建对象,你可以将从公共工厂类派生的工厂传递给IOC中的构造函数。
所以,我认为这也是关于对象的生命周期和创建。
点击这里查看:http://www.allapplabs.com/java_design_patterns/abstract_factory_pattern.htm 似乎Factory方法使用一个特定的类(不是抽象类)作为基类,而抽象工厂则使用一个抽象类。此外,如果使用接口而不是抽象类,结果将是抽象工厂模式的不同实现。
:D
工厂模式: 工厂生产iproduct实现
工厂模式: 一个工厂-工厂生产IFactories, IFactories反过来生产IProducts:)
[根据评论更新] 我之前写的至少在维基百科上是不正确的。抽象工厂就是一个简单的工厂接口。有了它,您可以在运行时切换工厂,以允许在不同的上下文中使用不同的工厂。例如针对不同操作系统的不同工厂、SQL提供者、中间件驱动程序等等。
基本的区别:
工厂:创建对象时不向客户端公开实例化逻辑。
工厂方法:定义用于创建对象的接口,但让子类决定实例化哪个类。Factory方法允许类延迟实例化到子类
抽象工厂:提供一个接口,用于创建一系列相关或依赖的对象,而无需指定它们的具体类。
AbstractFactory模式使用组合将创建对象的责任委托给另一个类,而Factory方法模式使用继承并依赖于派生类或子类来创建对象
来自oodesign的文章:
工厂类图:
例如:StaticFactory
public class ShapeFactory {
//use getShape method to get object of type shape
public static Shape getShape(String shapeType){
if(shapeType == null){
return null;
}
if(shapeType.equalsIgnoreCase("CIRCLE")){
return new Circle();
} else if(shapeType.equalsIgnoreCase("RECTANGLE")){
return new Rectangle();
} else if(shapeType.equalsIgnoreCase("SQUARE")){
return new Square();
}
return null;
}
}
非静态工厂实现FactoryMethod的例子在这篇文章中可用:
设计模式:工厂vs工厂方法vs抽象工厂
何时使用:客户端只需要一个类,并不关心它得到的是哪个具体实现。
工厂方法类digaram:
何时使用:客户端不知道在运行时需要创建什么具体的类,而只是想获得一个可以完成这项工作的类。
来自dzone的抽象工厂类图
何时使用:当您的系统必须创建多个产品系列,或者您希望提供一个产品库而不公开实现细节时。
以上文章中的源代码示例非常有助于清楚地理解这些概念。
相关SE问题与代码示例:
工厂模式。什么时候使用工厂方法?
差异:
抽象工厂类通常使用工厂方法来实现,但它们也可以使用原型来实现 设计开始使用工厂方法(不太复杂,更可定制,子类激增),然后向其他需要更多灵活性的创建模式(更灵活,更复杂)发展。 工厂方法通常在模板方法中调用。
其他有用的文章:
来自sourcemmaking的Factory_method
摘要工厂从sourcemmaking
来自journaldev的抽象工厂设计模式