一、工厂模式
简单来说,工厂模式就是调用工厂方法创建实例化对象,避免直接new一个对象,从而降低代码的耦合度;使用者也不需要了解对象的具体创建过程,具有良好的封装性; 同时对扩展开放对修改封闭,即开闭原则。
定义接口:手机
public interface Phone {
String brand();
}
定义实现类:Iphone类和HuaWei类实现手机接口
public class Iphone implements Phone {
@Override
public String brand() {
return "this is a Apple phone";
}
}
public class HuaWei implements Phone {
@Override
public String brand() {
return "this is a HuaWei phone";
}
}
定义工厂类:工厂类有一个方法createPhone(),用来根据不同的参数实例化不同的品牌的手机类并返回。
public class Factory {
public Phone createPhone(String phoneName) {
if("HuaWei".equals(phoneName)) {
return new HuaWei();
} else if ("Apple".equals(phoneName)) {
return new Iphone();
} else {
return null;
}
}
}
使用工厂模式:
import org.apache.log4j.PropertyConfigurator;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
// 上面的导包为了打印日志,与该文核心内容无关
public class UseFactoryDemo {
private final static Logger logger = LoggerFactory.getLogger(UseFactoryDemo.class);
public static void main(String[] args) {
PropertyConfigurator.configure("log4j.properties"); //日志配置
Factory factory = new Factory();
Phone huaWei = factory.createPhone("HuaWei");
Phone iphone = factory.createPhone("Apple");
logger.info(huaWei.brand()); //打印品牌信息到日志中
logger.info(iphone.brand());
}
}
二、抽象工厂模式
抽象工厂模式就是在工厂模式上添加一个创建不同工厂的抽象接口(抽象类或接口实现),可称为超级工厂。比如说手机工厂和笔记本工厂进一步抽象到既可以生产手机又可以生产笔记本电脑的电子厂; 又比如说一款应用要在两种操作系统上运行,应该怎么设计?是编写两套程序应用在两种系统上?这样实在是太浪费资源了,我们可以通过抽象工厂设计模式屏蔽掉操作系统对应用的影响。软件功能、逻辑、UI都是一样的,唯一不同的调用不同的工厂方法,由不同的产品类去处理与操作系统交互的信息,这就是抽象工厂的优势。
---------------------------------------------------------------------------------------------------------------------
定义电脑产品族:有相同的上网功能
public interface Computer {
String internet();
}
具体品牌的电脑:苹果电脑和华为电脑:
public class ComputerApple implements Computer {
@Override
public String internet() {
return "surf the internet by apple computer";
}
}
public class ComputerHuaWei implements Computer {
@Override
public String internet() {
return "surf the internet by huawei computer";
}
}
---------------------------------------------------------------------------------------------------------------------
定义手机产品族:有相同的打电话功能
public interface Phone {
String call();
}
具体品牌的手机:苹果手机和华为手机:
public class PhoneApple implements Phone {
@Override
public String call() {
return "call to anyone by Apple phone";
}
}
public class PhoneHuaWei implements Phone {
@Override
public String call() {
return "call to anyone by HuaWei phone";
}
}
---------------------------------------------------------------------------------------------------------------------
定义抽象工厂: 包括手机工厂和电脑工厂
public interface AbstractFactory {
public abstract Phone createPhone(String brand);
public abstract Computer createComputer(String brand);
}
手机工厂:
public class PhoneFactory implements AbstractFactory {
@Override
public Phone createPhone(String brand) {
if ("Apple".equals(brand)) {
return new Iphone();
} else if ("HuaWei".equals(brand)) {
return new HuaWei();
} else {
return null;
}
}
@Override
public Computer createComputer(String brand) {
return null;
}
}
电脑工厂:
public class ComputerFactory implements AbstractFactory {
@Override
public Phone createPhone(String brand) {
return null;
}
@Override
public Computer createComputer(String brand) {
if ("Apple".equals(brand)){
return new ComputerApple();
} else if ("HuaWei".equals(brand)){
return new ComputerHuaWei();
} else {
return null;
}
}
}
使用 FactoryProducer 来获取 AbstractFactory,通过传递类型信息来获取实体类的对象。
public class FactoryProducer {
public static AbstractFactory getFactory(String choice) {
if ("phone".equalsIgnoreCase(choice)) {
return new PhoneFactory();
} else if ("computer".equalsIgnoreCase(choice)) {
return new ComputerFactory();
} else {
return null;
}
}
}
---------------------------------------------------------------------------------------------------------------------
使用抽象工厂:
public class UseAbstractFactoryDemo {
public static void main(String[] args) {
AbstractFactory phoneFactory = FactoryProducer.getFactory("phone");
Phone phoneHuaWei = phoneFactory.createPhone("HuaWei");
Phone phoneApple = phoneFactory.createPhone("Apple");
System.out.println(phoneHuaWei.call());
System.out.println(phoneApple.call());
AbstractFactory computerFactory = FactoryProducer.getFactory("computer");
Computer computerHuaWei = computerFactory.createComputer("HuaWei");
Computer computerApple = computerFactory.createComputer("Apple");
System.out.println(computerHuaWei.internet());
System.out.println(computerApple.internet());
}
}
输出
call to anyone by HuaWei phone
call to anyone by apple phone
surf the internet by huawei computer
surf the internet by apple computer
---------------------------------------------------------------------------------------------------------------------
总结下抽象工厂模式的特点,抽象工厂是所有形式的工厂模式中最为抽象和最具一般性的一种形态,其优缺点大致如下:
1、隔离了具体类的生成,使得客户并不需要知道什么被创建,具有良好的封装性。
2、横向扩展容易。同个产品族如果需要增加多个 产品,只需要增加新的工厂类和产品类即可。
3、纵向扩展困难。如果增加新的产品组,抽象工厂类也要添加创建该产品组的对应方法,这样一来所有的具体工厂类都要做修改了,严重违背了开闭原则。