1、简单工厂
简单工厂就是工厂提供一个统一的产品接口,根据传入的参数,由工厂决定要创建什么类型的产品对象,隐藏创建对象的内部细节。
好处
就是解耦,使得代码不直接依赖于具体的实现类;
缺点
就是违反开闭原则,每新增一个产品类,都需要修改我们的工厂。
抽象产品:
/**
* 抽象产品--水果
*/
public interface Fruit {
//获取产品名称--水果名称
String name();
}
产品的具体实现:
/**
* 产品具体实现---苹果
*/
public class Apple implements Fruit{
@Override
public String name() {
return "苹果";
}
}
/**
* 具体的水果产品-- 香蕉
*/
public class Banana implements Fruit {
@Override
public String name() {
return "香蕉";
}
}
/**
* 具体的水果产品--葡萄
*/
public class Grape implements Fruit{
@Override
public String name() {
return "葡萄";
}
}
生产产品的工厂:
/**
* 生产水果的具体工厂
*/
public class FruitFactory {
/**
* 由工厂获取水果
* @return
*/
public Fruit getFruit(String name){
if(name.equals("苹果")){
return new Apple();
}else if(name.equals("香蕉")){
return new Banana();
} else if(name.equals("葡萄")){ //新增产品类--葡萄,需要修改工厂类的源代码,违反开闭原则
return new Grape();
} else{
return null;
}
}
}
测试:
public class Test {
public static void main(String[] args) {
//1.获取生产水果的工厂对象
FruitFactory fruitFactory = new FruitFactory();
//2.通过工厂生产水果
Fruit apple = fruitFactory.getFruit("苹果");
Fruit banana = fruitFactory.getFruit("香蕉");
Fruit grape = fruitFactory.getFruit("葡萄");
System.out.println("生产了:" + apple.name());
System.out.println("生产了:" + banana.name());
System.out.println("生产了:" + grape.name());
}
}
2、工厂方法
工厂方法在简单工厂的基础上进行进一步抽象,将简单工厂中的具体工厂进行抽象为接口或抽象类,将实际创建工作推迟到子工厂中。
好处
就是满足了开闭原则,用户只需要知道具体的工厂名称就可以得到所需的产品;
缺点
就是每添加一个产品就要新创建一个具体产品类和一个具体的产品工厂,增加了系统复杂度。
抽象产品:
/**
* 抽象产品--水果
*/
public interface Fruit {
//获取产品名称--水果名称
String name();
}
产品具体实现:
/**
* 产品具体实现---苹果
*/
public class Apple implements Fruit{
@Override
public String name() {
return "苹果";
}
}
/**
* 具体的水果产品-- 香蕉
*/
public class Banana implements Fruit {
@Override
public String name() {
return "香蕉";
}
}
/**
* 具体的水果产品--葡萄
*/
public class Grape implements Fruit{
@Override
public String name() {
return "葡萄";
}
}
抽象工厂:
/**
* 将简单工厂的具体工厂进行抽象为接口
*/
public interface FruitFactory {
/**
* 获取水果的抽象方法
* @return
*/
public Fruit getFruit();
}
抽象工厂的具体实现:
/**
* 生产苹果的具体工厂
*/
public class AppleFactory implements FruitFactory{
/**
* 苹果工厂生产苹果产品
* @return
*/
@Override
public Fruit getFruit() {
return new Apple();
}
}
/**
* 生产香蕉的具体共产
*/
public class BananaFactory implements FruitFactory{
/**
* 生产香蕉
* @return
*/
@Override
public Fruit getFruit() {
return new Banana();
}
}
/**
* 葡萄工厂具体实现
*/
public class GrapeFactory implements FruitFactory{
/**
* 生产葡萄产品
* @return
*/
@Override
public Fruit getFruit() {
return new Grape();
}
}
测试:
public class Test {
public static void main(String[] args) {
//1.我想要苹果,那么只需要知道苹果工厂即可
AppleFactory appleFruitFactory = new AppleFactory();
//2.生产苹果
Fruit apple = appleFruitFactory.getFruit();
//3.输出
System.out.println("AppleFactory生产了:" + apple.name());
System.out.println("=================================");
//1.我想要香蕉,那么只需要知道香蕉工厂即可
BananaFactory bananaFactory = new BananaFactory();
//2.生产香蕉
Fruit banana = bananaFactory.getFruit();
//3.输出
System.out.println("BananaFactory生产了:" + banana.name());
System.out.println("=================================");
//新增新的产品,只需新增具体产品的实现(Grape)和生产产品工厂的具体实现(GrapeFactory)即可
//1.我想要葡萄,那么只需要知道葡萄工厂即可
GrapeFactory grapeFactory = new GrapeFactory();
//2.生产葡萄
Fruit grape = grapeFactory.getFruit();
//3.输出
System.out.println("GrapeFactory生产了:" + grape.name());
}
}
3、抽象工厂
工厂方法只能生产同一产品等级的产品,而抽象工厂将考虑多等级的产品生产,即抽象工厂中定义生产多个等级的产品的行为,由具体工厂来生产具体的产品。
好处
是满足开闭原则,新增产品只需新增具体产品实现类和具体工厂实现,无需修改源代码,由具体的工厂来管理我们的产品族,无需引入其他类来管理;
缺点
就是当产品族需要新增一个产品时,需要修改所有的工厂类。
抽象产品–水果:
/**
* 抽象产品--水果
*/
public interface Fruit {
//获取产品名称--水果名称
String name();
}
/**
* 抽象产品--水果汁
*/
public interface FruitJuice {
//获取产品名称--水果汁名称
public String name();
}
/**
* 抽象产品--水果干
*/
public interface FruitDried {
//获取产品名称--水果干名称
public String name();
}
具体产品实现–苹果类:
/**
* 产品具体实现---苹果
*/
public class Apple implements Fruit {
@Override
public String name() {
return "苹果";
}
}
/**
* 具体的产品--苹果汁
*/
public class AppleJuice implements FruitJuice{
/**
* 获得苹果汁的名称
* @return
*/
@Override
public String name() {
return "苹果汁";
}
}
/**
* 具体的产品--苹果干
*/
public class AppleDried implements FruitDried{
/**
* 获取苹果干的名称
* @return
*/
@Override
public String name() {
return "苹果干";
}
}
具体产品实现–香蕉类:
/**
* 具体的水果产品-- 香蕉
*/
public class Banana implements Fruit {
@Override
public String name() {
return "香蕉";
}
}
/**
* 具体的产品--香蕉汁
*/
public class BananaJuice implements FruitJuice{
/**
* 获取香蕉汁的名称
* @return
*/
@Override
public String name() {
return "香蕉汁";
}
}
/**
* 具体的产品--香蕉干
*/
public class BananaDried implements FruitDried{
/**
* 获取具体产品香蕉干的名称
* @return
*/
@Override
public String name() {
return "香蕉干";
}
}
具体产品实现–葡萄类:
/**
* 具体的水果产品--葡萄
*/
public class Grape implements Fruit {
@Override
public String name() {
return "葡萄";
}
}
/**
* 具体的产品--葡萄汁
*/
public class GrapeJuice implements FruitJuice{
/**
* 获取葡萄汁的名称
* @return
*/
@Override
public String name() {
return "葡萄汁";
}
}
/**
* 具体的产品--葡萄干
*/
public class GrapeDried implements FruitDried {
/**
* 获取葡萄干的名称
* @return
*/
@Override
public String name() {
return "葡萄干";
}
}
抽象工厂:
/**
* 将工厂方法生产一个产品,升级为生产一个产品族
*/
public interface FruitFactory {
/**
* 生产水果
* @return
*/
public Fruit getFruit();
/**
* 生产水果汁
* @return
*/
public FruitJuice getFruitJuice();
/**
* 生产水果干
* @return
*/
public FruitDried getFruitDried();
}
具体工厂–苹果工厂:
/**
* 具体工厂--苹果工厂
*/
public class AppleFactory implements FruitFactory {
/**
* 生产具体的产品--苹果
* @return
*/
@Override
public Fruit getFruit() {
return new Apple();
}
/**
* 生产具体的产品--苹果汁
* @return
*/
@Override
public FruitJuice getFruitJuice() {
return new AppleJuice();
}
/**
* 生产具体的产品--苹果干
* @return
*/
@Override
public FruitDried getFruitDried() {
return new AppleDried();
}
}
具体工厂–香蕉工厂:
/**
* 具体的工厂--香蕉工厂
*/
public class BananaFactory implements FruitFactory{
/**
* 生产具体的产品--香蕉
* @return
*/
@Override
public Fruit getFruit() {
return new Banana();
}
/**
* 生产具体的产品--香蕉汁
* @return
*/
@Override
public FruitJuice getFruitJuice() {
return new BananaJuice();
}
/**
* 生产具体的产品--香蕉干
* @return
*/
@Override
public FruitDried getFruitDried() {
return new BananaDried();
}
}
具体工厂–葡萄工厂:
/**
* 具体的工厂--葡萄工厂
*/
public class GrapeFactory implements FruitFactory{
/**
* 生产具体的产品--葡萄
* @return
*/
@Override
public Fruit getFruit() {
return new Grape();
}
/**
* 生产具体的产品--葡萄汁
* @return
*/
@Override
public FruitJuice getFruitJuice() {
return new GrapeJuice();
}
/**
* 生产具体的产品--葡萄干
* @return
*/
@Override
public FruitDried getFruitDried() {
return new GrapeDried();
}
}
测试:
public class Test {
public static void main(String[] args) {
//1.我想获取苹果、苹果汁、苹果干产品,这些产品都有苹果工厂生产和管理
AppleFactory appleFactory = new AppleFactory();
//2.生产苹果、苹果汁、苹果干产品
Fruit apple = appleFactory.getFruit();
FruitJuice appleJuice = appleFactory.getFruitJuice();
FruitDried appleDried = appleFactory.getFruitDried();
//3.输出
System.out.println("AppleFactory生产了:" + apple.name() + "、" + appleJuice.name() + "、" + appleDried.name());
System.out.println("=====================================");
//1.我想获取香蕉、香蕉汁、香蕉干产品,这些产品都有香蕉工厂生产和管理
BananaFactory bananaFactory = new BananaFactory();
//2.生产香蕉、香蕉汁、香蕉干产品
Fruit banana = bananaFactory.getFruit();
FruitJuice bananaJuice = bananaFactory.getFruitJuice();
FruitDried bananaDried = bananaFactory.getFruitDried();
//3.输出
System.out.println("BananaFactory生产了:" + banana.name() + "、" + bananaJuice.name() + "、" + bananaDried.name());
System.out.println("=====================================");
//1.我想获取葡萄、葡萄汁、葡萄干产品,这些产品都有葡萄工厂生产和管理
GrapeFactory grapeFactory = new GrapeFactory();
//2.生产葡萄、葡萄汁、葡萄干产品
Fruit grape = grapeFactory.getFruit();
FruitJuice grapeJuice = grapeFactory.getFruitJuice();
FruitDried GrapeDried = grapeFactory.getFruitDried();
//3.输出
System.out.println("GrapeFactory生产了:" + grape.name() + "、" + grapeJuice.name() + "、" + GrapeDried.name());
}
}
面试–说说你对工厂设计模式的理解?
工厂模式分为三种:简单工厂、工厂方法、抽象工厂。
简单工厂就是工厂提供一个统一的产品接口,根据传入的参数,由工厂决定要创建什么类型的产品对象,隐藏创建对象的内部细节。
好处
就是解耦,使得代码不直接依赖于具体的实现类;
缺点
就是违反开闭原则,每新增一个产品类,都需要修改我们的工厂。
工厂方法在简单工厂的基础上进行进一步抽象,将简单工厂中的具体工厂进行抽象为接口或抽象类,将实际创建工作推迟到子工厂中。
好处
就是满足了开闭原则,用户只需要知道具体的工厂名称就可以得到所需的产品;
缺点
就是每添加一个产品就要新创建一个具体产品类和一个具体的产品工厂,增加了系统复杂度。
工厂方法只能生产同一产品等级的产品,而抽象工厂将考虑多等级的产品生产,即抽象工厂中定义生产多个等级的产品的行为,由具体工厂来生产具体的产品。
好处
是满足开闭原则,新增产品只需新增具体产品实现类和具体工厂实现,无需修改源代码,由具体的工厂来管理我们的产品族,无需引入其他类来管理;
缺点
就是当产品族需要新增一个产品时,需要修改所有的工厂类。