Java设计模式之工厂模式

本文详细介绍了工厂模式、简单工厂模式、工厂方法模式和抽象工厂模式在Java中的应用,探讨了它们的角色、职责、优缺点以及适用场景。重点强调了开闭原则在设计模式选择中的重要性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

目录

一、工厂模式(Factory Pattern)

二、简单工厂模式        

该模式中包含的角色及职责:

优点:

缺点:

适用场景:

三、工厂方法模式

该模式中包含的角色及其职责:

优点:

缺点:

四、抽象工厂模式

该模式中包含的角色及其职责:

优点:


一、工厂模式(Factory Pattern)

工厂模式是Java中最常用的设计模式之一,属于创建型模式。

二、简单工厂模式        

简单工厂模式并不是23种设计模式之一,因为它不符合开闭原则,主要目的是为了引出工厂方法模式,适合产品子类比较少的,操作比较简单的情况。

有一个工厂类,负责生产某一类产品。同一类产品,具备同一个抽象父类(抽象类,接口),将创建对象与使用对象分离(spring框架就是这种设计思想)。简单工厂模式违背了开闭原则,因为添加一个产品,就需要修改工厂代码。

由一个工厂根据传入的参数(一般是字符串参数),动态决定应该创建哪一个产品子类的实例,并以父类形式返回。具体看下面的例子。

该模式中包含的角色及职责:

1.工厂角色:简单工厂模式的核心,它负责实现创建所以实例的内部逻辑。工厂类提供静态方法,可以被外界直接调用,创建所需要的产品对象。

2.抽象产品角色:简单工厂模式所创建的所有对象的父类,描述所有实例共有的接口,可以是抽象类或接口。

3.具体产品角色:是简单工厂模式的创建目标。

优点:

客户端不负责对象的创建,而是由专门的工厂类完成;客户端只负责对象的调用,实现了创建和调用的分离,降低了客户端代码的难度。

缺点:

如果增加和减少产品子类,需要修改简单工厂类,违背了开闭原则。如果产品子类过多,会导致工厂类非常庞大,违反了开闭原则,不利于后期维护。

适用场景:

所有的产品子类都有同一个父类(或接口),属于同一个产品系列产品子类比较少而且创建操作比较简单。

例如:有一个专门生产Car的工厂类,负责生产奥迪汽车和宝马汽车,并且同一类汽车具备同一种功能(接口或抽象父类)。并且将创建对象和使用对象分离。

public class Aodi implements Car{

    @Override
    public void run() {
        System.out.println("奥迪汽车行驶");
    }
}

public class Bmw implements Car{

    @Override
    public void run() {
        System.out.println("宝马汽车行驶");
    }

}
public interface Car {

      void run();

}
public class CarFactory {

     public static Car createCar(String name){
            if(name.equals("aodi")){
                return new Aodi();
            }
            if(name.equals("bmw")){
                return new Bmw();
            }
            return null;
     }
}
public class Test {

    public static void main(String[] args) {

        Car bmw  = CarFactory.createCar("bmw");
        Car aodi  = CarFactory.createCar("aodi");

          bmw.run();
          aodi.run();
    }
}

测试结果:

三、工厂方法模式

在简单模式的基础之上,对工厂进行抽象,一个抽象的产品对应一个抽象的工厂,一个具体的产品对应一个具体的工厂,一个具体的工厂负责生产一个具体的产品。需要扩展新产品时,只需要添加新的具体产品类和新的生产该产品的具体工厂类即可,符合开闭原则。

该模式中包含的角色及其职责:

1.抽象工厂角色:工厂方法模式的核心,与应用程序无关。任何在模式中创建的对象的工厂类必须实现这个接口。

2.具体工厂接口:这是实现抽象工厂接口的具体工厂类,包含与应用程序密切相关的逻辑,并且受到应用程序调用用以创建产品对象。

3.抽象产品角色:工厂方法模式所创建的对象的父类,就是产品对象个共同父类或共同拥有的接口。

4.具体产品角色;这个角色实现了抽象产品角色所定义的接口。某聚体产品有专门的具体工厂窗创建,它们之间往往一一对应。

优点:

客户端不负责对象的创建,而是由专门的工厂类完成;客户端只负责对象的调用,实现了创建和调用的分离,降低了客户端代码的难度;若增加和减少产品子类,不需要修改工厂类,只增加产品子类和工厂子类,符合开闭原则。即使产品子类过多,不会导致工厂类的庞大,利于后期维护。

缺点:

需要编写额外的代码,增加了工作量

例如:

public class Aodi implements Car {

    @Override
    public void run() {
        System.out.println("奥迪汽车行驶");
    }
}

public class Bmw implements Car {

    @Override
    public void run() {
        System.out.println("宝马汽车行驶");
    }

}
public class AodiFactory implements  CarFactory{

    @Override
    public Car createCar() {
        return new Aodi();
    }
    
}

public class BmwFactory implements  CarFactory{

    @Override
    public Car createCar() {
        return new Bmw();
    }
    
}
public interface Car {

      void run();

}
public interface CarFactory {

       Car createCar();
}
public class Test {

    public static void main(String[] args) {

           CarFactory aodicarFactory = new AodiFactory();
           Car aodi =  aodicarFactory.createCar();
           aodi.run();

           CarFactory bmwcarFactory = new BmwFactory();
           Car bmw = bmwcarFactory.createCar();
           bmw.run();

    }
}

四、抽象工厂模式

简单工厂模式中,一个工厂负责同一类所有产品对象的创建,如果产品较多,职责大大增加,增加或减少产品时,需要修改工厂类,违背了开闭原则。

工厂方法模式中,一个具体的工厂类负责创建一个单独的产品,如果产品增加或减少,不需要修改工厂类,符合开闭原则。但是如果这些产品之间是有联系的,也必须有不同的工厂分别创建。

抽象工厂模式:一个具体的工厂负责创建一系列互相关联的产品(华为手机,华为汽车),在抽象的工厂中定义不同的产品,具体的工厂负责一个公司一系列产品。

该模式中包含的角色及其职责:

抽象工厂、具体工厂、抽象产品、具体产品

优点:

获取具体系列产品只需要通过具体系列工厂获取,无须关心创建的细节。

例如:

public class AodiCar implements Car{

    @Override
    public void run() {
        System.out.println("奥迪汽车行驶");
    }

}
public class AodiFactory implements  AbstractFactory{
    @Override
    public Car getCar() {
        return new AodiCar();
    }

    @Override
    public Phone getPhone() {
        return new AodiPhone();
    }
}
public class AodiPhone implements Phone{
    @Override
    public void call() {
        System.out.println("奥迪手机打电话");
    }
}
public class BmwCar implements Car{

    @Override
    public void run() {
        System.out.println("宝马汽车行驶");
    }

}

public class BmwFactory implements AbstractFactory{
    @Override
    public Car getCar() {
        return new BmwCar();
    }

    @Override
    public Phone getPhone() {
        return new BmwPhone();
    }
}

public class BmwPhone implements Phone {

    @Override
    public void call() {
        System.out.println("宝马手机打电话");
    }

}

public interface Car {

        void run();
}
public interface AbstractFactory {

       Car getCar();
       Phone getPhone();

}
public interface Phone {

       void  call();

}
public class Test {

    public static void main(String[] args) {
        AbstractFactory aodiFactory = new AodiFactory();
        Car aodiCar = aodiFactory.getCar();
        Phone aodiphone = aodiFactory.getPhone();
              aodiCar.run();
              aodiphone.call();
        AbstractFactory bmwFactory = new BmwFactory();
        Car bmwCar = bmwFactory.getCar();
        Phone bmwPhone = bmwFactory.getPhone();
              bmwCar.run();
              bmwPhone.call();
    }
}

运行结果:

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值