1简单工厂模式
简单工厂模式是属于创建型模式,是工厂模式的一种,简单工厂模式是由一个工厂对象决定创建出哪一种产品类的实例。简单工厂模式是工厂模式家族重最简单实用的模式
简单工厂模式:定义了一个创建对象的类,由这个类来封装实例化对象的行为
在软件开发重,当我们会用到大量的创建某种,某类或者某批对象时,就会使用到工厂模式、
简单工厂模式包含三个角色
1.**factory(工厂角色)**:就是工厂类,他是简单工厂模式的核心;这个类是直接被外界调用的,他负责创建所需的产品的对象;返回值的类型是抽象产品类型Product
2.**Product(抽象产品角色)**:他是工厂类创建的所有对象的父类,封装了一类产品都会拥有的方法,后期创建的所有的产品都会是它的子类
3.**ConreteProduct(具体产品角色)**:它是简单工厂模式的创建目标,所有被创建的对象都充当这个角色的某个具体类的实例
下面是代码案例
**关系类图 **
抽象产品角色
package com.designpatten.factory.simplefactory;
public interface Car {
void run();
}
具体的产品类
package com.designpatten.factory.simplefactory;
public class BenChi implements Car {
@Override
public void run() {
System.out.println("奔驰车再跑");
}
}
package com.designpatten.factory.simplefactory;
public class BaoMa implements Car {
@Override
public void run() {
System.out.println("宝马车再跑");
}
}
工厂角色
package com.designpatten.factory.simplefactory;
public class CarFactory {
public Car createCar(String brand){
if ("BaoMa".equals(brand)){
System.out.println("创建了一辆宝马车");
return new BaoMa();
}else if ("BenChi".equals(brand)){
System.out.println("创建了一辆奔驰车");
return new BenChi();
}else {
System.out.println("没有这种类型的车");
return null;
}
}
}
客户端调用
package com.designpatten.factory.simplefactory;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Scanner;
public class CarShopping {
CarFactory carFactory;
Scanner cin = new Scanner(System.in);
public CarShopping(CarFactory carFactory) {
setCarFactory(carFactory);
}
public void setCarFactory(CarFactory carFactory){
String brand = "";
this.carFactory = carFactory;
while (true){
brand = getType();
Car car = carFactory.createCar(brand);
if (car != null){
car.run();
}else{
break;
}
}
}
private String getType() {
System.out.println("请输入汽车的牌子");
return cin.nextLine();
}
public static void main(String[] args) {
CarShopping shopping = new CarShopping(new CarFactory());
}
}
运行结果
可以发现,用这种方式创建汽车的实例对象的时候只需要输入想要的类型就可以得到想到的对象,但是如果想要给工厂方法添加一个新对象的时候就需要改动工厂类中的代码,这个就违反了开闭原则
简单工厂模式的优点:
1.它实现了对象创建和使用的分离
2.客户端无需知道需要创建的具体的产品类的类型,可以在一定程度上减少使用者的记忆
3.可以通过引入配置文件的方式,可以在不修改任何客户端代码的情况下更换和增加新的类
简单工厂模式的缺点:
1.所有的创建的操作都集中在了工厂类,一旦工厂类凉了,整个系统都凉了
2.扩展比较不方便,如果想要添加新的类,就必须要修改工厂的逻辑
2.工厂方法模式
有些时候一些比较简单的创建是可以用简单工厂模式的,但是考虑到项目的规模,以及软件的可维护性,可扩展性并不是特别好,这个时候就可以考虑使用工厂方法模式
工厂方法模式包含4个角色
1.抽象产品Product:生产的所有的产品对象的父类
2.具体产品ConcreteProduct:生产的产品对象
3.抽象工厂Factory:所有创建的工厂类都必须实现这个接口
4.具体工厂ConcreteFactory:抽象工厂类的子类,实现了在抽象工厂中声明的工厂方法
产品抽象角色
package com.designpatten.factory.factorymethod.improve;
public interface Logger {
void info();
}
具体对象
package com.designpatten.factory.factorymethod.improve;
public class FileLogger implements Logger {
@Override
public void info() {
System.out.println("文件的日志记录");
}
}
package com.designpatten.factory.factorymethod.improve;
public class DatabaseLogger implements Logger {
@Override
public void info() {
System.out.println("数据库的日志记录");
}
}
抽象的工厂
package com.designpatten.factory.factorymethod.improve;
/**
* 生产日志的工厂的接口
*/
public interface LoggerFactory {
Logger createLogger();
}
具体的工厂
package com.designpatten.factory.factorymethod.improve;
public class DatabaseLoggerFactory implements LoggerFactory {
@Override
public Logger createLogger() {
return new DatabaseLogger();
}
}
package com.designpatten.factory.factorymethod.improve;
public class FileLoggerFactory implements LoggerFactory {
@Override
public Logger createLogger() {
return new FileLogger();
}
}
客户端
package com.designpatten.factory.factorymethod.improve;
public class Client {
public static void main(String[] args) {
LoggerFactory factory = new DatabaseLoggerFactory();
Logger logger = factory.createLogger()
logger.info();
}
}
类图
使用这种方式创建对象,当需要新增新的日志类的时候,只需要新增一个新的工厂类,无需再工厂类的代码中修改逻辑
工厂方法模式的优点
1.对于用户来说隐藏了实例化这一细节,用户只需要关心所需产品对应的工厂即可
2.这种写法扩展性比较好当想要新增的时候无需修改工厂类中代码,只需要新增一个工厂类就行了,满足了开闭原则
工厂方法模式的缺点
1.每次新增产品的时候都需要添加一个对应的工厂类,这样会使类的数量成对增加,增加了系统的复杂度,而且还会给系统带来额外的开销
2.增加了系统的抽象性和理解难度
3.抽象工厂模式
定义了一个interface用于创建相关或有依赖关系的对象族,而无需知名具体的类
抽象工厂模式可以将简单工厂模式和工厂方法模式进行整合
从设计层面看,抽象工厂模式就是对简单工厂模式的改进(或者称为进一步的抽象)
将工厂抽象称两层,第一层抽象工厂和第二层具体实现的工厂子类,程序员可以根据创建对象类型使用对应的工厂子类,这样将单个的简单工厂类变成了工厂簇,更利于代码的维护和扩展
抽象工厂的结构
1.AbstractFactory(抽象工厂):它声明了一组用于创建一族产品的方法,每一个方法对应一种产品
2.ConcreteFactory(具体工厂):它实现了再抽象工厂中声明的创建产品的方法,生成一组具体产品
3.AbstractProduct(抽象产品):它为每种产品声明接口,在抽象产品中声明了产品所具有的业务方法
4.ConcreteProduct(具体产品):它是工厂返回的具体的产品对象
产品的抽象类
package com.designpatten.factory.absfactory;
public interface Button {
void display();
}
package com.designpatten.factory.absfactory;
public interface ComboBox {
void display();
}
package com.designpatten.factory.absfactory;
public interface TextField {
void display();
}
具体的实现类
package com.designpatten.factory.absfactory;
public class SpringButton implements Button {
@Override
public void display() {
System.out.println("我是春天的按钮");
}
}
package com.designpatten.factory.absfactory;
public class SummerButton implements Button {
@Override
public void display() {
System.out.println("我是夏天按钮");
}
}
package com.designpatten.factory.absfactory;
public class SpringTextField implements TextField {
@Override
public void display() {
System.out.println("我是春天的文本");
}
}
package com.designpatten.factory.absfactory;
public class SummerTextField implements TextField {
@Override
public void display() {
System.out.println("我是夏天的文本");
}
}
package com.designpatten.factory.absfactory;
public class SpringComboBox implements ComboBox {
@Override
public void display() {
System.out.println("我是春天的组合框");
}
}
package com.designpatten.factory.absfactory;
public class SummerComboBox implements ComboBox {
@Override
public void display() {
System.out.println("我是夏天的组合框");
}
}
抽象的工厂类
package com.designpatten.factory.absfactory;
public interface SkinFactory {
Button createButton();
TextField createTextField();
ComboBox createComboBox();
}
具体的工厂类
package com.designpatten.factory.absfactory;
public class SpringSkinFactory implements SkinFactory {
@Override
public Button createButton() {
return new SpringButton();
}
@Override
public TextField createTextField() {
return new SpringTextField();
}
@Override
public ComboBox createComboBox() {
return new SpringComboBox();
}
}
package com.designpatten.factory.absfactory;
public class SummerSkinFactory implements SkinFactory {
@Override
public Button createButton() {
return new SummerButton();
}
@Override
public TextField createTextField() {
return new SummerTextField();
}
@Override
public ComboBox createComboBox() {
return new SummerComboBox();
}
}
客户端
package com.designpatten.factory.absfactory;
public class Client {
public static void main(String[] args) {
SkinFactory skinFactory = new SpringSkinFactory();
Button button = skinFactory.createButton();
TextField textField = skinFactory.createTextField();
ComboBox comboBox = skinFactory.createComboBox();
button.display();
textField.display();
comboBox.display();
}
}
运行结果
抽象工厂模式的优点:
1.对于增加新的产品族很方便,无需修改已有的系统,符合开闭原则
2.当一个产品族中的多个对象被设计成一起工作时,他能够保证客户端终只使用同一个产品族中的对象
抽象工厂模式的缺点
增加新的产品等级结构麻烦,需要对原有系统进行较大的修改,违背了开闭原则