标签:举例 als int oid 工厂方法模式 system lse ext color
工厂方法模式的应用非常广泛,结构也比较简单。在我们需要创建复杂对象,或创建实现某个接口的对象时,为了隐藏创建对象的过程,就可以用工厂方法来代替直接的new一个对象。从而达到对复杂对象的创建进行统一管理,或接口与实现相分离的目的。
工厂方法模式可以按照工厂的多少分为三类:
1.简单工厂模式或静态工厂模式
例如现在要生产复杂的SimpleProduct对象,因为只有一种要生产的对象,无需对其进行抽象,所以直接可以创建如下的工厂:
public class SimpleFactory { public static SimpleProduct createSimpleProduct() { //创建SimpleProduct对象 return new SimpleProduct(); } }
简单工厂适用于确定只有单一的复杂对象需要生产的场景。
2.多工厂的工厂方法模式
如果要生产的复杂对象是同一类别的不同实现类,如ProductA和ProductB,此时需要不同的工厂来对应生产这两种对象。我们首先建立产品的抽象类或接口,具体的产品来实现:
public abstract class Product { /** * 定义抽象产品方法,具体产品实现 */ public abstract void work(); }
public class ProductA extends Product { @Override public void work() { System.out.println("this is product A"); } }
public class ProductB extends Product { @Override public void work() { System.out.println("this is product B"); } }
有了产品的抽象,我们再创建工厂的抽象,并在生产产品对象的方法中返回产品的抽象,在工厂实现中创建不同的产品:
public abstract class ProductFactory { /** * 定义抽象工厂方法,具体工厂实现 * @return 产品的抽象 */ public abstract Product createProduct(); }
public class ProductFactoryA extends ProductFactory { @Override public Product createProduct() { return new ProductA(); } }
public class ProductFactoryB extends ProductFactory { @Override public Product createProduct() { return new ProductB(); } }
当需要产品对象时,直接通过对应的工厂来创建,我们不关心不同产品的创建过程。因为客户类依赖的是产品的抽象,如果需要更换产品,只需要修改工厂方法中创建产品的实现,或增加新产品的实现和对应的工厂实现。这样,将接口与实现相分离,提高了代码的可维护性和可扩展性。
3.抽象工厂模式
普通的工厂方法模式中,只有Product基类这一种产品,当需要生产多种类别的产品时,就需要升级到抽象工厂模式了。
举例,PC厂商会生产鼠标键盘等产品,如果只生产一种,比如鼠标,就直接按照上面普通工厂模式的写法,如果既要生产鼠标又要生产键盘就要使用抽象工厂了。
现在建立PC厂商抽象工厂和鼠标,键盘两种产品的抽象:
public abstract class PCFactory { public abstract Mouse createMouse(); public abstract Keyboard createKeyboard(); }
public abstract class Mouse { public abstract void method(); }
public abstract class Keyboard { public abstract void method(); }
现在有戴尔,惠普两个厂商,都会生产自家品牌的这两种产品。因此要实现两个厂商的产品类和厂商工厂类,并在各自的工厂方法中返回自家的产品对象:
惠普的产品
public class HPMouse extends Mouse { @Override public void method() { System.out.println("this is HP Mouse"); } }
public class HPKeyboard extends Keyboard { @Override public void method() { System.out.println("this is HP Keyboard"); } }
戴尔的产品
public class DELLMouse extends Mouse { @Override public void method() { System.out.println("this is DELL Mouse"); } }
public class DELLKeyboard extends Keyboard { @Override public void method() { System.out.println("this is DELL Keyboard"); } }
两个厂商的工厂类,并在工厂方法中返回自家的产品对象:
public class HPPCFactory extends PCFactory { @Override public Mouse createMouse() { return new HPMouse(); } @Override public Keyboard createKeyboard() { return new HPKeyboard(); } }
public class DELLPCFactory extends PCFactory { @Override public Mouse createMouse() { return new DELLMouse(); } @Override public Keyboard createKeyboard() { return new DELLKeyboard(); } }
客户端调用,要生产戴尔的产品:
public class Client { public static void main(String[] args) { PCFactory factory = new DELLPCFactory(); Mouse mouse = factory.createMouse(); Keyboard keyboard = factory.createKeyboard(); mouse.method(); keyboard.method(); } }
如果需要换成其它厂商的产品,我们只需要将new DELLPCFactory()更换为另一个工厂,生产出的产品即为该厂商的产品。新增厂商需要再实现对应的工厂和产品类。
为了继续隐藏创建工厂时new一个具体工厂的操作,让客户端不依赖具体工厂,还可增加一个工厂的工厂类:
public class PCFactoryProvider { public static PCFactory getPCFactory(String type) { if (type.equals("DELL")) { return new DELLPCFactory(); } else if (type.equals("HP")) { return new HPPCFactory(); } return null; } }
客户端调用:
public class Client { public static void main(String[] args) { PCFactory factory = PCFactoryProvider.getPCFactory("DELL"); if (factory != null) { Mouse dellMouse = factory.createMouse(); Keyboard dellKeyboard = factory.createKeyboard(); dellMouse.method(); dellKeyboard.method(); } } }
这样,客户端只是面向接口编程而已,不需要依赖具体的工厂和产品实现,在切换产品时会更加灵活。当然,抽象工厂的缺点也很明显,不仅类的数量众多,而且当需要新增产品类别时,由于修改了工厂抽象方法,导致所有的工厂实现和都需要改动。
标签:举例 als int oid 工厂方法模式 system lse ext color
原文地址:https://www.cnblogs.com/wanghan5950/p/13290761.html