工厂模式是 Java 中最常用的设计模式之一。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。在工厂模式中,我们在创建对象时不会对客户端暴露创建逻辑,并且是通过使用一个共同的接口来指向新创建的对象。
工厂模式的意义在于对象的创建、管理可以使用工厂去管理,而不是创建者自身。
工厂模式分简单工厂和抽象工厂。它们的区别在于抽象工厂抽象程度更高,把工厂也抽象成了一个接口,这样可以再每添加一个新的对象的时候而不需要修改工厂的代码。
比如有个Repository接口,用于存储数据,有DatabaseRepository,CacheRepository,FileRepository分别在数据库,缓存,文件中存储数据,定义如下:
public interface Repository {
void save(Object obj);
}
class DatabaseRepository implements Repository {
@Override
public void save(Object obj) {
System.out.println("save in database");
}
}
class CacheRepository implements Repository {
@Override
public void save(Object obj) {
System.out.println("save in cache");
}
}
简单工厂的使用
public class RepositoryFactory {
public Repository create(String type) {
Repository repository = null;
switch (type) {
case "db":
repository = new DatabaseRepository();
break;
case "cache":
repository = new CacheRepository();
break;
}
return repository;
}
public static void main(String[] args) {
RepositoryFactory factory = new RepositoryFactory();
factory.create("db").save(new Object());
factory.create("cache").save(new Object());
}
简单工厂的弊端在于每添加一个新的Repository(比如新增一个FileRepository),都必须修改RepositoryFactory中的代码,不利于代码扩展。
抽象工厂的使用
public interface RepositoryFactoryProvider {
Repository create();
}
class DatabaseRepositoryFactory implements RepositoryFactoryProvider {
@Override
public Repository create() {
return new DatabaseRepository();
}
}
class CacheRepositoryFactory implements RepositoryFactoryProvider {
@Override
public Repository create() {
return new CacheRepository();
}
}
class FileRepositoryFactory implements RepositoryFactoryProvider {
@Override
public Repository create() {
return new FileRepository();
}
}
抽象工厂测试
public static void main(String[] args) {
AbstractRepositoryFactoryProvider dbProvider = new DatabaseRepositoryFactoryProvider();
dbProvider.getInstance().save(new Object());
AbstractRepositoryFactoryProvider cacheProvider = new CacheRepositoryFactoryProvider();
cacheProvider.getInstance().save(new Object());
AbstractRepositoryFactoryProvider fileProvider = new FileRepositoryFactoryProvider();
fileProvider.getInstance().save(new Object());
}
抽象工厂把工厂也进行了抽象话,所以添加一个新的Repository的话,只需要新增一个RepositoryFactory即可,原有代码不需要修改。