工厂模式
一、概括
工厂模式属于创建型模式,它提供了一种创建对象的最佳方式。
特点:为创建对象提供过渡接口,以便在客户端将创建对象的具体过程(细节)屏蔽隔离起来,达到提高灵活性的目的。
工厂模式根据抽象程度的不同分为三种:
(1)简单工厂模式(也叫"静态"工厂模式)
特点:实质是由一个工厂类根据传入的参数,动态决定应该创建哪一个产品类(这些产品类继承自一个父类或接口)的实例。
需求引入:现在要打开一个门,根据不同的门完成不同的开门的动作---不知道设计模式的前提
说明:用Hand来打开Door,其中Door1、Door2是Door的子实现类
实例1:
Door
package pdemo;
public abstract class Door {
public abstract void opendoor();
}
Door1
package pdemo;
public class Door1 extends Door {
@Override
public void opendoor() {
System.out.println("把铁门使劲推开");
}
}
Door2
package pdemo;
public class Door2 extends Door {
@Override
public void opendoor() {
System.out.println("把木门轻轻拉开");
}
}
Test
package pdemo;
public class Test {
public static void main(String[] args) {
Hand hand = new Hand("door1");
hand.door.opendoor();
Hand hand1 = new Hand("door2");
hand1.door.opendoor();
}
}
出现问题:如果直接在客户端使用new表达式的方式创建对象,会使得Hand与D1、D2耦合(外界可以通过new的方式)
那么java开发原则是:高内聚,低耦合---自己的事情尽量自己干;所以要解决的问题:Hand与D1、D2耦合,如何解耦?
解决方案:为了避免Hand中出现硬编码的new表达式(关于在Hand中使用Java反射机制后续会提及),可以设计一个类DoorFactory,将Hand构造器中的代码封装起来,使得Hand解除对那些具体类的依赖。
方案说明:显然这是一种讨巧的技术,看似没有技术含量;但是一旦打开一种新的思路,就可以创造出更精巧的技术
改变:将Hand的构造方法私有化,通过根据传入的参数类型,在静态方法创建具体的对象
DoorDactory
package creational.factory;
public class DoorFactory{ //构造方法可以不私有化(最好私有化)
public static Door getObject(String typeName) {
if(typeName.equals("D1")){
return new D1();
}else if(typeName.equals("D2")){
return new D2();
}else{
return null;
}
}
}
以Cat、Dog的例子说明
实例2
工厂类
package staticfactoryre;
public class Factory {
//工厂类的作用就是创建具体的对象----通过多态的形式
private Factory(){
/* (1)
* 构造方法私有化,不让外界创建对象
* 回顾说明:如果不私有化就会默认为public
*/
}
/* (2)提供静态功能,每一种静态方法都会提供所需要的对象
* 说明:通过静态方法创建对象(也可以通过在静态方法中根据传入的参数创建对象或者在构造方法中完成)
*/
public static Animal creatDog(){
return new Dog();
}
public static Animal creatCat(){
return new Cat();
}
}
抽象类
package staticfactoryre;
public abstract class Animal {
//抽象类:公共的方法
public abstract void eat();
}
具体类
package staticfactoryre;
public class Cat extends Animal {
@Override
public void eat() {
System.out.println("猫吃鱼");
}
}
测试类
package staticfactoryre;
/**
* @author Orange
* @version 1.8
*/
public class Demo {
public static void main(String[] args) {
//(1)
Animal cat = Factory.creatCat();
cat.eat();
System.out.println("------------------");
//(2)
Animal dog = Factory.creatDog();
dog.eat();
}
}
说明:Dog类略
到这里了,就不得不回过头思考它出现的背景,解决的问题,优缺点等
背景及解决的问题:可以参考1:点击打开链接,2:点击打开链接
总结
抽象工厂类负责定义创建对象的接口(通俗的讲通过多态创建具体的对象);具体对象的创建工作由继承抽象类的具体子实现类实现
抽象类:只是定义了各个类共有的功能(行为)---声明;具体类--实现具体对象的功能----实现;工厂类(用它制造一些需要的对象)
优点:
(1) 使用静态工厂模式的优点是"实现责任的分割",该模式的核心是工厂类,工厂类含有必要的选择逻辑,可以决定什么时候创建哪一个产品的实例,而客户端则免去直接创建产品的责任,而仅仅是消费产品。也就是说静态工厂模式在不改变客户端代码的情况可以动态的增加产品,明确了类的职责. (2) 为创建对象提供过渡接口,以便将创建对象的具体过程屏蔽隔离起来,达到提高灵活性的目的。
缺点:
(1)这个静态工厂类负责"所有对象"的创建,如果有新的对象增加,或者某些对象的创建方式不同,就需要不断的"修改工厂类",不利于后期的"维护"---(细节问题更难)