列表

详情


113. 请你讲讲工厂模式,手写实现工厂模式

回答思路

得分点 简单工厂、工厂方法、抽象工厂 标准回答 工厂模式(Factory Method Pattern)也叫虚拟构造函数模式或多态性工厂模式,其用意是定义一个创建产品对象的工厂接口,将实际创建性工作推迟到子类中。 工厂模式可以分为简单工厂、工厂方法和抽象工厂模式 简单工厂模式严格来讲并不算是一种设计模式,更多的时候是一种编程习惯。简单工厂的实现思路是,定义一个工厂类,根据传入的参数不同返回不同的实例,被创建的实例具有共同的父类或接口。简单工厂适用于需要创建的对象较少或客户端不关心对象的创建过程的情况。 示例: 创建一个可以绘制不同形状的绘图工具,可以绘制圆形,正方形,三角形,每个图形都会有一个draw()方法用于绘图,首先可以定义一个接口或者抽象类,作为这三个图像的公共父类,并在其中声明一个公共的draw方法: public interface Shape { void draw(); } 下面就是编写具体的图形,每种图形都实现Shape接口: // 圆形 class CircleShape implements Shape { public CircleShape() { System.out.println("CircleShape: created"); } @Override public void draw() { System.out.println("draw: CircleShape"); } } // 正方形 class RectShape implements Shape { public RectShape() { System.out.println("RectShape: created"); } @Override public void draw() { System.out.println("draw: RectShape"); } } // 三角形 public class TriangleShape implements Shape { public TriangleShape() { System.out.println("TriangleShape: created"); } @Override public void draw() { System.out.println("draw: TriangleShape"); } } 下面是工厂类的具体实现: class ShapeFactory { public static Shape getShape(String type) { Shape shape = null; if (type.equalsIgnoreCase("circle")) { shape = new CircleShape(); } else if (type.equalsIgnoreCase("rect")) { shape = new RectShape(); } else if (type.equalsIgnoreCase("triangle")) { shape = new TriangleShape(); } return shape; } } 为工厂类传入不同的type可以new不同的形状,返回结果为Shape 类型,这个就是简单工厂核心的地方了。 工厂方法模式 工厂方法模式具有良好的封装性,代码结构清晰,一个对象创建是有条件约束的,如果一个调用者需要一个具体的产品对象,只要知道这个产品的类名或约束字符串即可,不用知道创建对象的过程如何,降低了模块间的耦合。工厂模式还拥有优秀的可扩展性,在增加产品类的情况下,只要适当地修改具体的工厂类或扩展一个工厂类,就可以适应变化。工厂方法模式是典型的解耦框架,高层模块只需要知道产品的抽象类或接口,其他的实现类都不用关心。举个例子,通过汽车工厂来演示工厂模式: 首先创建一个Car的接口: public interface Car { //品牌 public void brand(); //速度 public void speed(); //价格 public void price(); } 再创建一个Car的抽象工厂: public interface CarFactory { public Car factory(); } 奥迪Audi类实现Car接口,是一个具体的产品: public class Audi implements Car { @Override public void brand() { System.out.println("一台奥迪"); } @Override public void speed() { System.out.println("快"); } @Override public void price() { System.out.println("贵"); } } 奥拓Auto类实现Car接口,是一个具体的产品: public class Auto implements Car{ @Override public void brand() { System.out.println("一台奥拓"); } @Override public void speed() { System.out.println("慢"); } @Override public void price() { System.out.println("便宜"); } } 奥迪工厂AudiFactory实现CarFactory接口,专门用于生产奥迪: public class AudiFactory implements CarFactory { @Override public Car factory() { return new Audi(); } } 奥拓工厂AutoFactory实现CarFactory接口,专门用于生产奥拓: public class AutoFactory implements CarFactory { @Override public Car factory() { return new Auto(); } } 应用场景代码: public class ClientDemo { public static void mn(String[] args) { CarFactory carFactory= new AudiFactory(); Car audi = carFactory.factory(); audi.brand(); audi.speed(); audi.price(); carFactory=new AutoFactory(); Car auto = carFactory.factory(); auto.brand(); auto.speed(); auto.price(); } } 运行结果为: 一台奥迪 快 贵 一台奥拓 慢 便宜 抽象工厂模式(Abstract Factory Pattern)是一种比较常用的模式。为创建一组相关或相互依赖的对象提供一个接口,而且无须指定它们的具体类。抽象工厂模式是工厂方法模式的升级版本。在有多个业务品种、业务分类时,通过抽象工厂模式产生需要的对象是一种非常好的解决方式,抽象方法适用于下和工厂方法一样客户端不需要知道它所创建的对象的类,需要一组对象共同完成某种功能,可能存在多组对象完成不同功能以及系统结构稳定,不会频繁的增加对象的情况。 这里举个例子: 现在需要做一款跨平台的游戏,需要兼容Android,Ios,Wp三个移动操作系统,该游戏针对每个系统都设计了一套操作控制器(OperationController)和界面控制器(UIController),下面通过抽闲工厂方式完成这款游戏的架构设计。 由题可知,游戏里边的各个平台的UIController和OperationController应该是我们最终生产的具体产品。所以新建两个抽象产品接口。 抽象操作控制器: interface OperationController { void control(); } 抽象界面控制器: interface UIController { void display(); } 然后完成各个系统平台的具体操作控制器和界面控制器。 Android: class AndroidOperationController implements OperationController { @Override public void control() { System.out.println("AndroidOperationController"); } } class AndroidUIController implements UIController { @Override public void display() { System.out.println("AndroidInterfaceController"); } } IOS: class IosOperationController implements OperationController { @Override public void control() { System.out.println("IosOperationController"); } } class IosUIController implements UIController { @Override public void display() { System.out.println("IosInterfaceController"); } } WP: class WpOperationController implements OperationController { @Override public void control() { System.out.println("WpOperationController"); } } class WpUIController implements UIController { @Override public void display() { System.out.println("WpInterfaceController"); } } 下面定义一个抽闲工厂,该工厂需要可以创建OperationController和UIController。 public interface SystemFactory { public OperationController createOperationController(); public UIController createInterfaceController(); } 在各平台具体的工厂类中完成操作控制器和界面控制器的创建过程。 Android: public class AndroidFactory implements SystemFactory { @Override public OperationController createOperationController() { return new AndroidOperationController(); } @Override public UIController createInterfaceController() { return new AndroidUIController(); } } IOS: public class IosFactory implements SystemFactory { @Override public OperationController createOperationController() { return new IosOperationController(); } @Override public UIController createInterfaceController() { return new IosUIController(); } } WP: public class WpFactory implements SystemFactory { @Override public OperationController createOperationController() { return new WpOperationController(); } @Override public UIController createInterfaceController() { return new WpUIController(); } } 加分回答 简单工厂模式其实并不算是一种设计模式,更多的时候是一种编程习惯。简单工厂的实现思路是,定义一个工厂类,根据传入的参数不同返回不同的实例,被创建的实例具有共同的父类或接口。 工厂方法模式是简单工厂的仅一步深化, 在工厂方法模式中,我们不再提供一个统一的工厂类来创建所有的对象,而是针对不同的对象提供不同的工厂。也就是说每个对象都有一个与之对应的工厂。工厂方法的实现思路是,定义一个用于创建对象的接口,让子类决定将哪一个类实例化。工厂方法模式让一个类的实例化延迟到其子类。 抽象工厂模式是工厂方法的仅一步深化,在这个模式中的工厂类不单单可以创建一个对象,而是可以创建一组对象。这是和工厂方法最大的不同点。抽象工厂的实现思路是,提供一个创建一系列相关或相互依赖对象的接口,而无须指定它们具体的类。

上一题