学习笔记-设计模式之工厂模式

摘要:本文内容源于视频教程,若有侵权,请联系作者删除。

 

工厂是生产产品,java中的工厂是对象实例化的封装,用户无需关心对象实例化过程。

 一简单工厂

需求:构造不同课程的实例(语文,英语),每门课程都有公共方法:学习。

OK,这个简单,提起键盘就是敲。首先写出课程抽象类以及语文,英语课程。

 1 // 课程抽象类
 2 public interface ICourse {
 3 
 4     public void learning();
 5 }
 6 
 7 // 语文
 8 public class Chinese implements ICourse {
 9     public void learning(){
10         System.out.println("学习语文");
11     }
12 }
13 
14 // 英语
15 public class English implements ICourse {
16     public void learning(){
17         System.out.println("学习英语");
18     }
19 }

编写测试类。

1 public class SimpleFactoryTest {
2     public static void main(String[] args) {
3         ICourse chineseCourse = new Chinese();
4         ICourse EnglishCourse = new English();
5         chineseCourse.learning();
6         EnglishCourse.learning();
7     }
8 }

 这样写可以实现需求,但是当对象的实例化过程很复杂时,这里的代码就不会有这么简单了。在前面的软件设计原则中我们提到了迪米特原则,调用方无需关心实例的创建过程,它只需要拿到创建的对象就可以了,由此出现了简单工厂。

在上面代码基础上,增加了一个简单工厂类。

1     public ICourse createCource(String courseName){
2         if ("Chinese".equals(courseName)){
3             return new Chinese();
4         } else if ("English".equals(courseName)){
5             return new English();
6         }
7         return null;
8     }

此时调用方代码

1 public class SimpleFactoryTest {
2     public static void main(String[] args) {
3         SimpleFactory simpleFactory = new SimpleFactory();
4         ICourse chineseCourse = simpleFactory.createCource("Chinese");
5         ICourse EnglishCourse = simpleFactory.createCource("English");
6         chineseCourse.learning();
7         EnglishCourse.learning();
8     }
9 }

这个例子可能有些勉强,想表达的意思就是对象的创建过程不应该由调用方关心,他只需要知道如何拿到这个对象。当然,工厂模式中createCourse方法的入参可以优化成类实例,有兴趣的可以自己尝试。

由此可见,简单工厂做的事情就是对创建对象过程的封装。同时存在很明显的问题,如果需要新建一门课程,那么就需要修改createCourse方法,这就违背了开闭原则,此时,工厂模式就诞生了。

二 工厂方法模式

工厂方法模式(FatoryMethodPattern)是指定义一个创建对象的接口,但让实现这个接口的类来决定实例化哪个类,工厂方法让类的实例化推迟到子类中进行。

简单来说,工厂只提供规范,不负责实例的创建过程,实例的创建推迟到子类中实现。

首先创建一个工厂。

1 public interface ICourseFactory {
2 
3     ICourse createCourse();
4 }

接着创建语文和英语课程。

public class ChineseCourseFactory implements ICourseFactory {
    @Override
    public ICourse createCourse() {
        return new Chinese();
    }
}

public class EnglishCourseFactory implements ICourseFactory {
    @Override
    public ICourse createCourse() {
        return new English();
    }
}

编写测试类

1 public class FactoryMethodTest {
2     
3     public static void main(String[] args) {
4         ICourseFactory chineseFactory = new ChineseCourseFactory();
5         ICourseFactory englishFactory = new EnglishCourseFactory();
6         chineseFactory.createCourse().learning();
7         englishFactory.createCourse().learning();
8     }
9 }

工厂模式就是在简单工厂的基础上,把创建方法抽象出来,具体的创建过程由子类实现。这样在新增一个课程时只需要新增一个类。同时,每个类负责创建自己的实例,也遵循的单一职责原则。

然而工厂模式的缺点也清晰可见:一个工厂只能负责一类产品的创建,这样就导致了一个项目中有大量的工厂,而每次增加产品种类时都新增一个类,这样大量类便产生了。为了解决这类问题,衍生出了抽象工厂。

三、抽象工厂

抽象工厂模式(Abastract Factory Pattern)是指提供一个创建一系列相关或相互依赖对象的接口,无须指定他们具体的类。

简言之:抽象工厂只是工厂的变种,把工厂中的一个方法扩展到了多个。

下面看一张图

三种产品要生产三种家电,使用工厂方法模式此时需要创建三个工厂类:洗衣机工厂,空调工厂,电冰箱工厂,而且如果后续增加家电类型又要创建新的工厂,可见工厂方法模式已经不适用这种场景了。下面通过抽象工厂模式解决上面问题。

构造产品抽象

public interface IAirCondition {
}

public interface IFan {
}

构造工厂类

public interface AbstractFactory {
    // 风扇
    IAirCondition createAirCondition();
    // 空调
    IFan CreateFan();
}

构建海尔相关产品实例

1 public class HaierCondition implements IAirCondition {
2 }
3 
4 public class HaierFan implements IFan {
5 }

构建海尔工厂

 1 public class HaierFactory implements AbstractFactory {
 2     @Override
 3     public IAirCondition createAirCondition() {
 4         return new HaierCondition();
 5     }
 6 
 7     @Override
 8     public IFan CreateFan() {
 9         return new HaierFan();
10     }
11 }

 

同理,构建格力工厂

 1 public class GeliCondition implements IAirCondition {
 2 }
 3 
 4 public class GeliFan implements IFan {
 5 }
 6 
 7 public class GeliFactory implements AbstractFactory {
 8     @Override
 9     public IAirCondition createAirCondition() {
10         return new GeliCondition();
11     }
12 
13     @Override
14     public IFan CreateFan() {
15         return new GeliFan();
16     }
17 }

 

测试代码

 1 public class AbstractFactoryTest {
 2     public static void main(String[] args) {
 3         AbstractFactory haierFactory = new HaierFactory();
 4         IAirCondition haierCondition = haierFactory.createAirCondition();
 5         IFan haierFan = haierFactory.CreateFan();
 6 
 7         AbstractFactory geliFactory = new GeliFactory();
 8         IAirCondition geliCondition = geliFactory.createAirCondition();
 9         IFan geliFan = geliFactory.CreateFan();
10     }
11 }

抽象工厂用于解决一系列相关产品对象创建的问题,优点是扩展性更强。

需要注意的是:当新增产品时需要修改代码,不符合开闭原则。

 

posted @ 2020-07-08 22:58  落雨有清·风  阅读(157)  评论(0编辑  收藏  举报