设计模式 -(3)工厂模式(factory pattern)
通常我们需要某个类的对象时,通过 new Class 的方式即可,但是通过工厂模式可以屏蔽创建对象的过程,具体细节交给工厂方法即可。
简单工厂模式
如下,有一个汽车接口 Car :
public interface Car {
void printName();
}
目前有奥迪和宝马两种汽车:
public class Audi implements Car{
@Override
public void printName() {
System.out.println("奥迪");
}
}
public class BMW implements Car{
@Override
public void printName() {
System.out.println("宝马");
}
}
现在有一个 CarFactory 的类专门生产汽车,可以根据car名称生产出对应的汽车:
public class CarFactory {
public static Car getCarByName(String name) {
Car car = null;
switch (name) {
case "audi":
car = new Audi();
break;
case "bmw":
car = new BMW();
break;
}
return car;
}
}
测试:
public class Test1 {
public static void main(String[] args) {
Car car = CarFactory.getCarByName("audi");
car.printName();
}
}
奥迪
如上:通过 CarFactory 获取 Car对象 可以屏蔽 Car 的实例化细节,只需要告诉 CarFactory 需要生产的Car 名称即可获得对应的 Car ,但是通过这种方式有很明显的问题,假设有其他新型的汽车需要生产,那么就需要更改 getCarByName 方法
不过可以通过 反射的方式解决此问题,例如:
CarFactory
public static Car getCarByName2(String name) {
Car car = null;
try {
car = (Car) Class.forName(name).newInstance();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
return car;
}
测试类:
public class Test1 {
public static void main(String[] args) {
Car car = CarFactory.getCarByName2("com.example.dp._03factory.Audi");
car.printName();
}
}
奥迪
另外可以将 com.example.dp._03factory.Audi 放置到配置文件中,每一个类名可以对应配置一个 id ,程序实例化 bean 时根据 id 实例化即可。
例如 spring 就是将 bean 信息配置在 *.xml 中
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="zhangsan" class="com.springtest.model.People">
</bean>
</beans>
获取 bean 时通过以下方式:
ClassPathXmlApplicationContext classPathXmlApplicationContext = new ClassPathXmlApplicationContext("beans.xml");
People zs = (People) classPathXmlApplicationContext.getBean("zhangsan");