工厂模式,适用于创建复杂的对象的地方,若可直接用new完成对象创建则可无需使用工厂模式
工厂模式的主要组成:
抽象产品类:
package ban.com;
public abstract class Product {
abstract void method();
}
具体产品类A:
package ban.com;
public class ConcreteProductCup extends Product {
@Override
void method() {
System.out.println("Cup");
}
}
具体产品类B:
package ban.com;
public class ConcreteProductSpoon extends Product {
@Override
void method() {
System.out.println("Spoon");
}
}
抽象工厂类:
package ban.com;
public abstract class Factory {
public abstract Product createProduct();
}
具体工厂类:
package ban.com;
public class ConcreteFactory extends Factory{
@Override
public Product createProduct(){
return new ConcreteProductSpoon();
}
}
客户类:
package ban.com;
public class Client {
public static void main(String[] args) {
Factory factory=new ConcreteFactory();
factory.createProduct().method();
}
}
执行打印的数据为Spoon,很标准的工厂模式,要是像创建Cup对象,可以直接在创建一个工厂实现类生成Cup对象。
package ban.com;
public class ConcreteFactory extends Factory{
@Override
public Product createProduct(){
return new ConcreteProductCup();
}
}
工厂模式主要分为四个模块:
1、抽象工厂:工厂模式的核心
2、抽象产品:用于工厂方法创建的父类
3、具体工厂类的实现:具体的创建逻辑
4、具体产品类的实现:产品的特有逻辑
这样看上去,需要那个就创建那个工厂的实现类,但是代码比较多,也不简洁,这样我们可以根据反射的方式简洁的来生产具体产品对象,这里会用到泛型的部分(以后会更新泛型部分的知识)
更改抽象工厂:
package ban.com;
public abstract class Factory {
public abstract <T extends Product> T createProduct(Class<T> clz);
}
T为继承Product的泛型,返回值必须是Product的子类,传入的clz即为类对象
具体工厂实现:
package ban.com;
public class ConcreteFactory extends Factory{
@Override
public <T extends Product> T createProduct(Class<T> clz) {
Product product=null;
try {
//通过反射获取对象实例
product=(Product) Class.forName(clz.getName()).newInstance();
} catch (InstantiationException | IllegalAccessException
| ClassNotFoundException e) {
e.printStackTrace();
}
return (T) product;//需是Product的子类
}
}
这样就可以保证直接传入所需类的名称就可以获取相应的对象,更改Client:
package ban.com;
public class Client {
public static void main(String[] args) {
Factory factory=new ConcreteFactory();
factory.createProduct(ConcreteProductCup.class).method();
factory.createProduct(ConcreteProductSpoon.class).method();
}
}
打印结果就是:Cup Spoon
这样的好处是可以比较简洁、动态的生成所需要的对象,之前的一种方式成为多工厂方式,都可以使用