设计模式之工厂模式详解(附源代码)

作者: thorhill | 来源:发表于2018-02-07 01:56 被阅读29次

    工厂模式

    工厂模式(Factory Pattern)是 Java 中最常用的设计模式之一。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。

    在工厂模式中,我们在创建对象时不会对客户端暴露创建逻辑,并且是通过使用一个共同的接口来指向新创建的对象。

    下面举一个栗子:

    我们都是人类(Human),抽象一个Humen接口:

    public interface Human {
        /**
         * 输出身份
         */
        public void showIdentity();
        /**
         * 输出工作内容
         */
        public void showWorkContent();
        /**
         * 输出工资
         */
        public void showSalary();
        /**
         * 自我介绍
         */
        public void showSelf();
    }
    

    先创建一个程序员:

    public class Programmer implements Human {
    
        private Integer salary = 1024;
    
        public Integer getSalary() {
            return salary;
        }
    
        public void setSalary(Integer salary) {
            this.salary = salary;
        }
    
        @Override
        public void showIdentity() {
            System.out.println("我是程序员");
        }
    
        @Override
        public void showWorkContent() {
            System.out.println("996CODING,懂得自然懂");
        }
    
        @Override
        public void showSalary() {
            System.out.println("工资:" + salary);
    
        }
    
        @Override
        public void showSelf() {
            showIdentity();
            showWorkContent();
            showSalary();
    
        }
    
    }
    
    

    一个学生:

    public class Student implements Human {
    
        private Integer salary = 0;
    
        public Integer getSalary() {
            return salary;
        }
    
        public void setSalary(Integer salary) {
            this.salary = salary;
        }
    
        @Override
        public void showIdentity() {
            System.out.println("我是学生");
    
        }
    
        @Override
        public void showWorkContent() {
            System.out.println("念书");
    
        }
    
        @Override
        public void showSalary() {
            System.out.println("工资NuN");
    
        }
    
        @Override
        public void showSelf() {
            showIdentity();
            showWorkContent();
            showSalary();
    
        }
    
    }
    

    和一个老师:

    public class Teacher implements Human {
    
        private Integer salary = 1024;
    
        public Integer getSalary() {
            return salary;
        }
    
        public void setSalary(Integer salary) {
            this.salary = salary;
        }
    
        @Override
        public void showIdentity() {
            System.out.println("我是老师");
    
        }
    
        @Override
        public void showWorkContent() {
            System.out.println("教书即可");
    
        }
    
        @Override
        public void showSalary() {
            System.out.println("工资:" + salary);
    
        }
    
        @Override
        public void showSelf() {
            showIdentity();
            showWorkContent();
            showSalary();
    
        }
    
    }
    

    还有最重要的初代造人工厂0.0(静态工厂):

    public class HumenFactory0 {
        public static final Integer PROGRAMMER = 0;
        public static final Integer STUDENT = 1;
        public static final Integer TRACHER = 2;
    
        public static Human getHumen(Integer type) {
            Human human = null;
            switch (type) {
            case 0:
                human = new Programmer();
                break;
            case 1:
                human = new Student();
                break;
            case 2:
                human = new Teacher();
                break;
            default:
                break;
            }
            return human;
        }
    }
    

    跑起来:

    public class Test {
    
        public static void main(String[] args) {
            Programmer programmer =  (Programmer) HumenFactory0.getHumen(HumenFactory0.PROGRAMMER);
            Student student =  (Student) HumenFactory0.getHumen(HumenFactory0.STUDENT);
            Teacher teacher =  (Teacher) HumenFactory0.getHumen(HumenFactory0.TRACHER);
            
            programmer.setSalary(2048);
            student.setSalary(2048);
            teacher.setSalary(2048);
            
            
            programmer.showSelf();
            student.showSelf();
            teacher.showSelf();
    
        }
    
    }
    

    运行结果:(Perfect)

    我是程序员
    996CODING,懂得自然懂
    工资:2048
    我是学生
    念书
    工资NuN
    我是老师
    教书即可
    工资:2048
    
    优点:
    1. 能够将创建过程打包(废话)
    2. 实现简单
    缺点:
    1. 静态方法,当添加新的成员时,既要加类,也要改现有工厂代码,不符合开闭原则。
    2. 修改工厂代码不仅是在原有工厂类中修改,而且是在原有函数中修改,容易产生各种各样的错误。
    3. 不同的产品需要不同额外参数的时候不支持。(使用僵硬)

    但是, 劳动人民的智慧是伟大的

    二代造人工厂1.0:

    public class HumanFactory1 {
        public static <T> T getClass(Class<? extends T> c) {
            T result = null;
            try {
                result = (T) Class.forName(c.getName()).newInstance();
            } catch (InstantiationException | IllegalAccessException | ClassNotFoundException e) {
    
                // TODO 自动生成的 catch 块
                e.printStackTrace();
            }
            return result;
        }
    }
    

    public class Test {
    
        public static void main(String[] args) {
            
            /*
            Programmer programmer =  (Programmer) HumenFactory0.getHumen(HumenFactory0.PROGRAMMER);
            Student student =  (Student) HumenFactory0.getHumen(HumenFactory0.STUDENT);
            Teacher teacher =  (Teacher) HumenFactory0.getHumen(HumenFactory0.TRACHER);
            
            programmer.setSalary(2048);
            student.setSalary(2048);
            teacher.setSalary(2048);
            
            
            programmer.showSelf();
            student.showSelf();
            teacher.showSelf();
            
            */
            
            Programmer programmer1 =  HumanFactory1.getClass(Programmer.class);
            Student student1 =   HumanFactory1.getClass(Student.class);
            Teacher teacher1 =  HumanFactory1.getClass(Teacher.class);
            
            programmer1.setSalary(4096);
            student1.setSalary(4096);
            teacher1.setSalary(4096);
            
            
            programmer1.showSelf();
            student1.showSelf();
            teacher1.showSelf();
            
            
            
            
    
        }
    
    }
    

    结果:(Excellent)

    我是程序员
    996CODING,懂得自然懂
    工资:4096
    我是学生
    念书
    工资NuN
    我是老师
    教书即可
    工资:4096
    
    优点:
    1. 能够将创建过程打包(废话)。
    2. 反射机制支持,只需要写一次,不出意外用到天荒地老。
    3. 实现方法高大上,装逼必备。
    缺点:
    1. 静态方法,当添加新的成员时,既要加类,也要改现有工厂代码,不符合开闭原则。
    2. 构造是只能调用默认的无参构造函数。(更加僵硬)
      3.Java的反射机制,效率奇低无比。(编译器无法提前优化代码导致)
    3. 实现复杂,比起初代工厂。

    甚至还有一个版本:

    三代造人工厂2.0:

    public class HumanFactory2 {
        public static Programmer getProgrammer() {
            return new Programmer();
        }
    
        public static Student getStudent() {
            return new Student();
        }
    
        public static Teacher getTeacher() {
            return new Teacher();
        }
    }
    
    

    Run:

    public class Test {
    
        public static void main(String[] args) {
            
            /*
            Programmer programmer =  (Programmer) HumenFactory0.getHumen(HumenFactory0.PROGRAMMER);
            Student student =  (Student) HumenFactory0.getHumen(HumenFactory0.STUDENT);
            Teacher teacher =  (Teacher) HumenFactory0.getHumen(HumenFactory0.TRACHER);
            
            programmer.setSalary(2048);
            student.setSalary(2048);
            teacher.setSalary(2048);
            
            
            programmer.showSelf();
            student.showSelf();
            teacher.showSelf();
            
            */
            /*
            Programmer programmer1 =  HumanFactory1.getClass(Programmer.class);
            Student student1 =   HumanFactory1.getClass(Student.class);
            Teacher teacher1 =  HumanFactory1.getClass(Teacher.class);
            
            programmer1.setSalary(4096);
            student1.setSalary(4096);
            teacher1.setSalary(4096);
            
            
            programmer1.showSelf();
            student1.showSelf();
            teacher1.showSelf();
            
            */
            Programmer programmer2 =  HumanFactory2.getProgrammer();
            Student student2 =   HumanFactory2.getStudent();
            Teacher teacher2 =  HumanFactory2.getTeacher();
            
            programmer2.setSalary(8192);
            student2.setSalary(8192);
            teacher2.setSalary(8192);
            
            
            programmer2.showSelf();
            student2.showSelf();
            teacher2.showSelf();
            
            
            
            
    
        }
    
    }
    

    运行结果:(Amazing)

    我是程序员
    996CODING,懂得自然懂
    工资:8192
    我是学生
    念书
    工资NuN
    我是老师
    教书即可
    工资:8192
    

    这种工厂和初代工厂很像,所以优缺点也差不多

    优点:
    1. 能够将创建过程打包(废话)。
    2. 比起初代,更符合开闭原则,虽然略逊于二代。新增对象不用更改原函数,只需增加啊新函数即可,但是要在已有工厂中修改。
    3. 实现最简单。
    缺点:
    1. 不同的产品需要不同额外参数的时候不支持。(同初代)
    2. 有对象时,需要在原有工厂中修改。

    GitHub源代码

    相关文章

      网友评论

        本文标题:设计模式之工厂模式详解(附源代码)

        本文链接:https://www.haomeiwen.com/subject/qivgzxtx.html