JAVA设计模式 - 简单工厂模式、工厂方法模式、抽象工厂模式

时间:2020-12-06 20:29:15

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

     普通工厂模式就是创建一个工厂类,创建并返回多个实现相同接口的类的实例。
例子:根据传递的类型生产不同的食物。
     有一个生产食物的接口:
/**
* 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() ;
}


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

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