工厂模式分类
简单工厂模式
简单工厂模式是属于创建型模式,又叫做静态工厂方法模式
实例化对象的时候不再使用 new,而是根据用户的条件来实例化相关的类。对于客户端来说,去除了具体的类的依赖。只需要给出具体实例的描述给工厂,工厂就会自动返回具体的实例对象。
代码实现:
定义一个接口,表示时速这一性质
public interface Run {
public void run();
}
定义三个类具体实现时速这一接口
public class Car implements Run{
@Override
public void run() {
System.out.println("选的是汽车,时速120");
}
}
public class Bike implements Run{
@Override
public void run() {
System.out.println("选的是自行车,时速20");
}
}
public class Train implements Run {
@Override
public void run() {
System.out.println("选的是火车,时速200");
}
}
定义一个工厂用于创建实例:
public class SimpleFactory {
//简单工厂,根据需求创建对象
public static Run create(int speed){
Run run = null;
if(speed > 120){
run = new Train();
}else if(speed > 20 && speed <= 120){
run = new Car();
}else{
run = new Bike();
}
return run;
}
}
客户端代码:
public class Customer {
public static void main(String[] args) {
System.out.println("当我想要享受时速200的感觉");
int speed;
speed = 200;
Run choose = SimpleFactory.create(speed);
choose.run();
System.out.println("当我想要享受时速20的感觉");
speed = 20;
Run choose1 = SimpleFactory.create(speed);
choose1.run();
System.out.println("当我想要享受时速100的感觉");
speed = 100;
Run choose2 = SimpleFactory.create(speed);
choose2.run();
}
}
分析:我们无需提供具体的子类类名,只需要提供条件即可得到相应的实例对象。这样的话,当子类的类名更换或者增加子类时我们都无需修改客户端代码,只需要在简单工厂类上增加一个分支判断代码即可。
不过这种方式仍然存在弊端,在实例对象要实现很多不同的方法的话,我们还需要在工厂类中添加代码,从而导致这个简单工厂类代码臃肿、耦合性高。
工厂方法模式
工厂方法模式是对简单工厂模式进一步的解耦,因为在工厂方法模式中是一个子类对应一个工厂类,而这些工厂类都实现于一个抽象接口。这相当于是把原本会因为业务代码而庞大的简单工厂类,拆分成了一个个的工厂类,这样代码就不会都耦合在同一个类里了。
实现代码:
首先定义一个工厂接口:
public interface Factory {
public Run create();
}
同样的定义一个接口,表示时速这一性质
public interface Run {
public void run();
}
同简单工厂模式一样实现时速这接口的具体实现:
public class Bike implements Run {
@Override
public void run() {
System.out.println("时速20");
}
}
public class Train implements Run {
@Override
public void run() {
System.out.println("时速200");
}
}
public class Car implements Run{
@Override
public void run() {
System.out.println("时速120");
}
}
定义三个实体的工厂
public class BikeFactory implements Factory {
@Override
public Run create() {
System.out.println("选择的是bike");
return new Bike();
}
}
public class CarFactory implements Factory{
@Override
public Run create() {
System.out.println("选择的是car");
return new Car();
}
}
public class TrainFactory implements Factory {
@Override
public Run create() {
System.out.println("选择的是train");
return new Train();
}
}
客户端代码:
public class Customer {
public static void main(String[] args) throws Exception{
// 使用反射机制实例化工厂对象
Factory bikeFactory = (Factory)Class.forName("com.ctb.factorymethod.BikeFactory").newInstance();
Factory carFactory = (Factory)Class.forName("com.ctb.factorymethod.CarFactory").newInstance();
Factory trainFactory = (Factory)Class.forName("com.ctb.factorymethod.TrainFactory").newInstance();
// 通过工厂对象创建相应的实例对象
Run bike = bikeFactory.create();
Run car = carFactory.create();
Run train = trainFactory.create();
bike.run();
car.run();
train.run();
}
}
分析:调用者想创建一个对象,只要知道其名称就可以了。该模式扩展性高,如果想增加一个产品,只要扩展一个工厂类就可以。封装了产品的具体实现,调用者只关心产品的接口。但是每次增加一个产品时,都需要增加一个具体类和对象实现工厂,使得系统中类的个数成倍增加,在一定程度上增加了系统的复杂度,同时也增加了系统具体类的依赖
抽象工厂模式
基于上面的案例,不再只是选择出行工具,而是要加上选择的食物类型时,就好比我们去旅游,会给我们一个套餐:出行工具+食物类型,这样一个套餐统称为一个族,通过下面的新的方式进行实现:
实现代码:
首先定义一个抽象工厂类(套餐样板),抽象工厂类包括食物和交通工具:
public abstract class AbstractFactory {
abstract Food createdFood();
abstract Tool createdTool();
}
定义一个食物的抽象类:
public abstract class Food {
abstract void printName();
}
定义一个交通工具的抽象类:
public abstract class Tool {
abstract void run();
}
具体实现食物抽象类:
public class Chicken extends Food {
@Override
void printName() {
System.out.println("烤鸡");
}
}
public class Steak extends Food {
@Override
void printName() {
System.out.println("牛扒");
}
}
public class Vegetables extends Food{
@Override
void printName() {
System.out.println("蔬菜");
}
}
具体实现交通工具的类:
public class Bike extends Tool {
@Override
void run() {
System.out.println("时速20");
}
}
public class Car extends Tool {
@Override
void run() {
System.out.println("时速120");
}
}
public class Train extends Tool {
@Override
void run() {
System.out.println("时速200");
}
}
这时就可以定义一个族了,就是这个案例中的套餐
首先定义一个最贵的:
public class Expensive extends AbstractFactory {
@Override
Food createdFood() {
return new Steak();
}
@Override
Tool createdTool() {
return new Train();
}
}
再定义一个最便宜的:
public class Cheapest extends AbstractFactory {
@Override
Food createdFood() {
return new Vegetables();
}
@Override
Tool createdTool() {
return new Bike();
}
}
然后就是顾客的选择:
public class Customer {
public static void main(String[] args) {
//豪华大餐
AbstractFactory abstractFactory = new Expensive();
Tool tool = abstractFactory.createdTool();
Food food = abstractFactory.createdFood();
tool.run();
food.printName();
//穷游
AbstractFactory abstractFactory1 = new Cheapest();
Tool tool1 = abstractFactory.createdTool();
Food food1 = abstractFactory.createdFood();
tool1.run();
food1.printName();
}
}
同样的,你们也可以参照这个代码,创建一个大家都合适的套餐,然后在顾客 调用的时候只需要改变实例化的套餐模板就可以了
分析:工厂模式符合OCP原则,也就是开闭原则,在我们增加一类产品的时候,同时在增加一个工厂就可以解决这个问题,不需要我再来实现,具有高内聚,低耦合的特点,只需要提供product Interface和concrete factory就可以产生自己需要的对象和方法。
本文的代码:https://pan.baidu.com/s/1Y3faEUTzPZ5M6bOznu56Ng
提取码:n2no