工厂方法模式


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

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();
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

白日与明月

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值