一、工厂模式的分类
- 简单工厂模式
- 工厂方法模式
- 抽象工厂模式
二、具体模式的应用场景及说明
2.1 简单工厂模式
简单工厂模式定义一个生产对象的工厂类,使用者可以根据不同参数返回不同的子类,这些子类公用一个接口。
2.1.1简单工厂模式的组成
角色 | 关系 | 作用 |
---|---|---|
抽象产品 | 具体产品的父类 | 描述产品的公共接口 |
具体产品 | 抽象产品的子类 | 描述产品的具体实现 |
工厂类 | 外界调用 | 根据传入的参数不同返货不同的子类 |
2.1.2 简单工厂模式的具体应用
以星巴克咖啡为类,经典咖啡中有摩卡、美式咖啡。我们可以建一个经典咖啡的工厂类用来返回不同类型的咖啡。下面是具体的代码实现。
// 简单工厂类 根据传入的不同参数返回对应的子类
public class ClassicFactory {
public static Caffee createCaffee(String type) {
if ("Mocha".equals(type)) {
return new Mocha();
} else if ("Americano".equals(type)) {
return new Americano();
} else {
throw new IllegalArgumentException("Unknown type of coffee: " + type);
}
}
}
// 抽象产品caffee类
public abstract class Caffee {
public abstract String getName(); // 获取咖啡的名称
public abstract int cost(); // 获取咖啡的价格
public void printCost(){
// 打印咖啡的名称和价格
System.out.println(getName() + " ¥" + cost());
}
}
// 具体产品实现类1
public class Americano extends Caffee{
@Override
public String getName() {
return "美式咖啡";
}
@Override
public int cost() {
return 27;
}
}
// 具体产品实现类2
public class Mocha extends Caffee{
@Override
public String getName() {
return "摩卡咖啡";
}
@Override
public int cost() {
return 33;
}
}
// 测试类
public class CaffeTest {
public static void main(String args[]){
Caffee mocha = ClassicFactory.createCaffee("Mocha");
mocha.printCost();
Caffee americano = ClassicFactory.createCaffee("Americano");
americano.printCost();
}
}
结果输出
摩卡咖啡 ¥33
美式咖啡 ¥27
2.2 工厂方法模式
工厂方法模式包含四种类,分别是抽象产品类、具体产品类、抽象工厂类、具体工厂类。
2.2.1 工厂方法模式的组成
角色 | 关系 | 作用 |
---|---|---|
抽象产品 | 具体产品的父类 | 描述产品的公共接口 |
具体产品 | 抽象产品的子类 | 描述产品的具体实现 |
抽象工厂 | 具体工厂的父类 | 具体工厂的公共接口 |
具体工厂 | 抽象工厂的子类 | 描述具体工厂 ,创建具体产品实例 |
2.2.2 工厂方法模式的具体应用
如果现在新增了一个拿铁咖啡,就要在简单的工厂类新加一个逻辑即可,但是这样违背了开闭原则。所以工厂方法模式就应运而生。以下是具体的代码实现。
// 抽象工厂
public abstract class abFactory {
public abstract Caffee createClassicCaffee();
}
// 具体工厂1
public class AmericanoFactory extends abFactory {
@Override
public Caffee createClassicCaffee() {
return new Americano();
}
}
// 具体工厂2
public class MochaFactory extends abFactory{
@Override
public Caffee createClassicCaffee() {
return new Mocha();
}
}
// 具体工厂3
public class LatteFactory extends abFactory{
@Override
public Caffee createClassicCaffee() {
return new Latte();
}
}
// 抽象产品类
public abstract class Caffee {
public abstract String getName(); // 获取咖啡的名称
public abstract int cost(); // 获取咖啡的价格
public void printCost(){
// 打印咖啡的名称和价格
System.out.println(getName() + " ¥" + cost());
}
}
// 具体产品类1
public class Latte extends Caffee{
@Override
public String getName() {
return "拿铁";
}
@Override
public int cost() {
return 30;
}
}
// 具体产品类2
public class Mocha extends Caffee {
@Override
public String getName() {
return "摩卡咖啡";
}
@Override
public int cost() {
return 33;
}
}
// 具体产品类3
public class Americano extends Caffee {
@Override
public String getName() {
return "美式咖啡";
}
@Override
public int cost() {
return 27;
}
}
// 测试类
public class CaffeTest {
public static void main(String args[]){
Caffee mocha = new MochaFactory().createClassicCaffee();
mocha.printCost();
Caffee americano =new AmericanoFactory().createClassicCaffee();
americano.printCost();
Caffee latte = new LatteFactory().createClassicCaffee();
latte.printCost();
}
}
输出结果
摩卡咖啡 ¥33
美式咖啡 ¥27
拿铁 ¥30
2.3 抽象工厂模式
抽象工厂模式是基于工厂方法模式的基础上进行的。在这种模式中,每一个工厂不再只负责一个产品的创建,而是负责一组产品的创建。抽象工厂模式将每个产品组都提取为一个接口,每个工厂都负责一个产品组。
2.3.1 抽象工厂模式的组成
角色 | 关系 | 作用 |
---|---|---|
抽象产品 | 具体产品的父类 | 描述产品的公共接口 |
具体产品 | 抽象产品的子类 | 描述产品的具体实现 |
抽象工厂 | 具体工厂的父类 | 具体工厂的公共接口 |
具体工厂 | 抽象工厂的子类 | 描述具体工厂 ,创建具体产品实例 |
2.3.2 抽象工厂模式的具体应用
抽象工厂的组成和方法工厂的组成是一样的只不过抽象工厂不再只负责一个产品的创建,而是负责一组产品的创建,很简单,星巴克不仅仅卖咖啡还卖蛋糕只需要在抽象工厂类中新增创建蛋糕的抽象方法就行。代码如下
public abstract class AbFactory {
public abstract Caffee createClassicCaffee();
public abstract Cake createCake();
}
public class LatteCakeFactory extends AbFactory {
@Override
public Caffee createClassicCaffee() {
return new Latte();
}
@Override
public Cake createCake() {
return new StrawberryCake();
}
}
public class MochaCakeFactory extends AbFactory {
@Override
public Caffee createClassicCaffee() {
return new Mocha();
}
@Override
public Cake createCake() {
return new StrawberryCake();
}
}
public abstract class goods {
public abstract String getName(); // 获取商品的名称
public abstract int cost(); // 获取商品的价格
public abstract void descirption(); //对商品的描述
public void printCost(){
// 打印商品的名称和价格
System.out.println(getName() + " ¥" + cost());
}
}
public abstract class Caffee extends goods {
@Override
public void descirption() {
System.out.println("这是咖啡");
}
}
public abstract class Cake extends goods {
@Override
public void descirption() {
System.out.println("这是蛋糕");
}
}
public class Latte extends Caffee {
@Override
public String getName() {
return "拿铁";
}
@Override
public int cost() {
return 30;
}
}
public class Mocha extends Caffee {
@Override
public String getName() {
return "摩卡咖啡";
}
@Override
public int cost() {
return 33;
}
}
public class StrawberryCake extends Cake{
@Override
public String getName() {
return "草莓蛋糕";
}
@Override
public int cost() {
return 27;
}
}
public class CaffeTest {
public static void main(String args[]){
AbFactory factory= new LatteCakeFactory();
Caffee latte = factory.createClassicCaffee();
Cake cake = factory.createCake();
latte.printCost();
cake.printCost();
AbFactory mochaCakeFactory= new MochaCakeFactory();
Caffee mocha = mochaCakeFactory.createClassicCaffee();
Cake cake1 = mochaCakeFactory.createCake();
mocha.printCost();
cake1.printCost();
}
}
输出结果
拿铁 ¥30
草莓蛋糕 ¥27
摩卡咖啡 ¥33
草莓蛋糕 ¥27
##总结
如果是单一产品的话使用简单工厂模式或者工厂方法模式,如果是多个产品的话使用抽象工厂模式。tips:上面的抽象工厂模式有点强行带入了(自己改了之后感觉有点不合时宜后续再看看)