天天看点

设计模式中的创建类模式设计模式中的创建类模式工厂方法模式 VS 建造者模式抽象工厂模式 VS 建造者模式

设计模式中的创建类模式

创建类模式包括工厂方法模式、建造者模式、抽象工厂模式、单例模式和原型模式。

  • 单例模式:要保持在内存中只有一个对象。
  • 原型模式:要求通过复制的方式产生一个新的对象。实现Cloneable接口,并覆盖和重写clone()方法。克隆。
  • 工厂方法模式:注重的是整体对象的创建方法,用一个类封装特定产品的实例化,即把new进行封装。
  • 建造者模式:注重的是部件构建的过程。先使用一个类对产品进行组装,然后再使用导演类对其封装。
  • 抽象工厂模式:不需要关心构建过程,只关心什么产品由什么工厂生产。

工厂方法模式 VS 建造者模式

区别

(1)意图不同:

  • 工厂方法模式,关注的是一个产品整体;
  • 建造者模式,关注的是产品各个部件的产生以及装配顺序。

(2)产品的复杂度不同:

  • 工厂方法模式创建的产品一般都是单一性质产品,都是一个模样;
  • 建造者模式创建的是一个复合产品,它由各个部件复合而成,部件不同产品对象不同。

工厂方法模式的对象粒度比较粗,建造者模式的产品对象粒度比较细。

例如

如要制造一个超人,如果使用工厂方法模式,直接产生出来的就是一个力大无穷、能够飞翔、内裤外穿的超人;而如果使用建造者模式,则需要组装手、头、脚、躯干等部分,然后再把内裤外穿,才会产生一个超人。

(1)工厂方法模式建造超人

设计模式中的创建类模式设计模式中的创建类模式工厂方法模式 VS 建造者模式抽象工厂模式 VS 建造者模式
public interface ISuperMan { 
    //每个超人都有特殊技能 
    public void specialTalent(); 
}
           
public class AdultSuperMan implements ISuperMan { //成年超人
    public void specialTalent() { 
        System.out.println("超人力大无穷"); 
    }
}
           
public class ChildSuperMan implements ISuperMan { //未成年超人 
    public void specialTalent() { 
        System.out.println("小超人的能力是刀枪不入、快速运动"); 
    }
}
           
public class SuperManFactory { 
    //定义一个生产超人的工厂 
    public static ISuperMan createSuperMan(String type){ 
        //根据输入参数产生不同的超人 
        if(type.equalsIgnoreCase("adult")){ 
            return new AdultSuperMan(); 
        }else if(type.equalsIgnoreCase("child")){ 
            return new ChildSuperMan(); 
        }else{ 
            return null; 
        } 
    } 
} 
           
public class Client { 
    public static void main(String[] args) { 
        //生产一个成年超人 
        ISuperMan adultSuperMan = SuperManFactory.createSuperMan("adult"); 
        //展示一下超人的技能 
        adultSuperMan.specialTalent(); 
    } 
} 
           

注意:通过工厂方法模式生产出对象,然后由客户端进行对象的其他操作,但是并不代表所有生产出的对象都必须具有相同的状态和行为,它是由产品所决定。

(2)建造者模式建造超人

设计模式中的创建类模式设计模式中的创建类模式工厂方法模式 VS 建造者模式抽象工厂模式 VS 建造者模式
public class SuperMan { 
    //超人的躯体 
    private String body; 
    //超人的特殊技能 
    private String specialTalent; 
    //超人的标志 
    private String specialSymbol; 
    public String getBody() { 
        return body; 
    }
    public void setBody(String body) { 
        this.body = body; 
    }
    public String getSpecialTalent() { 
        return specialTalent; 
    }
    public void setSpecialTalent(String specialTalent) { 
        this.specialTalent = specialTalent; 
    }
    public String getSpecialSymbol() { 
        return specialSymbol; 
    }
    public void setSpecialSymbol(String specialSymbol) { 
        this.specialSymbol = specialSymbol; 
    }
} 
           
public abstract class Builder { 
    //定义一个超人的应用 
    protected final SuperMan superMan = new SuperMan(); 
    //构建出超人的躯体 
    public void setBody(String body){ 
        this.superMan.setBody(body); 
    }
    //构建出超人的特殊技能 
    public void setSpecialTalent(String st){ 
        this.superMan.setSpecialTalent(st); 
    }
    //构建出超人的特殊标记 
    public void setSpecialSymbol(String ss){ 
        this.superMan.setSpecialSymbol(ss); 
    }
    //构建出一个完整的超人 
    public abstract SuperMan getSuperMan(); 
} 
           
public class AdultSuperManBuilder extends Builder { 
    @Override 
    public SuperMan getSuperMan() { 
        super.setBody("强壮的躯体"); 
        super.setSpecialTalent("会飞行"); 
        super.setSpecialSymbol("胸前带S标记"); 
        return super.superMan; 
    } 
}
           
public class ChildSuperManBuilder extends Builder { 
    @Override 
    public SuperMan getSuperMan() { 
        super.setBody("强壮的躯体"); 
        super.setSpecialTalent("刀枪不入"); 
        super.setSpecialSymbol("胸前带小S标记"); 
        return super.superMan; 
    } 
} 
           
public class Director { 
    //两个建造者的应用 
    private static Builder adultBuilder = new AdultSuperManBuilder(); 
    //未成年超人的建造者 
    private static Builder childBuilder = new ChildSuperManBuilder(); 
    //建造一个成年、会飞行的超人 
    public static SuperMan getAdultSuperMan(){ 
        return adultBuilder.getSuperMan(); 
    }
    //建造一个未成年、刀枪不入的超人 
    public static SuperMan getChildSuperMan(){ 
        return childBuilder.getSuperMan(); 
    } 
} 
           
public class Client { 
    public static void main(String[] args) { 
        //建造一个成年超人 
        SuperMan adultSuperMan = Director.getAdultSuperMan(); 
        //展示一下超人的信息 
        adultSuperMan.getSpecialTalent(); 
    } 
} 
           

建造者必须关注超人的各个部件,而工厂方法模式则只关注超人的整体,这就是两者的区别。

抽象工厂模式 VS 建造者模式

区别

  • 如果希望屏蔽对象的创建过程,只提供一个封装良好的对象,则可以选择抽象工厂方法模式。
  • 而建造者模式可以用在构件的装配方面,如通过装配不同的组件或者相同组件的不同顺序,可以产生出一个新的对象,它可以产生一个非常灵活的架构,方便地扩展和维护系统。

例如

现代化的汽车工厂能够批量生产汽车。不同的工厂生产不同的汽车,宝马工厂生产宝马牌子的车,奔驰工厂生产奔驰牌子的车。车不仅具有不同品牌,还有不同的用途分类,如商务车Van,运动型车SUV等,我们按照两种设计模式分别实现车辆的生产过程。

(1)抽象工厂模式生产车辆

设计模式中的创建类模式设计模式中的创建类模式工厂方法模式 VS 建造者模式抽象工厂模式 VS 建造者模式
public interface ICar { 
    //汽车的生产商,也就是牌子 
    public String getBand(); 
    //汽车的型号 
    public String getModel(); 
}
           
public abstract class AbsBMW implements ICar { 
    private final static String BMW_BAND = "宝马汽车"; 
    //宝马车 
    public String getBand() { 
        return BMW_BAND; 
    }
    //型号由具体的实现类实现 
    public abstract String getModel(); 
} 
           
public class BMWVan extends AbsBMW { 
    private final static String SEVENT_SEARIES = "7系列车型商务车"; 
    public String getModel() { 
        return SEVENT_SEARIES; 
    } 
} 


public class BMWSuv extends AbsBMW { 
    private final static String X_SEARIES = "X系列车型SUV"; 
    public String getModel() { 
        return X_SEARIES; 
    } 
} 
           
public abstract class AbsBenz implements ICar { 
    private final static String BENZ_BAND = "奔驰汽车"; 
    public String getBand() { 
        return BENZ_BAND; 
    }
    //具体型号由实现类完成
    public abstract String getModel(); 
}
           
public class BenzVan extends AbsBenz { 
    private final static String R_SERIES = "R系列商务车"; 
    public String getModel() { 
        return R_SERIES; 
    } 
}

public class BenzSuv extends AbsBenz { 
    private final static String G_SERIES = "G系列SUV"; 
    public String getModel() { 
        return G_SERIES; 
    } 
} 
           
public interface CarFactory { 
    //生产SUV 
    public ICar createSuv(); 
    //生产商务车 
    public ICar createVan(); 
}
           
public class BMWFactory implements CarFactory { 
    //生产SUV 
    public ICar createSuv() { 
        return new BMWSuv();
    }
    //生产商务车 
    public ICar createVan(){ 
        return new BMWVan(); 
    } 
} 

public class BenzFactory implements CarFactory { 
    //生产SUV 
    public ICar createSuv() { 
        return new BenzSuv(); 
    }
    //生产商务车 
    public ICar createVan(){ 
        return new BenzVan(); 
    } 
} 
           
public class Client { 
    public static void main(String[] args) { 
        //要求生产一辆奔驰SUV 
        System.out.println("===要求生产一辆奔驰SUV==="); 
        //首先找到生产奔驰车的工厂 
        System.out.println("A、找到奔驰车工厂"); 
        CarFactory carFactory= new BenzFactory(); 
        //开始生产奔驰SUV 
        System.out.println("B、开始生产奔驰SUV"); 
        ICar benzSuv = carFactory.createSuv(); 
        //生产完毕,展示一下车辆信息 
        System.out.println("C、生产出的汽车如下:"); 
        System.out.println("汽车品牌:"+benzSuv.getBand()); 
        System.out.println("汽车型号:" + benzSuv.getModel()); 
    } 
} 
           

(2)建造者模式生产车辆

建造者模式需要把车辆进行拆分,拆分成引擎和车轮两部分,然后由建造者根据设计图纸制造车。它注重的是对零件的装配、组合、封装,从一个细微构件装配角度看待一个对象。

设计模式中的创建类模式设计模式中的创建类模式工厂方法模式 VS 建造者模式抽象工厂模式 VS 建造者模式
public interface ICar { 
    //汽车车轮 
    public String getWheel(); 
    //汽车引擎 
    public String getEngine(); 
}
           
public class Car implements ICar { 
    //汽车引擎 
    private String engine; 
    //汽车车轮 
    private String wheel; 
    //一次性传递汽车需要的信息 
    public Car(String _engine,String _wheel){ 
        this.engine = _engine; 
        this.wheel = _wheel; 
    }
    public String getEngine() { 
        return engine;
    }
    public String getWheel() { 
        return wheel; 
    }
    public String toString(){ 
        return "车的轮子是:" + wheel + "\n车的引擎是:" + engine; 
    } 
} 
           
public abstract class CarBuilder { 
    //待建造的汽车 
    private ICar car; 
    //设计蓝图 
    private Blueprint bp; 
    public Car buildCar(){ 
        //按照顺序生产一辆车 
        return new Car(buildEngine(),buildWheel()); 
    }
    //接收一份设计蓝图 
    public void receiveBlueprint(Blueprint _bp){ 
        this.bp = _bp; 
    }
    //查看蓝图,只有真正的建造者才可以查看蓝图 
    protected Blueprint getBlueprint(){ 
        return bp; 
    }
    //建造车轮 
    protected abstract String buildWheel(); 
    //建造引擎 
    protected abstract String buildEngine(); 
} 
           
public class Blueprint { 
    //车轮的要求 
    private String wheel; 
    //引擎的要求 
    private String engine; 
    public String getWheel() { 
        return wheel; 
    }
    public void setWheel(String wheel) { 
        this.wheel = wheel; 
    }
    public String getEngine() { 
        return engine; 
    }
    public void setEngine(String engine) { 
        this.engine = engine; 
    } 
} 
           

这和一个具体的产品Car类是不一样的,它是一个蓝图,有一个蓝图可以设计出非常多的产品,如有一个R系统的奔驰商务车设计蓝图,我们就可以生产出一系列的奔驰车。它指导我们的产品生产,而不是一个具体的产品。

public class BMWBuilder extends CarBuilder { 
    public String buildEngine() { 
        return super.getBlueprint().getEngine(); 
    }
    public String buildWheel() { 
        return super.getBlueprint().getWheel(); 
    } 
} 

public class BenzBuilder extends CarBuilder { 
    public String buildEngine() { 
        return super.getBlueprint().getEngine(); 
    }
    public String buildWheel() { 
        return super.getBlueprint().getWheel(); 
    }
}
           
public class Director { 
    //声明对建造者的引用 
    private CarBuilder benzBuilder = new BenzBuilder(); 
    private CarBuilder bmwBuilder = new BMWBuilder(); 
    //生产奔驰SUV 
    public ICar createBenzSuv(){ 
        //制造出汽车 
        return createCar(benzBuilder, "benz的引擎", "benz的轮胎"); 
    }
    //生产出一辆宝马商务车 
    public ICar createBMWVan(){ 
        return createCar(benzBuilder, "BMW的引擎", "BMW的轮胎"); 
    }
    //生产出一个混合车型 
    public ICar createComplexCar(){ 
        return createCar(bmwBuilder, "BMW的引擎", "benz的轮胎"); 
    }
    //生产车辆 
    private ICar createCar(CarBuilder _carBuilder,String engine,String wheel){ 
        //导演怀揣蓝图 
        Blueprint bp = new Blueprint(); 
        bp.setEngine(engine); 
        bp.setWheel(wheel); 
        System.out.println("获得生产蓝图"); 
        _carBuilder.receiveBlueprint(bp); 
        return _carBuilder.buildCar(); 
    } 
} 
           
public class Client { 
    public static void main(String[] args) { 
        //定义出导演类 
        Director director =new Director(); 
        //给我一辆奔驰车SUV 
        System.out.println("===制造一辆奔驰SUV===");
        ICar benzSuv = director.createBenzSuv(); 
        System.out.println(benzSuv); 
        //给我一辆宝马商务车 
        System.out.println("\n===制造一辆宝马商务车==="); 
        ICar bmwVan = director.createBMWVan(); 
        System.out.println(bmwVan); 
        //给我一辆混合车型 
        System.out.println("\n===制造一辆混合车==="); 
        ICar complexCar = director.createComplexCar(); 
        System.out.println(complexCar); 
    } 
} 
           

继续阅读