简单工厂模式
传统方式的优缺点: 1、优点是比较好理解,简单易操作 2、缺点是违反了设计模式的ocp原则,当我们给类增加新功能的时候,尽量不修改代码,或者尽可能少修改代码
基本介绍:
1、简单工厂模式是属于创建型模式,是工厂模式的一种。简单工厂模式是由一个工厂对象决定创建出哪一种产品类的实例。简单工厂模式是工厂模式家族中最简单使用的模式
2、定义了一个创建对象的类,由这个类来封装实例化对象的行为
3、在软件开发中,当我们需要大量的创建某种、某类或某批对象时,就会使用到工厂模式
例如有一个电脑工厂,生产惠普和华硕2中品牌
public abstract class Computer {
private String name;
/**
* 启动
*/
public abstract void startup();
public void setName(String name){
this.name=name;
}
}
public class HpComputer extends Computer {
@Override
public void startup() {
System.out.println("启动惠普");
}
}
public class HuashuoComputer extends Computer {
@Override
public void startup() {
System.out.println("启动华硕");
}
}
现在创建一个电脑工厂,这里创建实例用的是静态方法
public class ComputerFactory {
public static Computer createComputer(String name){
Computer computer = null;
switch (name){
case "hp":
computer = new HpComputer();
computer.setName(name);
break;
case "huashuo":
computer = new HuashuoComputer();
computer.setName(name);
break;
default:
System.out.println("品牌有误");
}
return computer;
}
}
然后可以通过电脑工厂来调用
public static void main(String[] args) {
Computer hp = ComputerFactory.createComputer("hp");
hp.startup();
Computer huashuo = ComputerFactory.createComputer("huashuo");
huashuo.startup();
}
工厂方法模式
工厂方法模式定义了一个创建对象的抽象方法,由子类决定要实例化的类,它将对象的实例化推迟到子类
简单的讲,就是在简单工厂方法模式上再加一层。将上述的工厂类改为抽象类,里面写抽象方法,方法是实现推迟到子类,这里方法的实现就是对象的实例化。
UML类图如下:
模式组成:
组成(角色) | 关系 | 作用 |
---|---|---|
抽象产品(Product) | 具体的产品关系 | 描述具体产品的公共接口 |
具体产品(Concrete Product) | 抽象产品的子类:工厂类创建的目标类 | 描述生产的具体产品 |
抽象工厂(Creator) | 具体工厂的父类 | 描述工厂的公共接口 |
具体工厂(Concrete Creator) | 抽象工厂的子类;被外界调用 | 描述具体工厂;实现FactoryMethod工厂方法创建产品的实例 |
抽象工厂模式
基本介绍:
1、定义了一个interface用于创建相关或有依赖关系的对象簇,而无需指明具体的类
2、抽象工厂可以将简单工厂模式和工厂方法模式进行整合
3、从设计层面看,抽象工厂模式就是对简单工厂模式的改进(进一步的抽象)
4、将工厂抽象成两层,AbsFactory(抽象工厂)和具体实现的工厂子类。可以根据创建对象类型使用对应的工厂子类,这样将单个的简单工厂类变成了工厂簇,更利于代码的维护和扩展
下面有示例,一个卖Pizza的例子。
AbsFactory接口作为抽象工厂,它有两个实现类,各种订单需求直接调用接口即可。
代码示例:
抽象类Pizza,及其2个抽象子类,4个实现类
public abstract class Pizza {
/**
* 准备Pizza
*/
public abstract void prepare();
public void bake(){
System.out.println("烘焙");
}
public void cut(){
System.out.println("切");
}
public void box(){
System.out.println("烤");
}
}
public abstract class BJPizza extends Pizza{
}
public abstract class LDPizza extends Pizza {
}
public class BJCheesePizza extends BJPizza {
@Override
public void prepare() {
System.out.println("准备北京奶酪Pizza");
}
}
public class BJPepperPizza extends BJPizza{
@Override
public void prepare() {
System.out.println("准备北京胡椒Pizza");
}
}
public class LDCheesePizza extends LDPizza{
@Override
public void prepare() {
System.out.println("准备伦敦奶酪Pizza");
}
}
public class LDPepperPizza extends LDPizza {
@Override
public void prepare() {
System.out.println("准备伦敦胡椒Pizza");
}
}
抽象工厂接口及其两个实现类
public interface AbsFactory {
/**
* 制作Pizza
* @param name
* @return Pizza
*/
Pizza createPizza(String name);
}
public class BJFactory implements AbsFactory {
@Override
public Pizza createPizza(String name) {
switch (name){
case "cheese":
return new BJCheesePizza();
case "pepper":
return new BJPepperPizza();
default:
return null;
}
}
}
public class LDFactory implements AbsFactory {
@Override
public Pizza createPizza(String name) {
switch (name){
case "cheese":
return new LDCheesePizza();
case "pepper":
return new LDPepperPizza();
default:
return null;
}
}
}
调用工厂接口
public class OrderPizza {
public static Pizza createPizza(AbsFactory absFactory,String name){
return absFactory.createPizza(name);
}
public static void main(String[] args) {
createPizza(new BJFactory(),"cheese").prepare();
createPizza(new BJFactory(),"pepper").prepare();
createPizza(new LDFactory(),"cheese").prepare();
createPizza(new LDFactory(),"pepper").prepare();
}
}
调用结果
准备北京奶酪Pizza
准备北京胡椒Pizza
准备伦敦奶酪Pizza
准备伦敦胡椒Pizza
工厂模式在JDK-Calender应用:JDK中的Calendar类中,就使用了简单工厂模式
- 工厂模式的意义:将实例化对象的代码提取出来,放到一个类中统一管理和维护,达到和主项目的依赖关系的解耦,从而提高项目的扩展性和维护性
- 三种工厂模式:
- 简单工厂模式(静态工厂模式)
- 工厂方法模式
- 抽象工厂模式
- 简单工厂模式(静态工厂模式)
对比工厂方法模式与抽象工厂模式
| 工厂方法模式 | 抽象工厂模式 | | —- | —- | | 针对的是一个产品等级结构 | 针对的是面向多个产品等级结构 | | 一个抽象产品类 | 多个抽象产品类 | | 可以派生出多个具体产品类 | 每个抽象产品类都可以派生出多个具体产品类 | | 一个抽象工厂类,可以派生出多个具体工厂类 | 一个抽象工厂类,可以派生出多个具体工厂类 | | 每个具体工厂类只能创建一个具体产品类的实例 | 每个具体工厂类可以创建多个具体产品类的实例 |设计模式的依赖抽象原则:
- 创建对象实例时,不要直接new类,而是把这个new类的动作放在一个工厂的方法中,并返回。换种说法,变量不要直接持有具体类的引用。
- 不要让类继承具体类,而是继承抽象类或者是实现接口
- 不要覆盖基类中已经实现的方
- 创建对象实例时,不要直接new类,而是把这个new类的动作放在一个工厂的方法中,并返回。换种说法,变量不要直接持有具体类的引用。