设计模式学习---工厂模式

 ̄綄美尐妖づ 提交于 2020-04-06 06:05:31

工厂模式:主要用于实例化对象,把实例化对象代码与使用对象代码分开, 目的是降低系统中代码耦合度,并且增强了系统的扩展性,如果实例化一个对象的过长很复杂,需要一定的代码量,并且多处使用就会出现大量重复代码,则可以把这些实例化对象的代码放到工厂管理,可以减少重复代码并且维护时候也相对简单很多。工厂模式分为三种实现方式,就是简单工厂模式,工厂方法模式和抽象工厂模式

简单工厂模式

先抽象一个接口,所有Bean都实现该接口

public interface Bean {
    void massage();
}

接着就是几个Bean:User,Role,Auth

public class Role implements Bean{
    public void massage() {
        System.out.println("this is a role");
    }
}
public class Auth implements Bean{
    public void massage() {
        System.out.println("this is an auth");
    }
}
public class User implements Bean{
    public void massage() {
        System.out.println("this is an user");
    }
}

最后是一个Factory类用于获取对象,因为User,Role,Auth都是属于Bean类,我们可以在工厂获取对象的方法里面直接返回一个Bean类,可以统一管理

public class BeanFactory {

    private static final String BEAN_USER="user";

    private static final String BEAN_ROLE="role";

    private static final String BEAN_AUTH="auth";

    public static Bean createBean(String name){
        switch (name) {
            case BEAN_USER:
                return new User();
            case BEAN_ROLE:
                return new Role();
            case BEAN_AUTH:
                return new Auth();
            default:
                return null;
        }
    }
}

实例化对象与使用方式

Bean bean = BeanFactory.createBean(BeanFactory.BEAN_USER);
bean.massage();

上面就是简单工厂模式的实现方式

优点:相比直接创建对象而言,可以统一管理某类对象的实例化,减少重复代码量

            因为create()函数是静态的,所以简单工厂模式又称为静态工厂模式

缺点:每多一种类型我们就要在create()添加相应的代码,类型越多,代码越多,多到一定程度时该工厂类也难以维护

            并且开闭原则也不推荐直接修改原来的类,而是新增一个扩展类使用

工厂方法模式:

创建工厂接口:

public interface Factory {
    Bean createBean();
}

创建Bean接口:

public interface Bean {
    void massage();
}

创建具体Bean类:

public class User implements Bean{
    @Override
    public void massage() {
        System.out.println("this is an user");
    }
}
public class Auth implements Bean{
    @Override
    public void massage() {
        System.out.println("this is an auth");
    }
}
public class Role implements Bean{
    @Override
    public void massage() {
        System.out.println("this is a role");
    }
}

创建具体工厂类:

public class UserFactory implements Factory {
    @Override
    public Bean createBean() {
        return new User();
    }
}
public class RoleFactory implements Factory{
    @Override
    public Bean createBean() {
        return new Role();
    }
}
public class AuthFactory implements Factory{
    @Override
    public Bean createBean() {
        return new Auth();
    }
}

使用方式:

public static void main(String[] args) {
    UserFactory userFactory = new UserFactory();
    userFactory.createBean().massage();
    AuthFactory authFactory = new AuthFactory();
    authFactory.createBean().massage();
    RoleFactory roleFactory = new RoleFactory();
    roleFactory.createBean().massage();
}

有一个Factory父类,每个对象有专门管理的Factory类,例如想使用User就使用UserFactory来获取User对象

优点: 每个具体工厂类只负责创建对应的产品,不用所有Bean都堆在一个Factory

            create()非静态,可以让其子类继续扩展,解决了简单工厂的扩展问题

缺点:每多一个Bean类不止是加一个Bean类,还要加一个对于的BeanFactory类

          一个Bean工厂只能创建一种具体Bean,修改Bean的时候也有可能需要修改Factory

抽象工厂模式:

顾名思义抽象工厂就是工厂类的一个抽象,例如Auth有分为系统权限和一般权限,Role也会分为系统角色和一般角色,这个时候我们就需要抽象一个如果用工厂方法模式实现我们就需要4个工厂类(系统权限工厂类,一般权限工厂类,系统角色工厂类,一般角色工厂类),我们使用抽象工厂就可以抽象为一个可以创建角色和权限的工厂类,再具体成系统工厂类和一般工厂类

权限抽象类与其2个子类(系统权限,一般权限)

public abstract class Auth implements Bean{
    public abstract void massage();
}
public class SysAuth extends Auth{
    public void massage() {
        System.out.println("system auth");
    }
}
public class GeneralAuth extends Auth{
    public void massage() {
        System.out.println("general auth");
    }
}

角色抽象类与其2个子类(系统角色,一般角色)

public abstract class Role implements Bean{
    public abstract void massage();
}
public class SysRole extends Role{
    public void massage() {
        System.out.println("system role");
    }
}
public class GeneralRole extends Role{
    public void massage() {
        System.out.println("general role");
    }
}

工厂抽象类与其2个子类:

public abstract class AbstractFactory {
    public abstract Auth getAuth();

    public abstract Role getRole();
}
public class SysFactory extends AbstractFactory{
    public Auth getAuth() {
        return new SysAuth();
    }

    public Role getRole() {
        return new SysRole();
    }
}
public class GeneralFactory extends AbstractFactory{
    public Auth getAuth() {
        return new GeneralAuth();
    }

    public Role getRole() {
        return new GeneralRole();
    }
}

使用方式:

public static void main(String[] args) {
    AbstractFactory sysFactory = new SysFactory();
    sysFactory.getAuth().massage();
    sysFactory.getRole().massage();
    AbstractFactory generalFactory = new GeneralFactory();
    generalFactory.getAuth().massage();
    generalFactory.getRole().massage();
}

总结:

三种方式都具有优缺点,要么是提高代码结构复杂度获得更小粒度的工厂,要么是牺牲扩展性能获取简单的代码结构。根据实际情况选择一种合适使用的就行,没有所谓的最好的实现方式

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!