工厂方法模式

来源:互联网 发布:网络打印机添加xp 编辑:程序博客网 时间:2024/06/14 03:31

设计模式学习笔记-工厂模式

1.含义

工厂模式定义了一个用户创建对象的接口,让子类决定实例化那一个类.工厂方法模式使一个类的实例化延迟到子类

对于一个大型的软件工程,一个行之有效的方法就是进行模块分解.每一个模块有大量的代码构成,这个模块的功能可以被其他模块使用.使用的方法就是,实例化此模块,调用这个模块的功能.

2.示例代码

示例1

实现商品自动上架功能:把货物放到指定的架子,并打印出信息.

package com.synwork.factorymthod;/** * com.synwork.factorymthod * 商品类 * @Author youxiangyang * @Time 2017/11/4 */public class Goods {    private String name;    public Goods(String name) {        this.name = name;    }    public String getName() {        return name;    }    public void setName(String name) {        this.name = name;    }}/*******************************************************/package com.synwork.factorymthod;/** * com.synwork.factorymthod * 货架类 * @Author youxiangyang * @Time 2017/11/4 */public class SampleShelf {    private String name="normal";    /**     * 打印基本信息     * @param goods     */    public void put(Goods goods){        System.out.println(this.name+"::"+goods.getName());    }}/*******************************************************/package com.synwork.factorymthod;/** * com.synwork.factorymthod * 测试类 * @Author youxiangyang * @Time 2017/11/4 */public class Rundemo {    public static void main(String[] args) {        Goods goods=new Goods("Pen");        SampleShelf sampleShelf=new SampleShelf();        sampleShelf.put(goods);        Goods goods1=new Goods("Ruler");        SampleShelf sampleShelf1=new SampleShelf();        sampleShelf1.put(goods1);    }}

初代代码->虽然实现了基本的功能,但是还有许多地方需要升级.

  1. 货架的使用应该具有可复用性.[假如没有装满的话,可以用来放其他的货物.由于使用程序来装货物,所以货物不应该知道货架的细节.]
  2. 货物应该是存放在对应的货架,不能随意.
  3. 代码的扩展性弱
  4. 新增货架的种类后,会导致货架类的使用方式变化,上面的代码扩展性不好,几乎需要重写一次代码.

3.工厂模式的结构

工厂模式的意义是定义一个创建产品对象的工厂接口,将实际创建工作推迟到子类.这样客户端代码就不会直接耦合需要的类,而是通过一个工厂类来耦合,从而改善代码之间的依赖.

常见的工厂模式:

  1. 简单工厂模式(静态工厂模式)
  2. 工厂方法模式/多态性工厂模式/虚拟构造子模式
  3. 抽象工厂模式/工具箱模式

4.简单工厂模式

一个具体工厂通过条件语句创建多个产品,产品的创建逻辑集中在一个工厂上,客户端通过传递不同的参数给工厂,实现创建不同产品的目的.增加新产品的时候,需要修改工厂类,增加产品类,这并不是很符合OCP原则

例子:按要求”生产汽车”

package com.synwork.factorymthod;/** * com.synwork.factorymthod * 抽象汽车类 * @Author youxiangyang * @Time 2017/11/4 */public abstract class Atuo {    private String catname;    abstract public void run();    public String getCatname() {        return catname;    }    public void setCatname(String catname) {        this.catname = catname;    }}/****************************************************************/package com.synwork.factorymthod;/** * com.synwork.factorymthod * Car * @Author youxiangyang * @Time 2017/11/4 */public class Car extends Atuo{    public Car() {        this.setCatname("PlayCar");    }    @Override    public void run() {        System.out.println("start :"+this.getCatname());    }}/****************************************************************/package com.synwork.factorymthod;/** * com.synwork.factorymthod * Bus * @Author youxiangyang * @Time 2017/11/4 */public class Bus extends Atuo {    public Bus() {        this.setCatname("Bus");    }    @Override    public void run() {        System.out.println("start:"+this.getCatname());    }}/****************************************************************/package com.synwork.factorymthod;/** * com.synwork.factorymthod * 静态工厂 * @Author youxiangyang * @Time 2017/11/4 */public class StaticFactory {  //工厂方法    public static Atuo createAuto(int autoId){        switch (autoId){            case 1:                return new Car();            case 2:                return new Bus();            default:                throw new RuntimeException("not find this class.");        }    }}/****************************************************************/package com.synwork.factorymthod;/** * com.synwork.factorymthod * 客户端代码 * @Author youxiangyang * @Time 2017/11/4 */public class Client {    public static void main(String[] args) {        Atuo atuo=StaticFactory.createAuto(1);        atuo.run();        Atuo atuo1=StaticFactory.createAuto(2);        atuo1.run();    }}

1.优点

  • 用代码和具体使用类的耦合度降低

  • 创建和使用的代码分离,可以独立的变化.维护和扩展高

  • 可以通过外部配置的方法将耦合度进一步降低

2.缺点

  • 当产品类有复杂的等级结构的时候,工厂类只有一个,不太适合.
  • 工厂类集中了所以的产品创建逻辑.(上帝类),一旦这个不能工作,所有的都不能使用了
  • 静态方法作为工厂方法,不能由子类继承,因此可扩展的效果并不好

工厂方法模式

对于静态工厂方法的不足:将不同的产品交给不同的工厂生产.各种工厂中的创建方法可以互相独立的改变.并将这些工厂类抽象为一个共同的父类.

代码示例

  • 参考上面代码:
  • Atuo.java
  • Car.java
  • Bus.java
package com.synwork.factorymthod;/** * com.synwork.factorymthod * 抽象工厂类 * @Author youxiangyang * @Time 2017/11/5 */public  abstract class Factory {    public abstract Atuo createAtuo();}package com.synwork.factorymthod;/** * com.synwork.factorymthod * Car具体工厂类 * @Author youxiangyang * @Time 2017/11/5 */public class CarFactory extends Factory {    @Override    public Atuo createAtuo() {        return new Car();    }}package com.synwork.factorymthod;/** * com.synwork.factorymthod * Bus具体工厂类 * @Author youxiangyang * @Time 2017/11/5 */public class BusFactory extends Factory {    @Override    public Atuo createAtuo() {        return new Bus();    }}package com.synwork.factorymthod;/** * com.synwork.factorymthod * 客户端类 * @Author youxiangyang * @Time 2017/11/5 */public class Client2 {    public static void main(String[] args) {        Factory factory;        Atuo atuo = null;        factory=new CarFactory();        atuo=factory.createAtuo();        atuo.run();        factory=new BusFactory();        atuo=factory.createAtuo();        atuo.run();    }}