工厂模式:简单工厂、工厂方法以及抽象工厂
文章目录
- 前言
- 简单工厂模式
- 优缺点
- 工厂方法模式
- 优缺点
- 抽象工厂
- 优缺点
前言
工厂模式是一种创建型设计模式,其作用是将对象的创建和使用进行解耦,用于提高代码的可维护性和可扩展性。通过提供给外部负责创建对象的工厂类,外部类通过工厂来创建对象。工厂模式包括简单工厂、工厂方法以及抽象工厂三种模式。
简单工厂模式
简单工厂模式如其名,非常简单,定义一个工厂类,提供给外部创建对象的方法,会根据传入的参数创建不同的对象。
代码实现:
/*水果接口*/
public interface Fruit {
}
/* 水果接口的两个具体的实现类 */
public class Apple implements Fruit{
}
public class Pear implements Fruit{
}
/* 创建对象的工厂*/
public class FruitFactory {
public Fruit creat(String fruit){
if (fruit.equals("apple")){
return new Apple();
}else if (fruit.equals("pear")){
return new Pear();
}
throw new IllegalArgumentException("参数值输入不正确");
}
}
优缺点
优点:代码实现简单,如果需要扩展对象的创建不需要额外创建类
缺点:不符合开闭原则,若要扩展对象的创建会修改工厂类的代码
开闭原则:对扩展是开放的,对修改是关闭的。在不修改原代码的前提下进行行为的扩展。
工厂方法模式
工厂方法模式,其实现需要定义一个接口/抽象类以及创建对象的抽象方法,并且定义多个具体工厂,继承或者实现抽象工厂类,并重写其抽象方法,完成具体对象的创建。
代码实现:
/*抽象工厂类*/
public interface IFruitFactory {
abstract Fruit create();
}
/* 苹果工厂类*/
public class AppleFactory implements IFruitFactory{
@Override
public Fruit create() {
return new Apple();
}
}
/*梨工厂类 */
public class PearFactory implements IFruitFactory{
@Override
public Fruit create() {
return new Pear();
}
}
/*测试*/
public class Test {
public static void main(String[] args) {
// 创建对应对象的工厂类
IFruitFactory factory=new AppleFactory();
// 根据具体工厂的创建行为创建对象
Fruit fruit = factory.create();
System.out.println(fruit);
}
}
优缺点
优点:符合开闭原则,当需要扩展对象的创建时,只需要扩展一个工厂类即可。
缺点:每次进行扩展都需要定义一个新的类
抽象工厂
对于一些存在关系的类,例如公司和产品,一个公司有许多产品。举个具体的例子,小米和苹果是两个公司,它们有很多相同的产品种类,例如手机、电脑等等。而抽象工厂模式则是定义一个抽象工厂类,其包含多个产品创建的抽象方法,通过创建具体工厂继承或实现抽象工厂,重写其方法完成产品的具体创建。
/*汽车、手机、电脑的接口*/
public interface Computer {
abstract void go();
}
public interface Phone {
abstract void begin();
}
public interface Car {
abstract void start();
}
/*具体的实现类*/
public class MiCar implements Car{
@Override
public void start() {
System.out.println("小米汽车启动");
}
}
public class MiComputer implements Computer{
@Override
public void go() {
System.out.println("小米电脑开机");
}
}
public class MiPhone implements Phone{
@Override
public void begin() {
System.out.println("小米手机启动");
}
}
苹果的实现类省略。。。
/*我们不妨定义一个抽象工厂,其包含公司各个产品的创建方法*/
public abstract ICompany {
abstract Car getCar();
abstract Computer getComputer();
abstract Phone getPhone();
}
/*具体工厂*/
public class MiCompany extend ICompany{
@Override
public Car getCar() {
return new MiCar();
}
@Override
public Computer getComputer() {
return new MiComputer();
}
@Override
public Phone getPhone() {
return new MiPhone();
}
}
public class AppleCompany extend ICompany{
@Override
public Car getCar() {
return new AppleCar();
}
@Override
public Computer getComputer() {
return new AppleComputer();
}
@Override
public Phone getPhone() {
return new ApplePhone();
}
}
测试:
public class Test {
/*指定具体的工厂类以及方法创建对象*/
public static void main(String[] args) {
ICompany company=new AppleCompany();
Car car = company.getCar();
car.start();
ICompany company1=new MiCompany();
Computer computer = company1.getComputer();
computer.go();
}
}
抽象工厂和工厂方法相比,其实两者很像但是也存在区别,两者都是创建抽象类,以及创建具体的实现类,由实现类完成对象的具体的创建。两者的区别在于工厂方法针对一个接口,抽象工厂针对一组存在依赖关系的接口。
优缺点
优点:可以减少类的创建,对于上面举得例子,我们完成每个具体对象的创建其实只定义了三个类,一个是抽象工厂,另外两个是具体的工厂。如果我们使用工厂方法来做,需要定义手机抽象工厂、汽车抽象工厂、电脑抽象工厂,以及小米手机具体工厂、苹果手机具体工厂…会多了很多类。
缺点:不符合开闭原则,并且扩展比较复杂,如果新增一些其他行为,例如电视的创建,就需要修改抽象工厂以及具体工厂的代码。