简单工厂模式(静态工厂模式)

     普通工厂模式就是创建一个工厂类,创建并返回多个实现相同接口的类的实例。
例子:根据传递的类型生产不同的食物。
     有一个生产食物的接口:
/**
* Created by j on 2018/2/27.
*/
public interface Food {
    
    public static void creatFood();

}
  
   一个生产面条的实现类:
    
/**
* Created by j on 2018/2/27.
*/
public class Noodle implements Food {

    public static void creatFood() {
        System.out.println("生产面条");
    }
}

    一个生产大米的实现类:
/**
* Created by j on 2018/2/27.
*/
public class Rice implements Food {
    @Override
    public static void creatFood() {
        System.out.println("生产大米");
    }
}

 

  创建一个食物工厂:
/**
* Created by j on 2018/2/27.
*/
public class FoodFactory {

    public static Food getFood(String type) {
        if ("noodle".equals(type)) {
            return new Noodle();
        } else if ("rice".equals(type)) {
            return new Rice();
        } else {
            throw new NullPointerException("找不到需要的类型");
        }
    }
}

    最后创建一个测试类:
    
/**
* Created by kaijiyu on 2018/2/27.
*/
public class Test {

    public static void main(String[] args) {
        Food food = FoodFactory.getFood("noodle");
        food.creatFood();
    }

}

其实这样做的缺点很明显,虽然能够根据类型对应返回不同的实例,但是如果新加一个品种比如面包,就需要修改工厂类,违反了开闭原则,不利于维护。

工厂方法模式
    
    工厂方法模式是对简单工厂模式的升级,将工厂抽象出来,对每个产品创建一个工厂来专门生产,使其可以扩展,复合开闭原则。

JAVA设计模式 - 简单工厂模式、工厂方法模式、抽象工厂模式
    
食物类:
/**
* Created by j on 2018/2/28.
*/
public interface Food {

    public void getFoodName();

}

/**
* Created by j on 2018/2/28.
*/
public class Noodle implements Food {

    @Override
    public void getFoodName() {
        System.out.println("食物的名称是面条");
    }

}

/**
* Created by j on 2018/2/28.
*/
public class Rice implements Food {

    @Override
    public void getFoodName() {
        System.out.println("食物的名称是大米");
    }

}

工厂类:
/**
* Created by j on 2018/2/28.
*/
public interface FoodFactory {

    public Food createFood();
}

/**
* Created by j on 2018/2/28.
*/
public class NoodleFactory implements FoodFactory {
    @Override
    public Food createFood() {
        return new Noodle();
    }
}

/**
* Created by j on 2018/2/28.
*/
public class RiceFactory implements FoodFactory {
    @Override
    public Food createFood() {
        return new Rice();
    }
}

测试类:
/**
* Created by j on 2018/2/28.
*/
public class Test {
    public static void main(String[] args) {
        FoodFactory noodleFactory = new NoodleFactory();
        FoodFactory riceFactory = new RiceFactory();
        Food noodle = noodleFactory.createFood();
        Food rice = riceFactory.createFood();
        noodle.getFoodName();
        rice.getFoodName();
    }
}

工厂方法模式是对一种产品族的多种产品的生产,如果对于多产品族,比如说食物添加一个产品族,分成生的和熟的,这时代码就无法进行通用了。这时,就需要用到抽象工厂模式

抽象工厂模式
抽象工厂是工厂方法模式的升级版,用于多产品族多种产品的情况使用。

JAVA设计模式 - 简单工厂模式、工厂方法模式、抽象工厂模式
食物类:

public interface Food {

    public void getFoodName();

    public void getIsCooked();

}

public abstract class CookedFood implements Food{
    public void getIsCooked(){
        System.out.println("生产一个熟的食物");
    }
}

public abstract class RawFood implements Food{
    public void getIsCooked(){
        System.out.println("生产一个生的食物");
    }
}

public class CookedNoodle extends CookedFood {

    @Override
    public void getFoodName() {
        System.out.println("食物的名称是面条");
    }

}

public class CookedRice extends CookedFood {

    @Override
    public void getFoodName() {
        System.out.println("食物的名称是大米");
    }

}

public class RawNoodle extends RawFood {

    @Override
    public void getFoodName() {
        System.out.println("食物的名称是面条");
    }

}

public class RawRice extends RawFood {

    @Override
    public void getFoodName() {
        System.out.println("食物的名称是大米");
    }

}

工厂类:
public interface FoodFactory {

    public Food createCookedFood();
    public Food createRawFood();

}

public class NoodleFactory implements FoodFactory {

    @Override
    public CookedFood createCookedFood() {
        return new CookedNoodle();
    }

    @Override
    public Food createRawFood() {
        return new RawNoodle();
    }
}

public class RiceFactory implements FoodFactory {

    @Override
    public Food createCookedFood() {
        return new CookedRice();
    }

    @Override
    public Food createRawFood() {
        return new RawRice();
    }
}

测试类:
public class Test {
    public static void main(String[] args) {
        FoodFactory noodleFactory = new NoodleFactory();
        FoodFactory riceFactory = new RiceFactory();
        // 生产一个熟的面条
        Food noodle = noodleFactory.createCookedFood();
        // 生产一个生的大米
        Food rice = riceFactory.createRawFood();

        noodle.getIsCooked();
        noodle.getFoodName();

        rice.getIsCooked();
        rice.getFoodName();
    }
}

也可以通过反射的机制和简单工厂模式来将抽象工厂升级:
public class AbsFoodFactory {
    // 通过AbsFoodFactory.createFood(CookedNoodle.class); 调用
    public static Food createFood(Class clazz) throws Exception {
        return (Food)clazz.newInstance();
}


抽象工厂模式的优点在于封装性比较好,以接口的形式提供,不需要知道具体如何实现,全部由工厂类来负责创造。所有的约束条件在工厂内实现,不对外公开。只需要知道是哪个工厂就可以创造出想要的对象。

缺点在于产品族非常难以扩展,例如,如果需要增加一个颜色或半生不熟的产品族。那么代码不满足通用原则,需要全部修改,但是如果增加一个产品,比如面包,这样直接新添加一个面包工厂即可。

相关文章: