工厂模式
核心本质:
- 实例化对象不使用new,用工厂方法代替
- 将选择实现类,创建对象统一管理和控制。从而将调用者跟我们的实现类解耦
详细分类:
- 简单工厂模式:用来生产同一等级结构中的任意产品(对于增加新的产品,需要修改已有代码)
- 工厂方法模式:用来生产同一等级结构中的固定产品(支持增加任意产品)
- 抽象工厂模式:围绕一个超级工厂创建其他工厂。该超级工厂又称为其他工厂的工厂。
满足OOP七大原则中的三个:
- 开闭原则: 一个软件的实体应当对扩展开放,对修改关闭
- 依赖倒转原则: 要针对接口编程,不要针对实现编程
- 迪米特法则: 只与你直接的朋友通信,而避免和陌生人通信
一、简单工厂模式(静态工厂模式)
用来生产同一等级结构中的任意产品(对于增加新的产品,需要扩展已有代码)
客户自己不去new车(相当于用户自己创造了车,如果车有许多属性,例如发动机,轮子等,用户就成了生产车间),使用工厂模式让用户只用从CarFatory取车,很大程度上降低了消费者和生产者的耦合度
public interface Car{
void name();
}
public class Aodi implements Car{
@Override
public void name() {
// TODO Auto-generated method stub
System.out.println("奥迪车");
}
}
public class Baoma implements Car{
@Override
public void name() {
// TODO Auto-generated method stub
System.out.println("宝马车");
}
}
//静态(简单)工厂模式
public class CarFactory {
// 方法一: 不满足开闭原则
public static Car getCar(String car){
if(car.equals("宝马")){
return new Baoma();
}else if(car.equals("奥迪")){
return new Aodi();
}else {
return null;
}
}
//方法二:
public static Car getBaoma() {
return new Baoma();
}
public static Car getAodi() {
return new Aodi();
}
}
public class Customer {
public static void main(String[] args) {
// 接口,所有的实现类
// Car car = new WuLing();
// Car car1 = new Tesla();
// 2、使用工厂创建
Car car = CarFactory.getCar("wuling");
Car car1 = CarFactory.getCar("tesila");
car.name();
car1.name();
}
}
注:大多数情况下用的都是简单工厂模式,这种模式仍有不足,如果再增加一辆车,则会修改CarFactory.java
的getCar方法,违反了开闭原则,(扩展原有代码,不应该修改)
二、工厂方法模型
用来生产同一等级结构中的固定产品(支持增加任意产品)
我们新建一个CarFactory的接口,然后为每种Car都建一个Factory类。这样就可以使得每次新加入一种车时,只为这种车建立一个对应的工厂就行,不会影响到原来的代码。
public interface Car{
void name();
}
public class Bench implements Car{
@Override
public void name() {
System.out.println("奔驰车");
}
}
public class Baoma implements Car{
@Override
public void name() {
System.out.println("宝马车");
}
public interface CarFactory {
Car getCar();
}
//奔驰工厂
public class BenchFactory implements CarFactory{
@Override
public Car getCar() {
return new Bench();
}
}
//宝马工厂
public class BaomaFactory implements CarFactory{
@Override
public Car getCar() {
return new Baoma();
}
}
public class Customer {
public static void main(String[] args) {
Car car = new BenchFactory().getCar();
car.name();
}
}
优点:
下次再加入新品牌,只需要新建一个 xxxFactory 就行,不会影响到别的工厂。
缺点:
代码量加大,管理复杂,结构复杂,实际业务一般使用简单工厂模式
总结:
不一定要符合设计原则,要根据实际情况加以分析取舍,只需要新建一个 DazhongFactory 就行,不会影响到别的工厂。
缺点:代码量加大,管理复杂,结构复杂,实际业务一般使用简单工厂模式
总结:不一定要符合设计原则,要根据实际情况加以分析取舍