设计模式学习笔记-工厂模式
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);
}
}
初代代码->虽然实现了基本的功能,但是还有许多地方需要升级.
- 货架的使用应该具有可复用性.[假如没有装满的话,可以用来放其他的货物.由于使用程序来装货物,所以货物不应该知道货架的细节.]
- 货物应该是存放在对应的货架,不能随意.
- 代码的扩展性弱
- 新增货架的种类后,会导致货架类的使用方式变化,上面的代码扩展性不好,几乎需要重写一次代码.
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();
}
}