设计模式---简单工厂模式 vs 工厂方法模式 vs 抽象工厂模式

这个是一直都不是很了解的两个设计模式已经他们之间的区别。

简单工厂模式

百度:

简单工厂模式是属于创建型模式,又叫做静态工厂方法(Static Factory Method)模式。

菜鸟教程:

应用实例
1、您需要一辆汽车,可以直接从工厂里面提货,而不用去管这辆汽车是怎么做出来的,以及这个汽车里面的具体实现。
2、Hibernate 换数据库只需换方言和驱动就可以。

优点
1、一个调用者想创建一个对象,只要知道其名称就可以了。
2、扩展性高,如果想增加一个产品,只要扩展一个工厂类就可以。
3、屏蔽产品的具体实现,调用者只关心产品的接口。

缺点:每次增加一个产品时,都需要增加一个具体类和对象实现工厂,使得系统中类的个数成倍增加,在一定程度上增加了系统的复杂度,同时也增加了系统具体类的依赖。这并不是什么好事。

使用场景
1、日志记录器:记录可能记录到本地硬盘、系统事件、远程服务器等,用户可以选择记录日志到什么地方。
2、数据库访问,当用户不知道最后系统采用哪一类数据库,以及数据库可能有变化时。
3、设计一个连接服务器的框架,需要三个协议,“POP3”、“IMAP”、“HTTP”,可以把这三个作为产品类,共同实现一个接口。

注意事项:作为一种创建类模式,在任何需要生成复杂对象的地方,都可以使用工厂方法模式。有一点需要注意的地方就是复杂对象适合使用工厂模式,而简单对象,特别是只需要通过
new 就可以完成创建的对象,无需使用工厂模式。如果使用工厂模式,就需要引入一个工厂类,会增加系统的复杂度。

实现如下

  1. 定义Product接口
public interface Product {
	void productFunction();
}
  1. 创建具体Product类,继承Product接口
public class ProductA implements Product {

	@Override
	public void productFunction() {
		System.out.println("Run Product A Function");
	}

}
public class ProductB implements Product {

	@Override
	public void productFunction() {
		System.out.println("Run Product B Function");
	}

}
  1. 创建工厂给出Product
public class ProductFactory {

	public Product getProduct(String productName) {
		switch (productName) {
		case "A":
			return new ProductA();
		case "B":
			return new ProductB();
		default:
			return new ProductA();
		}
	} 
}
  1. Test
public class ProductFactoryTest {

	public static void main(String[] args) {
		ProductFactory factory = new ProductFactory();
		Product a_product = factory.getProduct("A");
		Product b_product = factory.getProduct("B");
		
		a_product.productFunction();
		
		b_product.productFunction();
	}
}

UML 图
在这里插入图片描述

工厂方法模式

大话设计模式:

工厂方法模式:定义一个用于创建对象的接口,让子类决定实例化哪一个类。工厂方法使一个类的实例化延迟到其子类。

实现如下(主要是在简单工厂模式下对工厂进行抽象,创建一个工厂接口,然后根据具体产品创建具体的工厂,客户端只需要实例化具体的工厂)

工厂接口

public interface Factory {

	Product getProduct();
}

具体工厂类

public class AFactory implements Factory {

	@Override
	public Product getProduct() {
	    return new ProductA();
	}

}
public class BFactory implements Factory {

	@Override
	public Product getProduct() {
	    return new ProductB();
	}

}

Test

public class FactoryTest {

	public static void main(String[] args) {
		Factory aFactory = new AFactory();
		Factory bFactory = new BFactory();
		
		Product productA = aFactory.getProduct();
		Product productB = bFactory.getProduct();
		
		productA.productFunction();
		productB.productFunction();
	}
}

UML图
在这里插入图片描述

抽象工厂模式

大话设计模式:

抽象工厂模式,提供一个创建一系列相关或相互依赖对象的接口,而无需指定他们具体的类[DP]

菜鸟教程:

何时使用:系统的产品有多于一个的产品族,而系统只消费其中某一族的产品。
如何解决:在一个产品族里面,定义多个产品。
关键代码:在一个工厂里聚合多个同类产品。
优点:当一个产品族中的多个对象被设计成一起工作时,它能保证客户端始终只使用同一个产品族中的对象
缺点:产品族扩展非常困难,要增加一个系列的某一产品,既要在抽象的 Creator 里加代码,又要在具体的里面加代码

实现如下

  1. 定义多个产品接口
public interface Keyboard {

	void keybordFunction();
}
public interface Mouse {

	void mouseFunction();
}
  1. 实现不同产品类
public class HPKeyboard implements Keyboard {

	@Override
	public void keybordFunction() {
		System.out.println("This is HP keyboard");
	}

}

public class DellKeyboard implements Keyboard {

	@Override
	public void keybordFunction() {
		System.out.println("This is DEll keyboard");
	}

}

public class HPMouse implements Mouse {

	@Override
	public void mouseFunction() {
		System.out.println("This is HP mouse");
	}

}

public class DellMouse implements Mouse {

	@Override
	public void mouseFunction() {
		System.out.println("This is DEll mouse");
	}

}
  1. 定义工厂接口
public interface Factory {

	Keyboard getKeyboard();
	Mouse getMouse();
}

  1. 根据不同产品类型创建实现工厂接口的类
public class HPFactory implements Factory {

	@Override
	public Keyboard getKeyboard() {
		return new HPKeyboard();
	}

	@Override
	public Mouse getMouse() {
		return new HPMouse();
	}

}

public class DellFactory implements Factory {

	@Override
	public Keyboard getKeyboard() {
		return new DellKeyboard();
	}

	@Override
	public Mouse getMouse() {
		return new DellMouse();
	}

}
  1. Test
public class AbstractFactoryTest {

	public static void main(String[] args) {
		// 根据客户需要来选择工厂类型
		Factory factgFactory = new DellFactory();
		Keyboard keyboard = factgFactory.getKeyboard();
		Mouse mouse = factgFactory.getMouse();
		
		keyboard.keybordFunction();
		mouse.mouseFunction();
	}
}

UML图
在这里插入图片描述

简单工厂模式 + 反射 完善抽象工厂模式

我们可以用一个简单工厂来根据客户的需求生成不同类型的工厂,进而产出不同类型的产品。
反射可以做到根据 参数传进来的工厂类型 生成对应的工厂,而不是用switch 语句,这样就可以做到解耦。以后要增加工厂类型的话,需要 多一个工厂类型,修改ProductFactory,还有工厂类型的枚举类FactoryType。反射再挖深点就是AOP

ProductFactory

public class ProductFactory implements Factory {
	private Factory factory;

	public ProductFactory(FactoryType factoryType) throws Exception, IllegalAccessException, ClassNotFoundException {
		// 使用反射根据传进来的参数 创建对应的工厂实例    再更深挖下去的话可以用AOP
		factory = (Factory) Class.forName(factoryType.getClassPath()).newInstance();
	}
	
	
	@Override
	public Keyboard getKeyboard() {
		return factory.getKeyboard();
	}

	@Override
	public Mouse getMouse() {
		return factory.getMouse();
	}

}

FactoryType

public enum FactoryType {
	DellFactory("abstractFactory.DellFactory"),
	HPFactory("abstractFactory.HPFactory");
	
	private String mClassPath;
	
	private FactoryType(String classPath) {
		this.mClassPath = classPath;
	}
	
	public String getClassPath() {
		return mClassPath;
	}
}

Test

public class ProductFactoryTest {

	public static void main(String[] args) throws IllegalAccessException, ClassNotFoundException, Exception {
		Factory factory = new ProductFactory(FactoryType.DellFactory);
		factory.getKeyboard().keybordFunction();
		factory.getMouse().mouseFunction();
	}
}

Result

This is DEll keyboard
This is DEll mouse

总结

简单工厂模式 和 工厂模式方法都是对应只有一种产品类型。简单工厂模式的好处是客户不需要知道每个具体工厂的类型,只根据产品的名称来获得产品,所有具体实现都在一个简单工厂里。但是这样修改或者要增加产品就得每次都要修改这个简单工厂。工厂方法是对简单工厂模式的一个提高,它把简单工厂解耦出来,定义一个工厂接口,让客户根据产品来实例化工厂,如果是要修改或者增加产品,只需要多实现一个产品和具体的工厂。
抽象工厂则是对应多个产品类型的,具体的实现有点像工厂方法模式。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值