工厂模式:
- 简单工厂模式
- 工厂方法模式
- 抽象工厂模式
面向对象设计的基本原则:
- OCP(开放原则 Open-Closed Principe) : 一个软件的实体应当对拓展开放,对修改关闭。
- DIP(依赖倒转原型,Dependence Inversion Principle):要针对接口编程,不要针对实现编程。
- LoD(迪米特法则,Law of Demeter):只与你得朋友通信,而避免和陌生人通信。
简单工厂模式:
简单工厂模式 也可以叫做静态工厂模式,就是工厂一般使用静态方法 通过接收参数的形式来返回不同的对象实例。
对于新增产品无能为力。不修改代码的话是 无法拓展的
简单工厂代码:
创建一个车的接口:
package cn.fllday.factory;
/**
* 创建一个Car 的接口
* @author gssznb
*
*/
public interface Car {
void run();
}
创建一个创建车的工厂:
package cn.fllday.factory;
/**
* 简单工厂模式
* 简单工厂模式 也可以叫做静态工厂模式,就是工厂一般使用静态方法 通过接收参数的形式来返回不同的对象实例。
* 对于新增产品无能为力。不修改代码的话是 无法拓展的。
* @author gssznb
*
*/
public class CarFactory {
public static Car createAudi() {
return new Audi();
}
public static Car createBenBen() {
return new BenBen();
}
}
两种车的型号:
package cn.fllday.factory;
public class Audi implements Car {
@Override
public void run() {
// TODO Auto-generated method stub
System.out.println("我是Audi");
}
}
package cn.fllday.factory;
public class BenBen implements Car{
@Override
public void run() {
// TODO Auto-generated method stub
System.out.println("我是奔奔");
}
}
通过Client 类 来调用
package cn.fllday.factory;
/**
* 简单工厂模式
* @author gssznb
*
*/
public class Client01 {
public static void main(String[] args) {
Car audi = CarFactory.createAudi();
audi.run();
Car benben = CarFactory.createBenBen();
benben.run();
}
}
工厂方法模式:
为了避免简单工厂模式的缺点,不完全满足OCP工厂模式和简单工厂模式最大的不同在于,简单工厂模式只有一个(对于一个项目或者一个独立的模块)工厂类,而工厂模式有一组实现了相同接口的工厂类
创建车的接口和车的工厂:
package cn.fllday.factory.method;
public interface Car {
void run();
}
package cn.fllday.factory.method;
/**
* 创建一个工厂接口
* 为了避免简单工厂模式的缺点,不完全满足OCP
* 工厂模式和简单工厂模式最大的不同在于,简单工厂模式只有一个(对于一个项目或者一个独立的模块)工厂类,
* 而工厂模式有一组实现了相同接口的工厂类
* @author gssznb
*
*/
/**
* 简单工厂和工厂模式比较
* 结构复杂度
* 从这个角度比较,显然 简单工厂要占优势。简单工厂只需要一个工厂类,而工厂方法模式的工厂类随着产品的个数增多而增加。
* 这样就会使类的个数越来越多,无疑是增加了结构的复杂程度。
* 代码复杂度
* 代码复杂度和结构复杂度是一对矛盾,既然简单工厂模式在结构方面比较简洁,那么代码方面肯定是要比工厂方法模式的复杂的了。
* 简单工厂模式的工厂类随着产品的个数增多而增加很多方法。而工厂方法模式每个具体工厂只完成一项产品的任务。代码简洁
* 客户端编制难度
* 工厂方法模式虽然在工厂类结构中引入了接口从而满足了OCP,但是在客户端代码中需要对工厂进行实例化。
* 而简单工厂类是一个静态类。在客户端无法实例化。
* 管理上的难度
* 这是个关键的问题。
* 扩展,工厂方法模式完全满足于OCP,即 他又非常良好的拓展性,那是否就说明了简单工厂模式就没有了拓展性呢?
* 答案是否定的。简单工厂模式同样具有良好的拓展性。拓展的时候,仅需要修改少量的代码。修改工厂类的代码。
* 就可以满足拓展性的要求了。
*
*
* @author gssznb
*
*/
public interface CarFactory {
Car createCar();
}
创建车的类型:
我们新增产品就不需要进行修改原有的代码。只需要创建新的类就可以了
package cn.fllday.factory.method;
public class BenBen implements Car{
@Override
public void run() {
// TODO Auto-generated method stub
System.out.println("我是奔奔");
}
}
package cn.fllday.factory.method;
public class Audi implements Car {
@Override
public void run() {
// TODO Auto-generated method stub
System.out.println("我是Audi");
}
}
根据两种车创建两种车的工厂:
package cn.fllday.factory.method;
public class AudiFactory implements CarFactory{
@Override
public Car createCar() {
// TODO Auto-generated method stub
return new Audi();
}
}
package cn.fllday.factory.method;
public class BenBenFactory implements CarFactory{
@Override
public Car createCar() {
// TODO Auto-generated method stub
return new BenBen();
}
}
通过Client 调用
package cn.fllday.factory.method;
public class Client01 {
public static void main(String[] args) {
Car c1 = new AudiFactory().createCar();
Car c2 = new BenBenFactory().createCar();
c1.run();
c2.run();
}
}
工厂方法模式,可以增加新的产品。但是如果添加的多了。类的数量也增加的太多。导致项目结构不太友好。所以一般开发中使用简单工厂就可以了。
抽象工厂模式:
用来生产不同产品族的全部产品,(对于新增加的产品,无能为力。支持增加产品组)。抽象工厂模式是工厂模式的升级版本。在有多个业务品种,业务分类时,通过抽象工厂模式产生需要的对象是一种非常好的解决方式。
创建一个车的工厂:
可以制造 引擎,制造座椅,制造轮胎。
package cn.fllday.factory.abstracts;
public interface CarFactory {
Engline createEngline();
Seat createSeat();
Tyre createTyre();
}
创建引擎,座椅,轮胎的接口和实现类:
package cn.fllday.factory.abstracts;
public interface Engline {
void start();
}
class LuxuryEngline implements Engline{
@Override
public void start() {
// TODO Auto-generated method stub
System.out.println("启动快");
}
}
class LowEngline implements Engline{
@Override
public void start() {
// TODO Auto-generated method stub
System.out.println("启动慢");
}
}
package cn.fllday.factory.abstracts;
public interface Seat {
void message();
}
class LuxurySeat implements Seat{
@Override
public void message() {
// TODO Auto-generated method stub
System.out.println("真皮");
}
}
class LowSeat implements Seat{
@Override
public void message() {
// TODO Auto-generated method stub
System.out.println("假皮");
}
}
package cn.fllday.factory.abstracts;
public interface Tyre {
void use();
}
class LuxuryTyre implements Tyre{
@Override
public void use() {
// TODO Auto-generated method stub
System.out.println("耐用");
}
}
class LowTyre implements Tyre{
@Override
public void use() {
// TODO Auto-generated method stub
System.out.println("不耐用");
}
}
创建豪车工厂的实现类:
package cn.fllday.factory.abstracts;
public class LuxuryCarFactory implements CarFactory{
@Override
public Engline createEngline() {
// TODO Auto-generated method stub
return new LuxuryEngline();
}
@Override
public Seat createSeat() {
// TODO Auto-generated method stub
return new LuxurySeat();
}
@Override
public Tyre createTyre() {
// TODO Auto-generated method stub
return new LuxuryTyre();
}
}
通过工厂制造的车的引擎,轮胎,座椅
package cn.fllday.factory.abstracts;
public class Client01 {
public static void main(String[] args) {
CarFactory car = new LuxuryCarFactory();
Engline e = car.createEngline();
e.start();
car.createSeat().message();
car.createTyre().use();
}
}
应用场景:
- JDK中的Calendar 的getInstance方法
- JDBC的connection 对象的获取
- Hibernate中的sessionFactory的session创建
- Spring 的 IOC容器创建管理bean对象
- 反射中Class对象的newInstance