简单工厂
简单工厂模式又 叫静态工厂方法模式(Static FactoryMethod Pattern),是通过专门定义一个类来负责创建其他类的实例,被创建的实例通常都具有共同的父类。
简单工厂定义一个Factory类,可以根据参数的不同返回不同类的实例,被创建的实例通常有共同的父类。实质是由一个工厂类根据传入的参数,动态决定应该创建哪一个产品类实例。
在实际使用过程中,违背了 开放-关闭原则,因此并不属于23中设计模式之一。
结构图:
- Product:抽象产品类,将具体产品类公共的代码进行抽象和提取后封装在一个抽象产品类中。
- ConcreteProduct:具体产品类,将需要创建的各种不同产品对象的相关代码封装到具体产品类中。
- Factory:工厂类,提供一个工厂类用于创建各种产品,在工厂类中提供一个创建产品的工厂方法,该方法可以根据所传入参数的不同创建不同的具体产品对象。
- Client:客户端类,只需调用工厂类的工厂方法并传入相应的参数即可得到一个产品对象。
代码实现:
abstract class Car {
public abstract void run();
}
//实现接口
class Audi extends Car {
@Override
public void run() {
System.out.println("奥迪跑的快");
}
}
class Byd extends Car {
@Override
public void run() {
System.out.println("比亚迪跑的慢");
}
}
//接下来需要解决的就是对象的创建问既如何根据不同的情况创建不同的对象:我们正好可以通过简单工厂模式实现
class CarFactory {
public static Car createCar(String type){
switch (type){
case "audi" : return new Audi();
case "byd" : return new Byd();
default:break;
}
return null;
}
}
//调用:
public class SimpleFactory {
public static void main(String[] args) {
Car c1 =CarFactory.createCar("audi");
Car c2 = CarFactory.createCar("byd");
c1.run();
c2.run();
}
}
工厂方法
工厂方法模式,又称工厂模式,通过定义工厂父类负责定义创建对象的公共接口,而子类则负责生成具体的对象。将类的实例化(具体产品的创建)延迟到工厂类的子类(具体工厂)中完成,即由子类来决定应该实例化(创建)哪一个类。主要解决了简单工厂模式的缺点(工厂一旦需要生产新产品就需要修改工厂类的方法逻辑,违背了“开放 - 关闭原则)
结构图
- product:抽象产品,具体产品的父类,描述具体产品的公共接口
- concrete product:具体产品,抽象产品的子类,工厂类创建的目标类,描述生产的具体产品
- creator:抽象工厂,具体工厂的父类,描述具体工厂的公共接口
- concrete creator:具体工厂,抽象工厂的子类,被外界调用,描述具体工厂,创建产品的实例
代码
interface CarFactory{
Car createCar();
}
interface Car{
void run();
}
//实现工厂类
class AudiFactory implements CarFactory {
@Override
public Car createCar() {
return new Audi();
}
}
class BydFactory implements CarFactory {
@Override
public Car createCar() {
return new Byd();
}
}
//实现产品类
class Audi implements Car {
@Override
public void run() {
System.out.println("奥迪再跑!");
}
}
class Byd implements Car {
@Override
public void run() {
System.out.println("比亚迪再跑!");
}
}
public class FactoryMethod {
public static void main(String[] args) {
Car c1 = new AudiFactory().createCar();
Car c2 = new BydFactory().createCar();
c1.run();
c2.run();
}
}
工厂模式在保留了简单工厂的封装优点的同时,让扩展变得简单,让继承变得可行,增加了多态性的体现。但是,在添加新产品时,除了要添加新产品类以外,还要提供一直对应的具体工厂类,另外,虽然保证了工厂方法内对修改关闭,但是如果更换另一种产品,仍然需要修改实例化的具体工厂类,一种具体工厂只能创建一种具体产品。
抽象工厂
抽象工厂模式的适用范围比工厂模式更加广泛,它与工厂模式最大的区别在于:
工厂模式中一个工厂只能生产一种产品,而抽象工厂可以生产多个。
结构图:
代码:
interface CarFactory {
Engine createEngine();
Seat createSeat();
}
interface Engine {
void run();
void start();
}
interface Seat {
void massage();
}
//低配车
class LowCarFactory implements CarFactory {
@Override
public Engine createEngine() {
return new LowEngine();
}
@Override
public Seat createSeat() {
return new LowSeat();
}
}
//高配车
class LuxuryCarFactory implements CarFactory {
@Override
public Engine createEngine() {
return new LuxuryEngine();
}
@Override
public Seat createSeat() {
return new LuxurySeat();
}
}
//配件
class LuxuryEngine implements Engine{
@Override
public void run() {
System.out.println("转的快!");
}
@Override
public void start() {
System.out.println("启动快!可以自动启停!");
}
}
class LowEngine implements Engine{
@Override
public void run() {
System.out.println("转的慢!");
}
@Override
public void start() {
System.out.println("启动慢!");
}
}
class LuxurySeat implements Seat {
@Override
public void massage() {
System.out.println("可以自动按摩!");
}
}
class LowSeat implements Seat {
@Override
public void massage() {
System.out.println("不能按摩!");
}
}
public class AbstractFactory {
public static void main(String[] args) {
CarFactory factory = new LuxuryCarFactory();
Engine e = factory.createEngine();
e.run();
e.start();
}
}
在工厂模式中弥补了简单工厂模式的缺陷(不符合开闭原则),而在抽象工厂模式中弥补了工厂模式的不足(一个工厂只能生产一种产品)。
优点:
- 1、抽象工厂模式隔离了具体类的生产,使得客户并不需要知道什么被创建。
- 2、当一个产品族中的多个对象被设计成一起工作时,它能保证客户端始终只使用同一个产品族中的对象。
- 3、增加新的具体工厂和产品族很方便,无须修改已有系统,符合“开闭原则”。
缺点:
- 增加新的产品等级结构很复杂,需要修改抽象工厂和所有的具体工厂类,对“开闭原则”的支持呈现倾斜性。