工厂模式
工厂模式用于创建对象,根据不同的情况,创建不同的对象。
前期准备:
/**
* 饮料产品
*/
public interface DrinkProduct {
void showName();
}
public class MilkDrink implements DrinkProduct {
public MilkDrink() {
System.out.println("创建一个牛奶产品");
}
public void showName() {
System.out.println("饮品 : 牛奶");
}
}
public class TeaDrink implements DrinkProduct {
public TeaDrink() {
System.out.println("创建一个绿茶产品");
}
public void showName() {
System.out.println("饮品 : 绿茶");
}
}
1、简单工厂
简单工厂,根据参数创建不同的对象。适用场景:需要创建的产品不多的时候,而且修改不频繁。
public class DrinkFactory {
public static DrinkProduct getInstance(String type) {
if ("milk".equals(type)) {
return new MilkDrink();
} else if ("tea".equals(type)) {
return new TeaDrink();
} else {
return null;
}
}
}
public class Application {
public static void main(String[] args) {
String drinkType = "tea";
DrinkProduct drink = DrinkFactory.getInstance(drinkType);
drink.showName();
}
}
2、工厂方法模式(静态方法)
工厂方法模式跟简单工厂模式的区别在于简单工厂只有一个工厂类,提供了一个工厂方法,由入参决定生产那个产品,而工厂方法模式则定义一个工厂接口,不同的产品工厂实现工厂接口,生产的产品由产品工厂决定。这样减轻某一个工厂生产多种产品的压力。
public interface DrinkFactory {
DrinkProduct getInstance();
}
public class TeaDrinkFactory implements DrinkFactory {
public DrinkProduct getInstance() {
return new TeaDrink();
}
}
public class MilkDrinkFactory implements DrinkFactory {
public DrinkProduct getInstance() {
return new MilkDrink();
}
}
public class Application {
public static void main(String[] args) {
DrinkFactory factory = null;
DrinkProduct product = null;
factory = new MilkDrinkFactory();
product = factory.getInstance();
product.showName();
}
}
使用静态工厂,优点是:减轻压力,同时实现开闭原则。工厂方法可以使用反射替换使用,不用硬编程。
3、抽象工厂
抽象工厂有两个概念:一、产品族:同一工厂生产的一组不同产品结构的一组产品。二、产品等级结构:产品生产产生不同类型。就比如有一个代加工厂,要代加工多家公司的产品,都要生成手机电视,不过代生产多家的,比如小米家的和格力家的。这里产品族指的的是都需要生产的手机电视。产品等级结构指的是代生产小米和格力。抽象工厂创建一族产品的方法,一个方法对应一个产品。
接上前面所说的,以饮料为例,假设饮料分成儿童型和成人型。所以产品族就是儿童型饮料和成人型饮料。
public interface DrinkFactory {
/**
* 生产儿童饮料
* @return
*/
DrinkProduct createChildDrink();
/**
* 生产成人饮料
* @return
*/
DrinkProduct createAdultDrink();
}
上面的getChildDrink和getAdultDrink就是一个产品族。
public class MilkDrinkFactory implements DrinkFactory {
@Override
public DrinkProduct createChildDrink() {
System.out.println("生产一个旺仔牛奶");
return new MilkChildDrink();
}
@Override
public DrinkProduct createAdultDrink() {
System.out.println("生产一瓶养乐多");
return new MilkAdultDrink();
}
}
public class TeaDrinkFactory implements DrinkFactory {
@Override
public DrinkProduct createChildDrink() {
System.out.println("生产一瓶东方树叶");
return new TeaChildDrink();
}
@Override
public DrinkProduct createAdultDrink() {
System.out.println("生产一瓶啤儿茶爽");
return new TeaAdultDrink();
}
}
public class Application {
public static void main(String[] args) {
DrinkFactory factory = null;
DrinkProduct product = null;
factory = new MilkDrinkFactory();
product = factory.createAdultDrink();
product.showName();
}
}
在增加产品等级的时候无需修改抽象,只需要增加实现就可以了,但是如果增加一个产品族产品就需要该原来抽象工厂,这违背了开闭原则。
三、建造者模式
建造者模式也是一个创建型模式,相比于工厂模式,建造者模式更关注于一个复杂对象的创建过程。建造者模式将复杂的对象的创建与表示分离,使得同样的构建过程可以创建不同的表示。
Builder表示对象的各个组成部分构建方式。Director负责制定装配顺序。下面以电脑为例。
生成对象有哪些属性。
/**
* 电脑,拥有哪些属性
*/
public interface IComputer {
/**
* Cpu 型号
*/
void showCPU();
/**
* 内存量
*/
void showMemory();
/**
* 外存储大小
*/
void showStorage();
void setCpu(String cpu);
void setMemory(String memory);
void setStorage(String storage);
}
/**
* 联想电脑
*/
public class LenovoComputer implements IComputer{
private String cpu;
private String memory;
private String storage;
@Override
public void showCPU() {
System.out.println("CPU = " + cpu);
}
@Override
public void showMemory() {
System.out.println("Memory = " + memory);
}
@Override
public void showStorage() {
System.out.println("Storage = " + storage);
}
@Override
public void setCpu(String cpu) {
this.cpu = cpu;
}
@Override
public void setMemory(String memory) {
this.memory = memory;
}
@Override
public void setStorage(String storage) {
this.storage = storage;
}
}
生成属性的构建方式
public interface ComputerBuilder {
void buildCPU();
void buildMemory();
void buildStorage();
/**
* 装配电脑
* @return
*/
IComputer buildComputer();
}
public class LenovoComputerBuilder implements ComputerBuilder {
private LenovoComputer computer;
public LenovoComputerBuilder(){
computer = new LenovoComputer();
}
@Override
public void buildCPU() {
System.out.println("装一个 corei5 CPU");
computer.setCpu("corei5");
}
@Override
public void buildMemory() {
System.out.println("装一个 8G 内存");
computer.setMemory("8G");
}
@Override
public void buildStorage() {
System.out.println("装一个 256G SSD");
computer.setStorage("256G SSD");
}
@Override
public IComputer buildComputer() {
System.out.println("得到一个新电脑");
return computer;
}
}
组装顺序,组装流程控制器:
public interface ComputerDirector {
/**
* 构建一台电脑
* @param cb
* @return
*/
IComputer constructComputer(ComputerBuilder cb);
}
public class LenovoComputerDirector implements ComputerDirector {
@Override
public IComputer constructComputer(ComputerBuilder cb) {
cb.buildMemory();
cb.buildCPU();
//再加装一条内存
cb.buildMemory();
cb.buildStorage();
return cb.buildComputer();
}
}
结果
public class Application {
public static void main(String[] args) {
//获取组装过程
ComputerDirector cd = new LenovoComputerDirector();
//获取组装对象
IComputer computer = cd.constructComputer(new LenovoComputerBuilder());
computer.showCPU();
computer.showMemory();
computer.showStorage();
}
}
建造者模式将创建过程和对象属性的表示分离开了,这样方便对不同过程产生不同对象。