工厂方法模式:简单工厂模式的进一步抽象和推广。工厂方法模式把简单工厂中的具体的工厂类划分为两层:抽象工厂层+具体工厂层,类图如下:
涉及到的角色:
抽象产品角色:所有产品的共同父类或共有接口,用以实现多态。
1 //电脑接口 2 public interface Icomputer{ 3 }
具体产品角色:实现抽象产品角色所声明的接口。
1 //戴尔电脑 2 public class Dell implements Icomputer{ 3 }
1 //联想电脑 2 public class Lenovo implements Icomputer{ 3 }
抽象工厂角色:工厂方法模式的核心,创建对象工厂类必须继承或实现它,实际系统中常常是个抽象类。
1 //定义工厂,它是个抽象类 2 public abstract class AbstractFactory{ 3 public abstract Icomputer createComputer(); 4 }
具体工厂角色:实现了抽象工厂接口的具体类,应用程序调用它以创建具体产品。
1 //戴尔工厂 2 public class DellFactory extends AbstractFactory{ 3 @Override 4 public Icomputer createComputer() { 5 return new Dell(); 6 } 7 }
1 //联想工厂 2 public class LenovoFactory extends AbstractFactory{ 3 @Override 4 public Icomputer createComputer() { 5 return new Lenovo(); 6 } 7 }
应用实例:
1 //客户端 2 public class Client{ 3 private void mian() { 4 AbstractFactory factory = null; 5 factory = new DellFactory(); 6 factory.createComputer(); 7 factory = new LenovoFactory(); 8 factory.createComputer(); 9 } 10 }
这样做的好处就是只需要有Icomputer.java和AbstractFactory.java编译就能通过,另外当需求变化时只需要增加或者删除相应的类就可以。比如要增加华硕电脑只需增加Asus和AsusFactory俩个类即可,克服简单工厂不能拓展的缺陷。
关于IoC与DI:
IoC -- Inversion of Control,控制反转
DI -- Dependency Injection,依赖注入
控制反转和依赖注入是对于同一件事情的不同描述。
依赖注入从应用程序的角度去描述:应用程序依赖容器创建并注入它所需要的外部资源。
控制反转从容器角度去描述:容器控制应用程序,由容器反向地向应用程序注入器所需要的外部资源。
目的是分离了对象和它所需要的外部资源,使得它们松散耦合,有利于功能复用,还能使得程序的整个体系结构变得灵活起来。
使用工厂方法模式达到依赖注入效果,虽然这个例子很不好:
1 //抽象字符串工厂 2 public abstract class StrFactory{ 3 protected abstract String createStr();//耐人寻味的protected 4 public char invoke(){ 5 createStr().charAt(0); 6 } 7 }
1 //具体字符串工厂 2 public class AFactory extends StrFactory{ 3 @Override 4 protected String createStr(){ 5 return new String("A"); 6 } 7 }
1 //客户端代码 2 public class Client{ 3 public static void main(String[] args) { 4 char c = new AFactory().invoke(); 5 } 6 }
想要表达的意思是:AFactory中重写父类的createStr()方法,他的返回值就是StrFactory所依赖注入的对象。归根结底工厂方法的本质就是:延迟到子类来选择实现。