工厂方法模式
/**
* 根据品牌英文名称获取各品牌实例对象
* @param englishName
* @return
*/
public static Brand getInstance(String englishName){
if(ADIDAS.equals(englishName)){
return new Adidas();
}else if(NIKE.equals(englishName)){
return new Nike();
}else if(DONG_FENG.equals(englishName)){
return new DongFeng();
}else if(HONG_QI.equals(englishName)){
return new HongQi();
}else {
throw new RuntimeException(englishName+ "未能匹配到实例化对象!");
}
}
这是简单工厂模式的工厂类中根据品牌英文名称获取各品牌实例对象的方法,由于这个例子非常的简单,在现实业务中远远不仅于此,所以就会去修改代码以便于实现需求,这样就违背了开闭原则。
所以有了工厂方法模式,使得工厂类可以被子类继承,这样在简单工厂模式里集中在工厂方法上的压力可以由工厂方法模式里不同的工厂子类来分担。
public abstract class BrandFactory {
/**
* 获取可生产的品牌
*/
public abstract Brand[] getBrand();
}
public class ChinaBrandFactory extends BrandFactory{
/**
* 由子类来决定实现哪一个实例
* @return
*/
@Override
public Brand[] getBrand() {
return new Brand[]{new DongFeng(),new HongQi()};
}
}
public class ForeignBrandFactory extends BrandFactory{
/**
* 由子类来决定实现哪一个实例
* @return
*/
@Override
public Brand[] getBrand() {
return new Brand[]{new Adidas(),new Nike()};
}
}
测试
public class FactoryTest {
static void print(Brand[] brands){
for (Brand brand : brands) {
System.out.println(brand.getName());
}
}
public static void main(String[] args) {
ChinaBrandFactory chinaBrandFactory = new ChinaBrandFactory();
Brand[] chinaBrand = chinaBrandFactory.getBrand();
System.out.println("中国品牌有:");
print(chinaBrand);
ForeignBrandFactory foreignBrandFactory = new ForeignBrandFactory();
Brand[] foreignBrand = foreignBrandFactory.getBrand();
System.out.println("外国品牌有:");
print(foreignBrand);
}
}
中国品牌有:
东风
红旗
外国品牌有:
阿迪达斯
耐克
优缺点
工厂方法中,我们把生成所需的实例延迟,就是通过对应的工厂子类来生成对应的实例,这样就做到了无论需要增加多少实例,都可以通过增加子工厂实现类来实现,这种设计方式符合 “开闭”原则。缺点就是当实例过多的时候,需要定义很多实例对应的子工厂类。