上次实现了简单工厂模式,这次我们来学习工厂模式。

先看看工厂模式的代码实现,再来对比这两种工厂模式都有什么特点。

代码:

 1 public class MyFactory2 {
 2     public static void main(String[] args) {
 3         Factory1 studentFactory1 = new StudentFactory1();
 4         Service studentFactory1Service = studentFactory1.getService();
 5         studentFactory1Service.insert();
 6 
 7
 8         Factory1 teacherFactory1 = new TeacherFactory1();
 9         Service teacherFactory1Service = teacherFactory1.getService();
10         teacherFactory1Service.delete();
11     }
12 }
13 
14 interface Service {
15     void insert();
16 
17     void query();
18 
19     void delete();
20 
21     void update();
22 }
23 //实现接口
24 class StudentService1 implements Service {
25 
26     @Override
27     public void insert() {
28         System.out.println("插入学生");
29     }
30 
31     @Override
32     public void query() {
33         System.out.println("查询学生");
34     }
35 
36     @Override
37     public void delete() {
38         System.out.println("删除学生");
39     }
40 
41     @Override
42     public void update() {
43         System.out.println("更新学生");
44     }
45 }
46 
47 class TeacherService1 implements Service {
48 
49     @Override
50     public void insert() {
51         System.out.println("插入老师");
52     }
53 
54     @Override
55     public void query() {
56         System.out.println("查询老师");
57     }
58 
59     @Override
60     public void delete() {
61         System.out.println("删除老师");
62     }
63 
64     @Override
65     public void update() {
66         System.out.println("更新老师");
67     }
68 }
69 
70 interface Factory1 {
71     //方法属性,使用倚赖
72     Service getService();
73 }
74 //实现接口
75 class StudentFactory1 implements Factory1 {
76 
77     @Override
78     public Service getService() {
79         //局部变量,使用倚赖
80         return new StudentService1();
81     }
82 }
83 
84 class TeacherFactory1 implements Factory1 {
85 
86     @Override
87     public Service getService() {
88         //局部变量,使用倚赖
89         return new TeacherService1();
90     }
91 }

代码更长了

UML图:

(接口实现应该是虚线,更正下...)

简单工厂模式的UML图

我们可以看到两种模式最大的区别就是将工厂的实现:

新增工厂接口,再让具体的工厂实现工厂的接口

符合倚赖倒置原则(正置指的是倚赖实现类,倒置倚赖接口编程)

 

同时回一下简单工厂的客户端代码:

1  public static void main(String[] args) {
2     //目标增加学生,删除员工,查询老师,更新老师
3     MySimpleFactory mySimpleFactory = new MySimpleFactory();
4     System.out.println(mySimpleFactory.getMyService(0).myAdd());
5     System.out.println(mySimpleFactory.getMyService(1).myDelete());
6     System.out.println(mySimpleFactory.getMyService(2).myQuery());
7     System.out.println(mySimpleFactory.getMyService(3).myUpdate());
8 }

工厂模式客户端代码

public static void main(String[] args) {
        Factory1 studentFactory1 = new StudentFactory1();
        Service studentFactory1Service = studentFactory1.getService();
        studentFactory1Service.insert();

        Factory1 teacherFactory1 = new TeacherFactory1();
        Service teacherFactory1Service = teacherFactory1.getService();
        teacherFactory1Service.delete();
    }

简单工厂模式:

1.实例化工厂

2.通过通用的工厂实例化操作对象

3.操作对象进行相应的操作

这个过程中是通过工厂的内部逻辑实现对操作对象的直接初始化。

 

工厂模式:

1.实例化工厂

2.通过具体的工厂实例化操作对象

3.操作对象进行相应的操作

通过对指定工厂的具体实例化,实现具体的操作对象(也约等于实例化对象)。

 

上一次说过了,我们写更多的代码。是为了修改和维护起来更加方便。我们来看看在什么后面的维护和修改中两个工厂模式有什么特点

第一个需求:现在我们加入一个员工的增删改查

简单工厂:

1员工service实现service

2工厂中在判断返回对象中新增一个返回员工service对象的 逻辑语句

 

到这里就可以看到弊端了,简单工厂模式需要修改代码,违反了开放封闭原则(对于新增是开放,对于修改是闭合的)

 

那么工厂模式需要怎么做呢,

1工厂模式实现员工的service

2增加员工操作对应的工厂模式

对于现有的代码不需要修改,遵守了开放封闭原则。

 

第二个需求把客户端的代码都改成员工的增删改查

public static void main(String[] args) {
    //目标增加学生,删除员工,查询老师,更新老师
    MySimpleFactory mySimpleFactory = new MySimpleFactory();
    System.out.println(mySimpleFactory.getMyService(4).myAdd());
    System.out.println(mySimpleFactory.getMyService(4).myDelete());
    System.out.println(mySimpleFactory.getMyService(4).myQuery());
    System.out.println(mySimpleFactory.getMyService(4).myUpdate());
}

刚刚所有的工厂传入的参数都需要修改,修改的代码相对较多

如果是工厂模式:

public static void main(String[] args) {
        Factory1 empolyeetFactory1 = new EmpolyeeFactory1();
        Service empolyeetFactory1Service = empolyeetFactory1 .getService();
        empolyeetFactory1Service .insert();
        empolyeetFactory1Service .delete();
    }

可以看到只需要修改具体的工厂实现修改即可,相比简单工厂模式需要修改的代码更少。

 

到这里就可以看到简单工厂和工厂模式的特点:

简单工厂模式把返回操作对象的逻辑封装在工厂中

而工厂模式将实例化具体操作对象(实例化那个操作对象的工厂)逻辑放在客户端

 

区别:

新增功能

简单工厂:需要修改工厂

工厂模式:无修改代码,新增代码即可

修改客户端操作对象

简单工厂:修改工厂传入参数

工厂模式:修改具体工厂的实例化对象

 

当然优缺点也就很明显了

简单工厂模式:代码简洁,工厂中含有必要的逻辑判断,客户只需要传入条件即可 适合于修改较小的项目

工厂模式:遵守倚赖倒置,职责单一,开放闭合,代码较多,但是需要在客户端对实例化对象进行判断   适合较多数情况

 

当然后面我们可以通过反射来避免分子判断的问题(动态的加载类对象)

没有最好的技术,只有最适合业务的解决方案。如果场景业务可以使用简单工厂模式,那就没有必要使用工厂模式。

 

补充:

当然最后我还想试试能让代码优雅点哈哈,当然觉得麻烦可以不用往下看了哈哈。

首先第一点,我想增删改查的确是大部分dao层操作必须的,但是也不是所有的类都需要这几种操作。

所以我想接口应该是4个接口,你有神马操作实现什么操作

public class MyFactory {
    public static void main(String[] args) {
        Factory studentFactory = new StudentFactory();
        Insert studentFactoryInsertClass = studentFactory.getInsertClass();
        studentFactoryInsertClass.insert();

        Factory teacherFactory = new TeacherFactory();
        Delete teacherFactoryDeleteClass = teacherFactory.getDeleteClass();
        teacherFactoryDeleteClass.delete();
    }
}


interface Insert {
    void insert();
}

interface Query {
    void query();
}

interface Delete {
    void delete();
}

interface Update {
    void update();
}

class StudentService implements Insert, Query, Delete, Update {

    @Override
    public void insert() {
        System.out.println("插入学生");
    }

    @Override
    public void query() {
        System.out.println("查询学生");
    }

    @Override
    public void delete() {
        System.out.println("删除学生");
    }

    @Override
    public void update() {
        System.out.println("更新学生");
    }
}

class TeacherService implements Insert, Query, Delete, Update {

    @Override
    public void insert() {
        System.out.println("插入老师");
    }

    @Override
    public void query() {
        System.out.println("查询老师");
    }

    @Override
    public void delete() {
        System.out.println("删除老师");
    }

    @Override
    public void update() {
        System.out.println("更新老师");
    }
}

interface Factory {
    Insert getInsertClass();

    Query getQueryClass();

    Delete getDeleteClass();

    Update getUpdateClass();
}

class StudentFactory implements Factory {


    @Override
    public Insert getInsertClass() {
        return new StudentService();
    }

    @Override
    public Query getQueryClass() {
        return new StudentService();
    }

    @Override
    public Delete getDeleteClass() {
        return new StudentService();
    }

    @Override
    public Update getUpdateClass() {
        return new StudentService();
    }
}

class TeacherFactory implements Factory {


    @Override
    public Insert getInsertClass() {
        return new TeacherService();
    }

    @Override
    public Query getQueryClass() {
        return new TeacherService();
    }

    @Override
    public Delete getDeleteClass() {
        return new TeacherService();
    }

    @Override
    public Update getUpdateClass() {
        return new TeacherService();
    }
}

UML

 

这样看起来就好一点了,还是有个大大的问题。就是我们每个工厂还是实现了4个方法,工厂应该和service的实现方式相同

再想想办法改进下

 1 public class MyFactory3 {
 2     public static void main(String[] args) {
 3         Insert3Factory studentFactory3 = new StudentFactory3();
 4         Insert3 studentFactory3Insert = studentFactory3.getInsert();
 5         studentFactory3Insert.insert();
 6 
 7         Delete3Factory delete3Factory = new TeacherFactory3();
 8         Delete3 delete3FactoryDelete = delete3Factory.getDelete();
 9         delete3FactoryDelete.delete();
10     }
11 }
12 
13 interface Insert3 {
14     void insert();
15 }
16 
17 interface Query3 {
18     void query();
19 }
20 
21 interface Delete3 {
22     void delete();
23 }
24 
25 interface Update3 {
26     void update();
27 }
28 
29 class StudentService3 implements Insert3, Query3 {
30 
31     @Override
32     public void insert() {
33         System.out.println("插入学生");
34     }
35 
36     @Override
37     public void query() {
38         System.out.println("查询学生");
39     }
40 }
41 
42 class TeacherService3 implements Delete3, Update3 {
43 
44     @Override
45     public void delete() {
46         System.out.println("删除老师");
47     }
48 
49     @Override
50     public void update() {
51         System.out.println("更新老师");
52     }
53 }
54 
55 interface Insert3Factory {
56     Insert3 getInsert();
57 }
58 
59 interface Query3Factory {
60     Query3 getQuery();
61 }
62 
63 interface Delete3Factory {
64     Delete3 getDelete();
65 }
66 
67 interface Update3Factory {
68     Update3 getUpdate();
69 }
70 
71 class StudentFactory3 implements Insert3Factory, Query3Factory {
72 
73     @Override
74     public Insert3 getInsert() {
75         return new StudentService3();
76     }
77 
78     @Override
79     public Query3 getQuery() {
80         return new StudentService3();
81     }
82 }
83 
84 class TeacherFactory3 implements Delete3Factory, Update3Factory {
85 
86     @Override
87     public Delete3 getDelete() {
88         return new TeacherService3();
89     }
90 
91     @Override
92     public Update3 getUpdate() {
93         return new TeacherService3();
94     }
95 }

UML

 

 

哈哈哈哈哈到这里代码已经很长了,但是也算是达到了我想要的“面向对象”优雅实现(当然这样也可能不是最好的解决方案,如果你有更好的方案,欢迎留言哟)