工厂模式:主要用于实例化对象,把实例化对象代码与使用对象代码分开, 目的是降低系统中代码耦合度,并且增强了系统的扩展性,如果实例化一个对象的过长很复杂,需要一定的代码量,并且多处使用就会出现大量重复代码,则可以把这些实例化对象的代码放到工厂管理,可以减少重复代码并且维护时候也相对简单很多。工厂模式分为三种实现方式,就是简单工厂模式,工厂方法模式和抽象工厂模式
简单工厂模式:
先抽象一个接口,所有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(); }
总结:
三种方式都具有优缺点,要么是提高代码结构复杂度获得更小粒度的工厂,要么是牺牲扩展性能获取简单的代码结构。根据实际情况选择一种合适使用的就行,没有所谓的最好的实现方式
来源:oschina
链接:https://my.oschina.net/u/2925037/blog/3215794