工厂模式
工厂模式顾名思义就是生产实例的工厂,使用工厂模式不会在程序中使用new关键字创建实例。而是将创建对象的细节隐藏,对外提供统一的方法,外部通过该方法获取实例。以此降低调用者与程序之间的耦合性,更加灵活
工厂模式可以分为三类
- 简单工厂模式
- 工厂方法模式
- 抽象工厂模式
简单工厂模式
定义一个接口,将创建对象和其本身的业务分离解耦,如下示例:
public interface Pet {
void shout();
}
public class Cat implements Pet{
public void shout() {
System.out.println("猫叫");
}
}
public class Dog implements Pet{
public void shout() {
System.out.println("狗叫");
}
}
// 宠物工厂
public class PetFactory {
// 方式一
public static Pet getPet(String pet) {
if (pet.equals("小猫")) {
return new Cat();
} else if (pet.equals("小狗")) {
return new Dog();
} else {
return null;
}
}
// 方式二
public static Pet getCat(){
return new Cat();
}
public static Pet getDog(){
return new Dog();
}
}
// 用户类
public class Customer {
public static void main(String[] args) {
Pet pet = PetFactory.getPet("小猫");
pet.shout();
}
}
// 输出 : 猫叫
如上述代码所示,创建对象只需要直接调用PetFactory工厂的创建方法即可,根据用户需求来创建指定对象,执行对应方法
工厂方法模式
工厂方法模式相对于简单工厂,提高了拓展性,可以在不影响原有类的情况下实现横向扩展其他类,但是代码量加大,可能会产生更多的代码冗余。
我们针对每一个类都为其设置单独的工厂,即每个工厂只生产一种类型,如果在需要新增其他类型那么只需要创建其工厂提供获取实例方法即可
public interface Pet {
void shout();
}
public class Cat implements Pet {
public void shout() {
System.out.println("猫叫");
}
}
public class CatFactory {
public static Pet getCat(){
return new Cat();
}
}
public class Customer {
public static void main(String[] args) {
Pet cat = CatFactory.getCat();
cat.shout();
}
}
使用工厂方法模式可以再不修改原有代码的基础上继续扩展,但是工作量较大
对比简单工厂和工厂方法模式:就代码和结构的复杂度,使用简单工厂模式更加简便,但是对于可拓展性则工厂方法模式更加优越
抽象工厂模式
抽象工厂用于常见一系列相关对象的家族,抽象的意思是,我们会定义一个工厂接口并且不做任何实现,只用来约束它的实现工厂生产产品的规范。
四大核心:抽象工厂、具体工厂、抽象产品、具体产品
以华为、小米生产手机和电视为例:
代码如下:
// 工厂接口
public interface ProductFactory {
RouterProduct getRouter(); // 生产路由器
PhoneProduct getPhone(); // 生产手机
}
// 手机、路由器接口
public interface PhoneProduct { void close();}
public interface RouterProduct {void start();}
// 工厂
public class HuaweiFactory implements ProductFactory{
public RouterProduct getRouter() {return new HuaweiRouter();}
public PhoneProduct getPhone() {
return new HuaweiPhone();
}
}
public class XiaoMiFactory implements ProductFactory{
public RouterProduct getRouter() {
return new XiaoMiRouter();
}
public PhoneProduct getPhone() {
return new XiaoMiPhone();
}
}
// 测试
public static void main(String[] args) {
// 拿到工厂对象
XiaoMiFactory miFactory = new XiaoMiFactory();
HuaweiFactory huaweiFactory = new HuaweiFactory();
// 小米工厂生产
PhoneProduct miFactoryPhone = miFactory.getPhone();
miFactoryPhone.close();
RouterProduct router = miFactory.getRouter();
router.start();
// 华为工厂生产
PhoneProduct phone = huaweiFactory.getPhone();
phone.close();
RouterProduct router1 = huaweiFactory.getRouter();
router1.start();
}
还有其他的产品接口实现类,华为手机、小米手机、华为路由器等等
同样的抽象工厂模式也可以进行扩展但是比较繁琐,需要再顶级工厂也就是工厂接口中去扩展,但是扩展之后其所有的实现类也都需要完成实现。如果是长期稳定状态下可以这样扩展,但是经常改动的话抽象工厂模式就显得非常鸡肋