- 优点是比较好理解,简单易操作。
- 缺点是违反了设计模式的 ocp 原则,即对扩展开放,对修改关闭。即当我们给类增加新功能的时候,尽量不修改代码,或者尽可能少修改代码
- 比如我们这时要新增加一个新的实现类,需要修改源代码
现有3个类,分别是Coffee、AmericanCoffee、LatteCoffee
public class Coffee {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public void addSugar(){
System.out.println("Coffee加糖");
}
public void addMilk(){
System.out.println("Coffee加奶");
}
}
public class AmericanCoffee extends Coffee {
@Override
public void addSugar(){
System.out.println("AmericanCoffee加糖");
}
@Override
public void addMilk(){
System.out.println("AmericanCoffee加奶");
}
}
public class LatteCoffee extends Coffee {
@Override
public void addSugar(){
System.out.println("LatteCoffee加糖");
}
@Override
public void addMilk(){
System.out.println("LatteCoffee加奶");
}
}
简单工厂模式不是一个正式的设计模式,但它是工厂模式的基础。
它使用一个单独的工厂类来创建不同的对象,根据参数类型决定创建哪种类型的对象。
- 简单工厂模式是属于创建型模式,是工厂模式的一种。简单工厂模式是由一个工厂对象决定创建出哪一种产品类的实例。简单工厂模式是工厂模式家族中最简单实用的模式
- 简单工厂模式:定义了一个创建对象的类,由这个类来封装实例化对象的行为(代码)
- 在软件开发中,当我们会用到大量的创建某种、某类或者某批对象时,就会使用到工厂模式
public class SimpleCoffeeFactory {
public Coffee createCoffee(String type){
Coffee coffee = null;
if ("american".equals(type)) {
return new AmericanCoffee();
} else if ("latte".equals(type)) {
return new LatteCoffee();
}
return coffee;
}
}
这样每次创建只需要根据type来判断就行了,而且如果你新增了一个子类(浓缩咖啡)也不用去修改父类的代码,只需要修改工厂的代码即可
public class SimpleCoffeeFactory {
public Coffee createCoffee(String type){
Coffee coffee = null;
if ("american".equals(type)) {
return new AmericanCoffee();
} else if ("latte".equals(type)) {
return new LatteCoffee();
} else if ("nongsuo".equals(type)){
return NongSuoCoffee();
}
return coffee;
}
}
- 封装了创建对象的过程,可以通过参数直接获取对象。把对象的创建和业务逻辑层分开,这样以后就避免了修改客户代码,如果要实现新产品直接修改工厂类,而不需要在原代码中修改,这样就降低了客户代码修改的可能性,更加容易扩展。
- 增加新产品时还是需要修改工厂类的代码,违背了“开闭原则"
- 工厂方法模式设计方案:将实例化功能抽象成抽象方法,根据不同的类型实例化子类。
- 工厂方法模式:定义了一个创建对象的抽象方法,由子类决定要实例化的类。工厂方法模式将对象的实例
public interface CoffeeFactory {
Coffee createCoffee();
}
public class AmericanCoffeeFactory implements CoffeeFactory {
public Coffee createCoffee() {
return new AmericanCoffee();
}
}
public class LatteCoffeeFactory implements CoffeeFactory {
public Coffee createCoffee() {
return new LatteCoffee();
}
}
同样,如果你需要添加一个浓缩咖啡,只需要创建一个浓缩咖啡工厂的实现类,来实现咖啡工厂,通过Java的多态来创建想要的咖啡对象
- 用户只需要知道具体工厂的名称就可得到所要的产品,无须知道产品的具体创建过程;在系统增加新的产品时只需要添加具体产品类和对应的具体工厂类,无须对原工厂进行任何修改满足开闭原则;
- 每增加一个产品就要增加一个具体产品类和一个对应的具体工厂类,这增加了系统的复杂度。
- 抽象工厂模式:定义了一个interface 用于创建相关或有依赖关系的对象簇,而无需指明具体的类
- 抽象工厂模式可以将简单工厂模式和工厂方法模式进行整合。
- 从设计层面看,抽象工厂模式就是对简单工厂模式的改进(或者称为进一步的抽象)。
- 将工厂抽象成两层,AbsFactory(抽象工厂)和 具体实现的工厂子类。程序员可以根据创建对象类型使用对应的工厂子类。这样将单个的简单工厂类变成了工厂簇,更利于代码的维护和扩展。
现有需求添加甜品,那么咖啡工厂就不够用了,所以这个时候我们往上套一个工厂,既可以创建咖啡,又可以创建甜品
public interface DessertFactory {
Coffee createCoffee();
Dessert createDessert();
}
public class ItalyDessertFactory implements DessertFactory {
public Coffee createCoffee() {
return new LatteCoffee();
}
public Dessert createDessert() {
return new Tiramisu();
}
}
public class AmericanDessertFactory implements DessertFactory {
public Coffee createCoffee() {
return new AmericanCoffee();
}
public Dessert createDessert(){
return new MatchaMousse();
}
}
- 当一个产品族中的多个对象被设计成一起工作时,它能保证客户端始终只使用同一个产品族中的对象.
- 当产品族中需要增加一个新的产品时,所有的工厂类都需要进行修改。
工厂模式的意义
将实例化对象的代码提取出来,放到一个类中统一管理和维护,达到和主项目的依赖关系的解耦。从而提高项目的扩展和维护性。
- 三种工厂模式(简单工厂模式、工厂方法模式、抽象工厂模式)
- 设计模式的依赖抽象原则
- 创建对象实例时,不要直接 new 类,而是把这个new 类的动作放在一个工厂的方法中,并返回。有的书上说变量不要直接持有具体类的引用。
- 不要让类继承具体类,而是继承抽象类或者是实现interface(接口)
- 不要覆盖基类中已经实现的方法。