这个是一直都不是很了解的两个设计模式已经他们之间的区别。
简单工厂模式
百度:
简单工厂模式是属于创建型模式,又叫做静态工厂方法(Static Factory Method)模式。
菜鸟教程:
应用实例:
1、您需要一辆汽车,可以直接从工厂里面提货,而不用去管这辆汽车是怎么做出来的,以及这个汽车里面的具体实现。
2、Hibernate 换数据库只需换方言和驱动就可以。优点:
1、一个调用者想创建一个对象,只要知道其名称就可以了。
2、扩展性高,如果想增加一个产品,只要扩展一个工厂类就可以。
3、屏蔽产品的具体实现,调用者只关心产品的接口。缺点:每次增加一个产品时,都需要增加一个具体类和对象实现工厂,使得系统中类的个数成倍增加,在一定程度上增加了系统的复杂度,同时也增加了系统具体类的依赖。这并不是什么好事。
使用场景:
1、日志记录器:记录可能记录到本地硬盘、系统事件、远程服务器等,用户可以选择记录日志到什么地方。
2、数据库访问,当用户不知道最后系统采用哪一类数据库,以及数据库可能有变化时。
3、设计一个连接服务器的框架,需要三个协议,“POP3”、“IMAP”、“HTTP”,可以把这三个作为产品类,共同实现一个接口。注意事项:作为一种创建类模式,在任何需要生成复杂对象的地方,都可以使用工厂方法模式。有一点需要注意的地方就是复杂对象适合使用工厂模式,而简单对象,特别是只需要通过
new 就可以完成创建的对象,无需使用工厂模式。如果使用工厂模式,就需要引入一个工厂类,会增加系统的复杂度。
实现如下
- 定义Product接口
public interface Product {
void productFunction();
}
- 创建具体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");
}
}
- 创建工厂给出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();
}
}
}
- 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 里加代码,又要在具体的里面加代码
实现如下
- 定义多个产品接口
public interface Keyboard {
void keybordFunction();
}
public interface Mouse {
void mouseFunction();
}
- 实现不同产品类
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");
}
}
- 定义工厂接口
public interface Factory {
Keyboard getKeyboard();
Mouse getMouse();
}
- 根据不同产品类型创建实现工厂接口的类
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();
}
}
- 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
总结
简单工厂模式 和 工厂模式方法都是对应只有一种产品类型。简单工厂模式的好处是客户不需要知道每个具体工厂的类型,只根据产品的名称来获得产品,所有具体实现都在一个简单工厂里。但是这样修改或者要增加产品就得每次都要修改这个简单工厂。工厂方法是对简单工厂模式的一个提高,它把简单工厂解耦出来,定义一个工厂接口,让客户根据产品来实例化工厂,如果是要修改或者增加产品,只需要多实现一个产品和具体的工厂。
抽象工厂则是对应多个产品类型的,具体的实现有点像工厂方法模式。