设计模式学习——工厂模式
工厂模式有几种不同方式:简单工厂模式、工厂方法模式、抽象工厂模式。用来统一管理不同产品的创建。
简单工厂模式
- 定义:属于类的创新型模式,又称静态工厂方法模式,通过专门定义一个类来负责创建其他类的实例,被创建的实例通常都具有共同的父类。
- 包含的角色及其职责:
- 工厂角色:这是简单工厂模式的核心,由它负责创建所有类的内核逻辑。能够被外界调用,创建所需的产品对象。
- 抽象产品角色:简单工厂模式所创建的所有对象的父类(可以是接口也可以是抽象类),负责描述所有实例所共有的公共接口。
、* 具体产品角色:简单工厂所创建的具体实例对象。
- 核心思想:有一个专门的类来负责创建实例的过程。 实质是选择实现的过程。
- 优缺点
优点:用户无需了解对象是如何创建及如何组织的,有利于整个软件体系结构的优化。
缺点:违背单一职责原则和开放封闭原则。 - android中简单工厂模式之一就是获取服务的系统方法“getSystemService”
- 简单示例:
- 工厂角色
/**
* 工厂类,用来创建Api对象
* @author dream
*
*/
public class Factory {
/**
* 具体创建Api对象的方法
* @param condition 从外部传入的选择条件
* @return 创建好的Api对象
*/
public static Api createApi(int condition){
//应该根据某些条件去选择创建哪一个具体的实现对象
//这些条件可以从外部传入,也可以从其他途径来获取
//如果只有一个实现,可以省略条件,因为你没有选择的必要
Api api = null;
if(condition == 1){
api = new ImplA();
}else if(condition == 2){
api = new ImplB();
}
return api;
}
}
- 抽象产品
/**
* 接口的定义,该接口可以通过简单工厂来创建
*/
public interface Api {
/**
* 示意,具体功能方法的定义
*/
public void operation(String s);
}
- 具体产品
public class ImplA implements Api{
@Override
public void operation(String s) {
//实现功能的代码
System.out.println("ImplA s==" + s);
}
}
public class ImplB implements Api{
@Override
public void operation(String s) {
//实现功能的代码
System.out.println("ImplB s==" + s);
}
}
- 客户端测试用例
public class Client {
public static void main(String[] args) {
//通过简单工厂来获取接口对象
Api api = Factory.createApi(1);
api.operation("正在使用简单工厂");
}
}
工厂方法模式
- 定义:同样属于类的创建型模式,又称多态工厂模式。意义是定义一个创建产品对象的工厂接口,让子类决定实例化哪个类。(当只有一个工厂类时,可简化相当与简单工厂)
- 包含的角色及其职责:
A、抽象工厂角色:这是工厂方法模式的核心,任何工厂类都必须实现这个接口。
B、具体工厂角色:具体工厂类是抽象工厂的一个实现,负责实例化产品对象。
C、抽象产品角色:工厂方法模式所创建的所有产品的父类(可以是接口也可以是抽象类)。
D、具体产品角色:工厂方法所创建的具体实例对象。 - 工厂方法模式解决的是同一系列产品的创建问题。
- 优缺点
优点:当系统拓展需要添加新的产品对象时,仅需添加一个具体对象以及一个具体工厂对象,原有工厂对象不需修改。很好符合开放封闭原则。
缺点:把简单工厂模式的内部判断逻辑转移到了客户端,客户端需要决定实例化哪一个具体的工厂。 - android的activity和service等核心组件中都定义了onCreate()方法。和List和Set都用到此模式。
- UML图
7.简单实现
- 抽象的工厂类
public abstract class AGrower {
//抽象的果农类,生产水果的方法
public abstract <T extends Fruits> T getFruits(Class<T> clz);
}
- 具体的工厂类
这是一种简洁的实现,其实也可以分别为每一个产品都定义一个具体的工厂。
public class Grower extends AGrower{
public <T extends Fruits> T getFruits(Class<T> clz) {
try {
Fruits fruits = (Fruits) Class.forName(clz.getName()).newInstance(); //反射获得产品类的实例
return (T) fruits;
} catch (Exception e) {
return null;
}
}
}
- 抽象产品类
public abstract class Fruits {
/**
* 水果的名称(产品属性)
*/
public abstract void name();
}
- 具体产品类
public class Banana extends Fruits {
@Override
public void name() {
System.out.println("my name is banana");
}
}
public class Apple extends Fruits {
@Override
public void name() {
System.out.println("my name is apple");
}
}
- 客户测试类
public class Client {
public static void main(String[] args) {
//构建一个生产水果的果农对象 (工厂)
Grower grower = new Grower();
//获得具体的水果(产品)
Fruits banana = grower.getFruits(Banana.class);
banana.name();
Fruits apple = grower.getFruits(Apple .class);
apple.name();
}
}
抽象工厂模式
- 抽象工厂模式:是所有形态 的工厂模式中最为抽象和最具一般性的。抽象工厂模式可以向客户端提供一个接口,使客户端在不必指定产品类型的情况下,能够创建多个产品族的产品对象。
- 包含的角色及其职责:
- 抽象工厂角色:这是工厂方法模式的核心,包含对多个产品结构的声明,任何工厂类都必须实现这个接口。
- 具体工厂角色:具体工厂类是抽象工厂的一个实现,负责实例化某个产品族中的产品对象。
- 抽象产品角色:抽象模式所创建的所有对象的父类(可以是接口也可以是抽象类),负责描述所有实例所共有的公共接口。
- 具体产品角色:抽象模式所创建的具体实例对象。
-
工厂方法模式针对的是一个产品等级结构;而抽象工厂模式针对的是多个产品等级结构。
-
优缺点
优点:客户端不再负责对象的具体创建,而是把这个任务交给了具体工厂类,客户端只负责对对象的调用。
缺点:新产品加入时,需要修改抽象工厂类的设计,导致要修改所有具体工厂类。 -
android应用开发中涉及到的IPC通信就是抽象工厂模式很好的说明。
-
UML图
-
实现demo
- 抽象工厂:AbstractFactory接口
//抽象工厂,定义了生产族产品的方法;
public interface AbstractFactory {
public ProductA factoryA();
public ProductB factoryB();
}
- 抽象产品:ProductA接口
//抽象产品A定义了产品的公共方法,产品A和B属于一个产品族
public interface ProductA {
public void method1();
public void method2();
}
- 抽象产品:ProductB接口
//抽象产品B定义了产品的公共方法,产品A和B属于一个产品族
public interface ProductB {
public void method1();
public void method2();
}
- 具体工厂(生产等级为1的族产品):ConcreteFactory1类
[html] view plain copy
//ConcreateFactory1是用来生产等级为1的产品A,B;
public class ConcreateFactory1 implements AbstractFactory {
//生产等级为1的产品A
@Override
public ProductA factoryA() {
// TODO Auto-generated method stub
return new ConcreateProductA1();
}
//生产等级为1的产品B
@Override
public ProductB factoryB() {
// TODO Auto-generated method stub
return new ConcreateProductB1();
}
}
- 具体工厂(生产等级为2的族产品):ConcreteFactory2类
[html] view plain copy
public class ConcreateFactory2 implements AbstractFactory {
//生产等级为2的产品A
@Override
public ProductA factoryA() {
// TODO Auto-generated method stub
return new ConcreateProductA2();
}
//生产等级为2的产品B
@Override
public ProductB factoryB() {
// TODO Auto-generated method stub
return new ConcreateProductB2();
}
}
- 具体产品(等级为1的A产品):ConcreteProductA1类
[html] view plain copy
//等级为1的具体产品A
public class ConcreateProductA1 implements ProductA {
@Override
public void method1() {
// TODO Auto-generated method stub
System.out.println("等级为1的产品A的method1()");
}
@Override
public void method2() {
// TODO Auto-generated method stub
System.out.println("等级为1的产品A的method2()");
}
}
- 具体产品(等级为2的A产品):ConcreteProductA2类
[html] view plain copy
//等级为2的具体产品A
public class ConcreateProductA2 implements ProductA {
@Override
public void method1() {
// TODO Auto-generated method stub
System.out.println("等级为2的产品A的method1()");
}
@Override
public void method2() {
// TODO Auto-generated method stub
System.out.println("等级为2的产品A的method2()");
}
}
- 具体产品(等级为1的B产品):ConcreteProductB1类
[html] view plain copy
//等级为1的产品B
public class ConcreateProductB1 implements ProductB{
@Override
public void method1() {
// TODO Auto-generated method stub
System.out.println("等级为1的产品B的method1()");
}
@Override
public void method2() {
// TODO Auto-generated method stub
System.out.println("等级为1的产品B的method2()");
}
}
- 具体产品(等级为2的B产品):ConcreteProductB2类
[html] view plain copy
//等级为2的产品B
public class ConcreateProductB2 implements ProductB {
@Override
public void method1() {
// TODO Auto-generated method stub
System.out.println("等级为2的产品B的method1()");
}
@Override
public void method2() {
// TODO Auto-generated method stub
System.out.println("等级为2的产品B的method2()");
}
}