工厂模式的主要功能是帮我们把对象的实例化部分抽取出来,优化了系统架构增强了系统的可扩展性。
1.简单工厂:通过接受不同的参数,返回不同的对象实例(不修改代码是不能扩展的)
public interface Phone {
void call();
}
public class ApplePhone implements Phone {
@Override
public void call() {
System.out.println("苹果手机打电话");
}
}
public class OppoPhone implements Phone {
@Override
public void call() {
System.out.println("Oppo手机打电话");
}
}
public class PhoneFactory {
public Phone getPhone(String name) {
if("苹果".equals(name)) {
return new ApplePhone();
}else if("OPPO".equals(name)){
return new OppoPhone();
}else {
System.out.println("手机工厂暂时不支持制造这种手机");
return null;
}
}
}
public class MainTest {
public static void main(String[] args) {
PhoneFactory phoneFactory=new PhoneFactory();
Phone phone=phoneFactory.getPhone("苹果");
if(phone!=null) {
phone.call();
}
phone=phoneFactory.getPhone("OPPO");
if(phone!=null) {
phone.call();
}
phone=phoneFactory.getPhone("无名");
if(phone!=null) {
phone.call();
}
}
}
苹果手机打电话
Oppo手机打电话
手机工厂暂时不支持制造这种手机
这种情况好比一个大工厂(PhoneFactory)能够实现各种各样的手机(Phone)(所有手机产品种类已经确定),所以调用者可以清楚的知道该如何获取指定产品,从而使用产品功(call)。但是不修改代码是无法获取新的扩展产品的。
2.工厂方法:针对每一种产品,提供一个具体的工厂。通过不同的工厂实例来获取不同的产品(对象)
public interface PhoneFactory {
Phone getPhone();
}
public class ApplePhoneFactory implements PhoneFactory{
@Override
public Phone getPhone() {
return new ApplePhone();
}
}
public class OppoPhoneFactory implements PhoneFactory{
@Override
public Phone getPhone() {
return new OppoPhone();
}
}
public class MainTest {
public static void main(String[] args) {
PhoneFactory phoneFactory=new ApplePhoneFactory();
phoneFactory.getPhone().call();
phoneFactory=new OppoPhoneFactory();
phoneFactory.getPhone().call();
}
}
这种情况,只是需要一种产品,不想知道也不需要知道是哪个工厂生产的,最终选择具体的产品在生产者一方。好比要买一部手机,不管是哪个厂商的,最终去哪个工厂店里去买去拿到手机,决定权在自己手里。由于PhoneFactory是空壳工厂(interface),生产的产品依赖具体的工厂,所以有新的产品出现的时候,就必须有新的工厂实现(成对出现),这样增加了可扩展性,而不必去改动代码。
3.抽象工厂:是应对产品族概念的。比如说,每个汽车公司可能要同时生产轿车,货车,客车,那么每一个工厂都要有创建轿车,货车和客车的方法。此种模式同2差不多。只不过2是一个工厂只能生产一种产品,3是一个工厂能生产多种产品,然后每种产品又具有不同的功能。所以增加新的产品线(例如新建一个能生产不同种类的轿车、货车、客车的工厂)很容易,此种方法也是成对出现(新增的工厂能生产新的产品族),但是却无法新增新的产品,因为新的产品打乱了产品线,这样导致所有工厂都得重写代码才能生产此种新产品。