作用:实现了创建者和调用者的分离
核心本质:
- 实例化对象不使用new,用工厂方法代替
- 将选择实现类,创建对象统一管理和控制。从而将调用者跟我们的实现类解耦。
先说说oop的几个原则
- 开闭原则:一个软件的实体应当对扩展开放,对修改关闭
- 依赖倒转原则:要针对接口编程,不要针对实现编程
- 迪米特原则:只与你直接的朋友通信,而避免和陌生人接触
工厂模式的实现要尽量遵循oop原则
1、简单工厂模式
用来生产同一等级结构中的任意产品,对于增加的新的产品,需要修改原有代码。
下面直接写代码,用手机来举个例子
首先是一个手机接口
public interface Phone {
void name();
}
然后是手机品牌的实现类,都要实现手机接口
public class XiaoMi implements Phone {
@Override
public void name() {
System.out.println("小米手机");
}
}
public class HuaWei implements Phone {
@Override
public void name() {
System.out.println("华为手机");
}
}
然后写手机工厂类
public class PhoneFactory {
public static Phone getPhone(String phone){
if(phone.equals("xiaomi")){
return new XiaoMi();
}else if(phone.equals("huawei")){
return new HuaWei();
}else {
return null;
}
}
}
这样消费者类买手机时不用new手机品牌类了,直接调用手机工厂就行
public class Consumer {
public static void main(String[] args) {
Phone phone1 = PhoneFactory.getPhone("xiaomi");
Phone phone2 = PhoneFactory.getPhone("huawei");
phone1.name();
phone2.name();
}
}
但是当我们想要再增加一个手机品牌的时候,比如增加一个苹果手机,写它的类
public class Iphone implements Phone{
@Override
public void name() {
System.out.println("苹果手机");
}
}
这个时候手机工厂就必须修改代码
public class PhoneFactory {
public static Phone getPhone(String phone){
if(phone.equals("xiaomi")){
return new XiaoMi();
}else if(phone.equals("huawei")){
return new HuaWei();
}else if(phone.equals("iphone")){
return new Iphone();
}else {
return null;
}
}
}
这就不符合oop的开闭原则了,所以为了优化这个问题,我们引入了工厂方法模式。
2、工厂方法模式
用来生产统一登记结构中的固定产品,支持增加任意产品。
直接写代码,同样是手机接口,实现各品牌手机类
public interface Phone {
void name();
}
public class XiaoMi implements Phone {
@Override
public void name() {
System.out.println("小米手机");
}
}
public class HuaWei implements Phone {
@Override
public void name() {
System.out.println("华为手机");
}
}
然后再写一个手机工厂接口
public interface PhoneFactory {
Phone getPhone();
}
不同手机品牌有不同的手机工厂
public class MiPhoneFactory implements PhoneFactory{
@Override
public Phone getPhone() {
return new XiaoMi();
}
}
public class HuaWeiPhoneFactory implements PhoneFactory {
@Override
public Phone getPhone() {
return new HuaWei();
}
}
消费者买手机时直接调用相应的手机工厂就行
public class Consumer {
public static void main(String[] args) {
MiPhoneFactory miPhoneFactory = new MiPhoneFactory();
HuaWeiPhoneFactory huaWeiPhoneFactory = new HuaWeiPhoneFactory();
Phone phone1 = miPhoneFactory.getPhone();
Phone phone2 = huaWeiPhoneFactory.getPhone();
phone1.name();
phone2.name();
}
}
这样想要再扩展一个苹果手机,只需要再写一个苹果手机类和苹果手机工厂就行,不用再原代码上进行修改
public class Iphone implements Phone {
@Override
public void name() {
System.out.println("苹果手机");
}
}
public class IphonePhoneFactory implements PhoneFactory {
@Override
public Phone getPhone() {
return new Iphone();
}
}
根据设计原则,是工厂方法模式更好。但是根据例子可以看出,从结构复杂度,代码复杂度,编程复杂度和管理上的复杂度来看,都是简单工厂模式更有优势。
所以在实际的业务中,简单工厂模式应用更加广泛。
3、抽象工厂模式
围绕一个超级工厂创建其他工厂,该超级工厂又称为其他工厂的工厂。
写代码,这次用不同品牌举例子,不同品牌下有固定的产品
首先写不同品牌下相同的固定的产品的接口,手机接口和电视接口
public interface Phone {
void start();
void shutdown();
void call();
}
public interface Television {
void start();
void shutdown();
void watch();
}
然后写小米与华为两个品牌的实现类
public class MiPhone implements Phone {
@Override
public void start() {
System.out.println("小米手机开机");
}
@Override
public void shutdown() {
System.out.println("小米手机关机");
}
@Override
public void call() {
System.out.println("小米手机打电话");
}
}
public class MiTV implements Television{
@Override
public void start() {
System.out.println("小米电视开机");
}
@Override
public void shutdown() {
System.out.println("小米电视关机");
}
@Override
public void watch() {
System.out.println("小米电视收看节目");
}
}
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("华为手机打电话");
}
}
public class HuaWeiTV implements Television {
@Override
public void start() {
System.out.println("华为智慧屏开机");
}
@Override
public void shutdown() {
System.out.println("华为智慧屏关机");
}
@Override
public void watch() {
System.out.println("华为智慧屏增智慧");
}
}
然后是工厂接口,这个工厂为“生产工厂的工厂”
//抽象产品工厂
public interface Factory {
//生产手机
Phone phoneProduct();
//生产电视
Television tvProduct();
}
小米工厂和华为工厂的类
public class XiaoMiFactory implements Factory {
@Override
public Phone phoneProduct() {
return new MiPhone();
}
@Override
public Television tvProduct() {
return new MiTV();
}
}
public class HuaWeiFactory implements Factory {
@Override
public Phone phoneProduct() {
return new HuaWeiPhone();
}
@Override
public Television tvProduct() {
return new HuaWeiTV();
}
}
写个客户端测试
public class Client {
public static void main(String[] args) {
System.out.println("============小米==============");
XiaoMiFactory xiaoMiFactory = new XiaoMiFactory();
Phone phone = xiaoMiFactory.phoneProduct();
phone.start();
phone.call();
phone.shutdown();
Television television = xiaoMiFactory.tvProduct();
television.start();
television.watch();
television.shutdown();
System.out.println("============华为==============");
HuaWeiFactory huaWeiFactory = new HuaWeiFactory();
Phone phone1 = huaWeiFactory.phoneProduct();
phone1.start();
phone1.call();
phone1.shutdown();
Television television1 = huaWeiFactory.tvProduct();
television1.start();
television1.watch();
television1.shutdown();
}
}