Design Pattern [2] —— 工厂模式 +抽象工厂模式 Factory
工厂作用:
创建者和调用者分离( " 解耦 " ==》开闭原则 )
可扩展性强
使用场景:
FactoryBean ==》IOC
日志门面框架slf4j: private final static Logger logger = LoggerFactory.getLogger(HelloWord.class);
JDK 的 Calendar (简单工厂) Calendar calendar = Calendar.getInstance();
JDBC的 Connection
分类:
简单工厂
工厂方法
抽象工厂
符合的OOP原则:开闭原则、依赖倒转原则(针对接口,而不是针对实现)、迪米特法则(只与直接朋友通信)
我的Github里有源码,可以clone下来自己跑下:https://github.com/Yang2199/Design-Pattern/tree/master/src
〇、朴素new对象
首先写个接口:
public interface Car {
void name();
}
然后implement两个类:
public class NIO implements Car {
@Override
public void name() {
System.out.println("This is 蔚来汽车");
}
}
public class Tesla implements Car {
@Override
public void name() {
System.out.println("This is 特斯拉");
}
}
然后写个测试类:
public class Test {
public static void main(String[] args) {
Car car1 = new Tesla();
car1.name();
Car car2 = new NIO();
car2.name();
}
}
这时候需要new出对象来,不高级,没有工厂自动化生产对象
一、静态工厂/ 简单工厂模式 (用的最多)
public class SimpleFactory {
public static Car getCar(String car){
if(car.equals("NIO")) return new NIO(); //简单工厂需要根据传参来判断需要生产的对象类型
if(car.equals("Tesla")) return new Tesla();
else return null;
}
}
测试
public class Test {
public static void main(String[] args) {
CarFactory.getCar("NIO").name(); //进步是传参进去就好了,不用在这里new了
CarFactory.getCar("Tesla").name();
}
}
这种方法也不好,不方便扩展,扩展的时候,还要改原来的代码。==》不满足 "开闭原则"
二、工厂方法 模式
加一层,为每个类型写一个new的工厂;
增加了代码量,但是符合OOP原则:开闭原则(新增功能不用改原来的代码)
public interface Factory {
Car getCar();
}
public class TeslaFactory implements Factory{
@Override
public Car getCar() {
return new Tesla(); //getCar调用Tesla()类的构造器
}
}
public class NIOFactory implements Factory {
@Override
public Car getCar() {
return new NIO();
}
}
public class Test {
public static void main(String[] args) {
Car car1 = new TeslaFactory().getCar();
car1.name();
new NIOFactory().getCar().name();
}
}
三、抽象工厂 模式
抽象工厂("工厂的工厂")负责创建各个工厂,是一个超级工厂
适用场景:m个工厂(“品牌”)* n种产品
例子:
具体代码:
public interface Phone { void start(); void shutdown(); void call(); void message(); }
public class HuaweiPhone implements Phone{ @Override public void start() { System.out.println("开启华为手机"); } @Override public void shutdown() { System.out.println("关闭华为手机"); } @Override public void call() { System.out.println("华为打电话"); } @Override public void message() { System.out.println("华为打电话"); } }
public class XiaomiPhone implements Phone{ @Override public void start() { System.out.println("开启小米手机"); } @Override public void shutdown() { System.out.println("关闭小米手机"); } @Override public void call() { System.out.println("小米打电话"); } @Override public void message() { System.out.println("小米打电话"); } }
public interface Router { void start(); void shutdown(); void wifi(); }
public class HuaweiRouter implements Router{ @Override public void start() { System.out.println("打开华为路由器"); } @Override public void shutdown() { System.out.println("关闭华为路由器"); } @Override public void wifi() { System.out.println("华为wifi"); } }
public class XiaomiRouter implements Router{ @Override public void start() { System.out.println("打开小米路由器"); } @Override public void shutdown() { System.out.println("关闭小米路由器"); } @Override public void wifi() { System.out.println("小米wifi"); } }
然后开始创建工厂:
public interface AbstractFactory { Phone phone(); Router router(); }
public class HuaweiFactory implements AbstractFactory{ @Override public Phone phone() { return new HuaweiPhone(); } @Override public Router router() { return new HuaweiRouter(); } }
public class XiaomiFactory implements AbstractFactory{ @Override public Phone phone() { return new XiaomiPhone(); } @Override public Router router() { return new XiaomiRouter(); } }
Test:
public class Test {
public static void main(String[] args) {
System.out.println("======Huawei系列产品======");
HuaweiFactory huaweiFactory = new HuaweiFactory();
Phone phone = huaweiFactory.phone(); //实际生产的时候,分两层,第一层找具体factory,第二层找具体产品
phone.call();
phone.shutdown();
Router router =huaweiFactory.router();
router.wifi();
System.out.println("======小米产品======");
XiaomiFactory xiaomiFactory = new XiaomiFactory();
Phone phone2= xiaomiFactory.phone();
phone2.message();
}
}
以上代码生成 Class Diagram:
特色:
一个Factory作为一个产品簇,这样实际生产的时候,分两层,第一层找具体factory,第二层找具体产品
增/删 新的品牌,无需更改原有代码;
增/删 新的产品,对原有改动很小
简单工厂
工厂:
3种工厂特色对比: