工厂模式
作用:封装和管理类的创建,终极目的是为了解耦,实现创建者和调用者的分离。这种类型的属于设计模式中创建型模式,它提供了一种创建对象的最佳方式。
工厂模式的定义:定义一个创建对象的接口,让其子类自己决定实例化哪一个工厂类,工厂模式使其创建过程延迟到子类进行。这满足创建型模式中所要求的“创建与使用相分离”的特点。
工厂模式有三种分别是:简单工厂模式(静态工厂模式),工厂方法模式,抽象工厂模式
简单工厂模式
将创建对象的任务交给工厂类让工厂决定创建何种对象调用即可。
举个例子:
点pizza
在没有用工厂模式时:
class OrderPizza1{
public Pizza pizza ;
public OrderPizza(int type){
if(type==1){
pizza = new BigPizza();
System.out.println("您订购的是大披萨");
}else if(type==2){
pizza = new SmallPizza();
System.out.println("您订购的是小披萨");
}else if(type==3){
pizza = new ChessPizza();
System.out.println("您订购的是芝士披萨");
}else {
System.out.println("没有该类型的披萨");
throw new RuntimeException("披萨类型错误");
}
pizza.prepare();
pizza.cake();
pizza.cut();
pizza.box();
}
}
这个门店实现订购多种pizza,但当我们pizza的种类新增时,就要创建新pizza类,并修改判断,如果只有一个门店类,就要修改一次,但是,当门店类一多起来,所要修改的地方就会异常冗余和繁琐。这显然是不合理的。
采用简单工厂模式,将创建这些pizza的任务封装成一个工厂类,前台与该类发生联系,之后只要向其传入某个pizza的类型信息,工厂类创建相应对象,并返回给它即可。当之后新增加一个pizza类,只要修改工厂类即可。
class PizzaFactory{
public Pizza createPizza(int type){
Pizza pizza ;
if(type==1){
pizza = new BigPizza();
System.out.println("您订购的是大披萨");
}else if(type==2){
pizza = new SmallPizza();
System.out.println("您订购的是小披萨");
}else if(type==3){
pizza = new ChessPizza();
System.out.println("您订购的是芝士披萨");
}else {
System.out.println("没有该类型的披萨");
throw new RuntimeException("披萨类型错误");
}
pizza.prepare();
pizza.cake();
pizza.cut();
pizza.box();
return pizza;
}
}
class OrderPizza3{
// 采用聚合的方式
PizzaFactory pizzaFactory;
public OrderPizza3(PizzaFactory pizzaFactory){
this.pizzaFactory = pizzaFactory;
}
public void getPizza(int type){
Pizza pizza = pizzaFactory.createPizza(type);//拿到需要创建的pizza类型
if(pizza==null){
System.out.println("预定失败");
return;
}
System.out.println("预定成功!");
}
}
简单工厂模式的弊端:
违背了开闭原则,系统扩展困难,一旦增加新产品不得不修改工厂逻辑,在产品类型较多时,可能造成逻辑过于复杂。
工厂方法模式
定义一个用于创建对象的接口,让子类决定实例化哪一个类。工厂方法使一个类的实例化延迟到其子类。
/**
* 工厂方法模式
*/
abstract class PizzaFactory3{
//让子类自己实现创建
public abstract Pizza createPizza(int type);
// 通过构造方法决定类型
public PizzaFactory3(int type){
Pizza pizza = createPizza(type);
pizza.prepare();
pizza.cake();
pizza.cut();
pizza.box();
}
}
class BJFactory extends PizzaFactory3{
public BJFactory(int type) {
super(type);
}
@Override
public Pizza createPizza(int type) {
if(type==1){
return new BigPizza();
}else if(type==2){
return new SmallPizza();
}else {
throw new RuntimeException("当前店面没有该类");
}
}
}
class SHFactory extends PizzaFactory3{
public SHFactory(int type) {
super(type);
}
@Override
public Pizza createPizza(int type) {
if(type==3){
return new ChessPizza();
}else {
throw new RuntimeException("当前店面没有该类");
}
}
}
抽象工厂模式
抽象工厂模式就是工厂方法模式plus版
抽象工厂模式可以使得具体工厂类可以创建多个大类(不同产品)的对象,不过还是需要修改抽象工厂和具体工厂的代码,违反开闭原则。
public interface AbstractFactory {
Pizza createPizza(String orderType);
Sauce createSauce(String orderType);
//创建蔬菜的方法
Vegetable createVegetable(String orderType);
}
public class BJFactory implements AbstractFactory {
@Override
public Pizza createPizza(String orderType) {
System.out.println("~~~使用的是抽象工厂模式~~~");
Pizza pizza = null;
if (orderType.equals("chess")){
pizza = new BJChessPizza();
}else if (orderType.equals("pepper")){
pizza = new BJPepperPizza();
}
return pizza;
}
//实现其他产品的方法
public Vegetable createVegetable (String orderType) {
System.out.println("~~~使用的是抽象工厂模式~~~");
Vegetable vegetable = null;
if (orderType.equals("Shengcai")){
Vegetable = new BJShengcaiVegetable ();
}else if (orderType.equals("Youmaicai")){
Vegetable = new BJYoumaicaiVegetable();
}
return Vegetable ;
}
}
抽象工厂模式和工厂方法模式:
工厂方法模式:
一个抽象产品类,可以派生出多个具体产品类。
一个抽象工厂类,可以派生出多个具体工厂类。
每个具体工厂类只能创建一个具体产品类的实例。
抽象模式:
多个抽象产品类,每个抽象产品类可以派生出多个具体产品类。
一个抽象工厂类,可以派生出多个具体工厂类。
每个具体工厂类可以创建多个具体产品类的实例。
-
区别:
-
工厂方法模式只有一个抽象产品类,而抽象工厂模式有多个。
-
工厂方法模式的具体工厂类只能创建一个具体产品类的实例,而抽象工厂模式可以创建多个。