这篇文章简单介绍java工厂设计模式,用最简单的例子演示如何使用工厂模式,以及为什么要用工厂模式。
使用场景:
在开发中我们经常使用抽象类或者接口定义一类功能,通过具体的实现类实现。创建这些实现类的时候可以使用工厂类来简化代码,提高代码的扩展性。
代码演化:
不使用工厂模式
interface Animal {
void eat();
}
Class Dog implements Animal {
public void eat(){
System.out.println("吃骨头");
}
}
Class Cat implements Animal {
public void eat(){
System.out.println("吃鱼");
}
}
class MainClass {
private String anl = "dog";
public static void main(String args[]) {
Animal animal;
if ("dog".equals(anl)){
animal = new Dog();
} else if ("cat".equals(anl)){
animal = new Cat();
}
animal.eat();
}
}
使用简单工厂模式
在调用的时候都是使用new创建对象的,调用者不一定对Animal这个接口了解。所以我们可以在开发Animal的同时创建工厂类,这样调用的时候不需要写这么多if else,就能创建对象了。
interface Animal {
void eat();
}
Class Dog implements Animal {
public void eat(){
System.out.println("吃骨头");
}
}
Class Cat implements Animal {
public void eat(){
System.out.println("吃鱼");
}
}
class AnimalFactory {
public static Animal getAnimal(String anl) {
Animal animal;
if ("dog".equals(anl)){
animal = new Dog();
} else if ("cat".equals(anl)){
animal = new Cat();
}
return animal;
}
}
class MainClass {
public static void main(String args[]) {
Animal animal = AnimalFactory.getAnimal("dog");
animal.eat();
}
}
使用工厂方法模式
简单工厂模式最大的问题就是,每一次增加新的实现类的时候修改修改工厂类创建对象的方法,如果实现类比较多的时候,if else会非常的长。
这时候就演化出工厂方法模式:
就是想工厂类抽象化,每一个实现类对应一个工厂抽象类,调用者使用工厂抽象类(这个可以在配置文件中配置,这样修改工厂类不需要重新build工程)去创建对应的对象。
这种方式,在开发新的实现类的时候就可以开发新的对应的工厂实现类,不会影响以前的代码。
interface Animal {
void eat();
}
Class Dog implements Animal {
public void eat(){
System.out.println("吃骨头");
}
}
Class Cat implements Animal {
public void eat(){
System.out.println("吃鱼");
}
}
interface AnimalFactory {
Animal getAnimal();
}
class DogFactory implements AnimalFactory{
public Animal getAnimal() {
return new Dog();
}
}
class CatFactory implements AnimalFactory{
public Animal getAnimal() {
return new Cat();
}
}
class MainClass {
public static void main(String args[]) {
//DogFactory可以在配置文件中配置,通过放射的方式创建工厂类
Animal animal = DogFactory.getAnimal();
animal.eat();
}
}
抽象工厂模式
工厂方法模式也存在问题,就是如果一个借口有很多实现类,那么也就会有很多实现工厂类。这也是一种资源消耗。为了解决这个问题,就有了抽象工厂模式:
- 将所有的工厂类进行分类,每一个具体的工厂类都能创建一类对象。
当然抽象工厂类也有扩展性问题: - 扩展新的工厂类是很容易,但是对于已经有的工厂类,如果想要扩容让他创建新的对象,那就十分困难。 比如,我们将动物分成野生动物和宠物。那么DogFactory可以创建野生狗和宠物狗,CatFactory可以创建野生猫和宠物猫。那么新增新的工厂比如PigFactory是很容易的,但是假如又有一类新的Dog,那么DogFactory就很难创建它了。
interface Animal {
void eat();
}
Class PegDog implements Animal {
public void eat(){
System.out.println("吃骨头罐头");
}
}
Class WildDog implements Animal {
public void eat(){
System.out.println("吃骨头渣");
}
}
Class PegCat implements Animal {
public void eat(){
System.out.println("吃鱼饼干");
}
}
Class WildCat implements Animal {
public void eat(){
System.out.println("吃鱼骨头");
}
}
abstract class AbstractAnimalFactory {
abstract Animal getPegAnimal();
abstract Animal getWildAnimal();
}
class DogFactory extends AbstractAnimalFactory{
public Animal getPegAnimal() {
return new PegDog();
}
public Animal getWildAnimal() {
return new WildDog();
}
}
class CatFactory extends AbstractAnimalFactory{
public Animal getPegAnimal() {
return new PegCat();
}
public Animal getWildAnimal() {
return new WildCat();
}
}
class MainClass {
public static void main(String args[]) {
//DogFactory可以在配置文件中配置,通过放射的方式创建工厂类
Animal peg = DogFactory.getPegAnimal();
Animal wild = DogFactory.getWildAnimal();
peg.eat();
wild.eat();
}
}