工厂模式
一、普通写法
1、UML
1、代码案例
/**
* @Author: dashu
* @Description: 饺子
* @Date: 23:18
* @Version: 1.0
*/
public abstract class Dumplings {
private String stuffing;
/**
* 准备食材
*/
public abstract void ingredient();
/**
* 包饺子
*/
public void makeDumplings() {
System.out.println("包" + stuffing + "饺子");
}
/**
* 煮饺子
*/
public void boilDumplings() {
System.out.println("煮" + stuffing + "饺子");
}
/**
* 捞饺子
*/
public void fishingDumplings() {
System.out.println("捞" + stuffing + "饺子");
}
/**
* 饺子名
*
* @param stuffing
*/
public void setStuffing(String stuffing) {
this.stuffing = stuffing;
}
}
/**
* @Author: dashu
* @Description: 猪肉饺子
* @Date: 23:28
* @Version: 1.0
*/
public class PorkDumplings extends Dumplings{
/**
* 准备食材
*/
@Override
public void ingredient() {
System.out.println("准备猪肉和饺子皮...");
}
}
/**
* @Author: dashu
* @Description: 牛肉饺子
* @Date: 23:26
* @Version: 1.0
*/
public class BeefDumplings extends Dumplings{
/**
* 准备食材
*/
@Override
public void ingredient() {
System.out.println("准备牛肉和饺子皮...");
}
}
/**
* @Author: dashu
* @Description: 买饺子
* @Date: 23:30
* @Version: 1.0
*/
public class BuyDumplings {
public BuyDumplings(){
Dumplings dumplings = null;
String stuffing;
do {
stuffing = getStuffing();
if (stuffing.equals("猪肉")){
dumplings = new PorkDumplings();
dumplings.setStuffing(stuffing);
}else if (stuffing.equals("牛肉")){
dumplings = new BeefDumplings();
dumplings.setStuffing(stuffing);
}else{
System.out.println("没有你要买的饺子...");
break;
}
dumplings.ingredient();
dumplings.makeDumplings();
dumplings.boilDumplings();
dumplings.fishingDumplings();
}while (true);
}
/**
* 获取饺子馅
* @return
*/
private String getStuffing(){
try {
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(System.in));
System.out.println("请输入饺子馅:");
String s = bufferedReader.readLine();
return s;
}catch (IOException e){
e.printStackTrace();
return "";
}
}
}
/**
* @Author: dashu
* @Description: 测试
* @Date: 23:37
* @Version: 1.0
*/
public class Main {
public static void main(String[] args) {
new BuyDumplings();
}
}
2、结论
该写法优点就是比较好理解,容易操纵。
但是严重违反了设计模式的开闭原则(ocp),即对扩展开放,对修改关闭。
当我们给类中添加一个白菜饺子
时,需要修改到BuyDumplings
类中的方法BuyDumplings
public BuyDumplings(){
Dumplings dumplings = null;
String stuffing;
do {
stuffing = getStuffing();
if (stuffing.equals("猪肉")){
dumplings = new PorkDumplings();
dumplings.setStuffing(stuffing);
}else if (stuffing.equals("牛肉")){
dumplings = new BeefDumplings();
dumplings.setStuffing(stuffing);
}else{
System.out.println("没有你要买的饺子...");
break;
}
dumplings.ingredient();
dumplings.makeDumplings();
dumplings.boilDumplings();
dumplings.fishingDumplings();
}while (true);
}
二、简单工厂模式
1、UML
1、代码案例
/**
* @Author: dashu
* @Description: 饺子
* @Date: 23:18
* @Version: 1.0
*/
public abstract class Dumplings {
private String stuffing;
/**
* 准备食材
*/
public abstract void ingredient();
/**
* 包饺子
*/
public void makeDumplings() {
System.out.println("包" + stuffing + "饺子");
}
/**
* 煮饺子
*/
public void boilDumplings() {
System.out.println("煮" + stuffing + "饺子");
}
/**
* 捞饺子
*/
public void fishingDumplings() {
System.out.println("捞" + stuffing + "饺子");
}
/**
* 饺子名
*
* @param stuffing
*/
public void setStuffing(String stuffing) {
this.stuffing = stuffing;
}
}
/**
* @Author: dashu
* @Description: 牛肉饺子
* @Date: 23:26
* @Version: 1.0
*/
public class BeefDumplings extends Dumplings{
/**
* 准备食材
*/
@Override
public void ingredient() {
System.out.println("准备牛肉和饺子皮...");
}
}
/**
* @Author: dashu
* @Description: 猪肉饺子
* @Date: 23:28
* @Version: 1.0
*/
public class PorkDumplings extends Dumplings{
/**
* 准备食材
*/
@Override
public void ingredient() {
System.out.println("准备猪肉和饺子皮...");
}
}
/**
* @Author: dashu
* @Description: 简单工厂:创建饺子
* @Date: 23:41
* @Version: 1.0
*/
public class DumplingsSimplenessFactory {
public Dumplings createDumplings(String stuffing) {
Dumplings dumplings = null;
if (stuffing.equals("猪肉")) {
dumplings = new PorkDumplings();
dumplings.setStuffing(stuffing);
} else if (stuffing.equals("牛肉")) {
dumplings = new BeefDumplings();
dumplings.setStuffing(stuffing);
}
return dumplings;
}
}
/**
* @Author: dashu
* @Description: 买饺子
* @Date: 23:30
* @Version: 1.0
*/
public class BuyDumplingsBySimplenessFactory {
private DumplingsSimplenessFactory dumplingsSimplenessFactory;
private Dumplings dumplings;
public BuyDumplingsBySimplenessFactory(DumplingsSimplenessFactory dumplingsSimplenessFactory){
this.dumplingsSimplenessFactory = dumplingsSimplenessFactory;
buyDumplings();
}
public void buyDumplings(){
String stuffing;
do {
stuffing = getStuffing();
dumplings = dumplingsSimplenessFactory.createDumplings(stuffing);
if (dumplings == null){
System.out.println("没有你要买的饺子...");
break;
}
dumplings.ingredient();
dumplings.makeDumplings();
dumplings.boilDumplings();
dumplings.fishingDumplings();
}while (true);
}
/**
* 获取饺子馅
* @return
*/
private String getStuffing(){
try {
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(System.in));
System.out.println("请输入饺子馅:");
String s = bufferedReader.readLine();
return s;
}catch (IOException e){
e.printStackTrace();
return "";
}
}
}
/**
* @Author: dashu
* @Description: 测试
* @Date: 23:57
* @Version: 1.0
*/
public class Main {
public static void main(String[] args) {
new BuyDumplingsBySimplenessFactory(new DumplingsSimplenessFactory());
}
}
2、结论
简单工厂模式是由一个工厂对象决定创建出哪一种产品的实例。
简单工厂模式:定义一个创建对象的类,由这个类来封装实例化对象
的行为
当我们给类中添加一个白菜饺子
时,只需要修改工厂类DumplingsSimplenessFactory
即可,不会影响到使用对象的类
三、静态工厂模式
1、UML
1、代码案例
/**
* @Author: dashu
* @Description: 饺子
* @Date: 23:18
* @Version: 1.0
*/
public abstract class Dumplings {
private String stuffing;
/**
* 准备食材
*/
public abstract void ingredient();
/**
* 包饺子
*/
public void makeDumplings() {
System.out.println("包" + stuffing + "饺子");
}
/**
* 煮饺子
*/
public void boilDumplings() {
System.out.println("煮" + stuffing + "饺子");
}
/**
* 捞饺子
*/
public void fishingDumplings() {
System.out.println("捞" + stuffing + "饺子");
}
/**
* 饺子名
*
* @param stuffing
*/
public void setStuffing(String stuffing) {
this.stuffing = stuffing;
}
}
/**
* @Author: dashu
* @Description: 牛肉饺子
* @Date: 23:26
* @Version: 1.0
*/
public class BeefDumplings extends Dumplings{
/**
* 准备食材
*/
@Override
public void ingredient() {
System.out.println("准备牛肉和饺子皮...");
}
}
/**
* @Author: dashu
* @Description: 猪肉饺子
* @Date: 23:28
* @Version: 1.0
*/
public class PorkDumplings extends Dumplings{
/**
* 准备食材
*/
@Override
public void ingredient() {
System.out.println("准备猪肉和饺子皮...");
}
}
/**
* @Author: dashu
* @Description: 静态工厂:创建饺子
* @Date: 23:41
* @Version: 1.0
*/
public class DumplingsStaticFactory {
public static Dumplings createDumplings(String stuffing) {
Dumplings dumplings = null;
if (stuffing.equals("猪肉")) {
dumplings = new PorkDumplings();
dumplings.setStuffing(stuffing);
} else if (stuffing.equals("牛肉")) {
dumplings = new BeefDumplings();
dumplings.setStuffing(stuffing);
}
return dumplings;
}
}
/**
* @Author: dashu
* @Description: 买饺子
* @Date: 23:30
* @Version: 1.0
*/
public class BuyDumplingsByStaticFactory {
private Dumplings dumplings;
public BuyDumplingsByStaticFactory() {
buyDumplings();
}
public void buyDumplings() {
String stuffing;
do {
stuffing = getStuffing();
dumplings = DumplingsStaticFactory.createDumplings(stuffing);
if (dumplings == null) {
System.out.println("没有你要买的饺子...");
break;
}
dumplings.ingredient();
dumplings.makeDumplings();
dumplings.boilDumplings();
dumplings.fishingDumplings();
} while (true);
}
/**
* 获取饺子馅
*
* @return
*/
private String getStuffing() {
try {
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(System.in));
System.out.println("请输入饺子馅:");
String s = bufferedReader.readLine();
return s;
} catch (IOException e) {
e.printStackTrace();
return "";
}
}
}
/**
* @Author: dashu
* @Description: 测试
* @Date: 23:57
* @Version: 1.0
*/
public class Main {
public static void main(String[] args) {
new BuyDumplingsByStaticFactory();
}
}
2、结论
简单工厂模式也叫静态工厂模式。只是工厂创建实例的方式直接由类名调用创建实例的静态方法
四、工厂方法模式
1、UML
1、代码案例
/**
* @Author: dashu
* @Description: 饺子
* @Date: 23:18
* @Version: 1.0
*/
public abstract class Dumplings {
private String stuffing;
/**
* 准备食材
*/
public abstract void ingredient();
/**
* 包饺子
*/
public void makeDumplings() {
System.out.println("包" + stuffing + "饺子");
}
/**
* 煮饺子
*/
public void boilDumplings() {
System.out.println("煮" + stuffing + "饺子");
}
/**
* 捞饺子
*/
public void fishingDumplings() {
System.out.println("捞" + stuffing + "饺子");
}
/**
* 饺子名
*
* @param stuffing
*/
public void setStuffing(String stuffing) {
this.stuffing = stuffing;
}
}
/**
* @Author: dashu
* @Description: 北方猪肉饺子
* @Date: 23:28
* @Version: 1.0
*/
public class BFPorkDumplings extends Dumplings {
/**
* 准备食材
*/
@Override
public void ingredient() {
System.out.println("北方饺子");
System.out.println("准备猪肉和饺子皮...");
}
}
/**
* @Author: dashu
* @Description: 北方牛肉饺子
* @Date: 23:26
* @Version: 1.0
*/
public class BFBeefDumplings extends Dumplings {
/**
* 准备食材
*/
@Override
public void ingredient() {
System.out.println("北方饺子");
System.out.println("准备牛肉和饺子皮...");
}
}
/**
* @Author: dashu
* @Description: 南方猪肉饺子
* @Date: 23:28
* @Version: 1.0
*/
public class NFPorkDumplings extends Dumplings {
/**
* 准备食材
*/
@Override
public void ingredient() {
System.out.println("南方饺子");
System.out.println("准备猪肉和饺子皮...");
}
}
/**
* @Author: dashu
* @Description: 南方牛肉饺子
* @Date: 23:26
* @Version: 1.0
*/
public class NFBeefDumplings extends Dumplings {
/**
* 准备食材
*/
@Override
public void ingredient() {
System.out.println("南方饺子");
System.out.println("准备牛肉和饺子皮...");
}
}
/**
* @Author: dashu
* @Description: 买北方饺子
* @Date: 2022/3/25 0:05
* @Version: 1.0
*/
public class BFBuyDumplingsByFactoryMethod extends BuyDumplingsByFactoryMethod {
/**
* 创建饺子
* @param stuffing 馅
* @return
*/
@Override
public Dumplings createDumplings(String stuffing) {
Dumplings dumplings = null;
if (stuffing.equals("猪肉")) {
dumplings = new BFPorkDumplings();
dumplings.setStuffing(stuffing);
} else if (stuffing.equals("牛肉")) {
dumplings = new BFBeefDumplings();
dumplings.setStuffing(stuffing);
}
return dumplings;
}
}
/**
* @Author: dashu
* @Description: 买南方饺子
* @Date: 2022/3/25 0:05
* @Version: 1.0
*/
public class NFBuyDumplingsByFactoryMethod extends BuyDumplingsByFactoryMethod {
/**
* 创建饺子
* @param stuffing 馅
* @return
*/
@Override
public Dumplings createDumplings(String stuffing) {
Dumplings dumplings = null;
if (stuffing.equals("猪肉")) {
dumplings = new NFPorkDumplings();
dumplings.setStuffing(stuffing);
} else if (stuffing.equals("牛肉")) {
dumplings = new NFBeefDumplings();
dumplings.setStuffing(stuffing);
}
return dumplings;
}
}
/**
* @Author: dashu
* @Description: 买饺子
* @Date: 23:30
* @Version: 1.0
*/
public abstract class BuyDumplingsByFactoryMethod {
/**
* 创建饺子
*
* @param stuffing 馅
* @return
*/
public abstract Dumplings createDumplings(String stuffing);
private Dumplings dumplings;
public BuyDumplingsByFactoryMethod() {
String stuffing;
do {
stuffing = getStuffing();
dumplings = createDumplings(stuffing);
if (dumplings == null) {
System.out.println("没有你要买的饺子...");
break;
}
dumplings.ingredient();
dumplings.makeDumplings();
dumplings.boilDumplings();
dumplings.fishingDumplings();
} while (true);
}
/**
* 获取饺子馅
*
* @return
*/
private String getStuffing() {
try {
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(System.in));
System.out.println("请输入饺子馅:");
String s = bufferedReader.readLine();
return s;
} catch (IOException e) {
e.printStackTrace();
return "";
}
}
}
/**
* @Author: dashu
* @Description: 测试
* @Date: 23:57
* @Version: 1.0
*/
public class Main {
public static void main(String[] args) {
new BFBuyDumplingsByFactoryMethod();
}
}
2、结论
工厂方法模式:定义一个创建对象的抽象方法,由子类决定要实例化的类。
工厂方法模式将对象的实例化推迟到了子类
五、抽象工厂模式
1、UML
2、代码案例
/**
* @Author: dashu
* @Description: 饺子
* @Date: 23:18
* @Version: 1.0
*/
public abstract class Dumplings {
private String stuffing;
/**
* 准备食材
*/
public abstract void ingredient();
/**
* 包饺子
*/
public void makeDumplings() {
System.out.println("包" + stuffing + "饺子");
}
/**
* 煮饺子
*/
public void boilDumplings() {
System.out.println("煮" + stuffing + "饺子");
}
/**
* 捞饺子
*/
public void fishingDumplings() {
System.out.println("捞" + stuffing + "饺子");
}
/**
* 饺子名
*
* @param stuffing
*/
public void setStuffing(String stuffing) {
this.stuffing = stuffing;
}
}
/**
* @Author: dashu
* @Description: 北方猪肉饺子
* @Date: 23:28
* @Version: 1.0
*/
public class BFPorkDumplings extends Dumplings {
/**
* 准备食材
*/
@Override
public void ingredient() {
System.out.println("北方饺子");
System.out.println("准备猪肉和饺子皮...");
}
}
/**
* @Author: dashu
* @Description: 北方牛肉饺子
* @Date: 23:26
* @Version: 1.0
*/
public class BFBeefDumplings extends Dumplings {
/**
* 准备食材
*/
@Override
public void ingredient() {
System.out.println("北方饺子");
System.out.println("准备牛肉和饺子皮...");
}
}
/**
* @Author: dashu
* @Description: 南方猪肉饺子
* @Date: 23:28
* @Version: 1.0
*/
public class NFPorkDumplings extends Dumplings {
/**
* 准备食材
*/
@Override
public void ingredient() {
System.out.println("南方饺子");
System.out.println("准备猪肉和饺子皮...");
}
}
/**
* @Author: dashu
* @Description: 南方牛肉饺子
* @Date: 23:26
* @Version: 1.0
*/
public class NFBeefDumplings extends Dumplings {
/**
* 准备食材
*/
@Override
public void ingredient() {
System.out.println("南方饺子");
System.out.println("准备牛肉和饺子皮...");
}
}
/**
* @Author: dashu
* @Description: 抽象工厂:饺子
* @Date: 2022/3/25 0:23
* @Version: 1.0
*/
public interface DumplingsAbstractFactory {
/**
* 创建饺子
* @param stuffing 馅
* @return
*/
Dumplings createDumplings(String stuffing);
}
/**
* @Author: dashu
* @Description: 简单工厂:北方饺子
* @Date: 2022/3/25 0:25
* @Version: 1.0
*/
public class BFDumplingsAbstractFactory implements DumplingsAbstractFactory{
/**
* 创建饺子
* @param stuffing 馅
* @return
*/
@Override
public Dumplings createDumplings(String stuffing) {
Dumplings dumplings = null;
if (stuffing.equals("猪肉")) {
dumplings = new BFPorkDumplings();
dumplings.setStuffing(stuffing);
} else if (stuffing.equals("牛肉")) {
dumplings = new BFBeefDumplings();
dumplings.setStuffing(stuffing);
}
return dumplings;
}
}
/**
* @Author: dashu
* @Description: 简单工厂:北方饺子
* @Date: 2022/3/25 0:25
* @Version: 1.0
*/
public class NFDumplingsAbstractFactory implements DumplingsAbstractFactory {
/**
* 创建饺子
*
* @param stuffing 馅
* @return
*/
@Override
public Dumplings createDumplings(String stuffing) {
Dumplings dumplings = null;
if (stuffing.equals("猪肉")) {
dumplings = new NFPorkDumplings();
dumplings.setStuffing(stuffing);
} else if (stuffing.equals("牛肉")) {
dumplings = new NFBeefDumplings();
dumplings.setStuffing(stuffing);
}
return dumplings;
}
}
/**
* @Author: dashu
* @Description: 买饺子
* @Date: 23:30
* @Version: 1.0
*/
public class BuyDumplingsByAbstractFactory {
private DumplingsAbstractFactory dumplingsAbstractFactory;
private Dumplings dumplings;
public BuyDumplingsByAbstractFactory(DumplingsAbstractFactory dumplingsAbstractFactory) {
this.dumplingsAbstractFactory = dumplingsAbstractFactory;
buyDumplings();
}
public void buyDumplings() {
String stuffing;
do {
stuffing = getStuffing();
dumplings = dumplingsAbstractFactory.createDumplings(stuffing);
if (dumplings == null) {
System.out.println("没有你要买的饺子...");
break;
}
dumplings.ingredient();
dumplings.makeDumplings();
dumplings.boilDumplings();
dumplings.fishingDumplings();
} while (true);
}
/**
* 获取饺子馅
*
* @return
*/
private String getStuffing() {
try {
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(System.in));
System.out.println("请输入饺子馅:");
String s = bufferedReader.readLine();
return s;
} catch (IOException e) {
e.printStackTrace();
return "";
}
}
}
/**
* @Author: dashu
* @Description: 测试
* @Date: 23:57
* @Version: 1.0
*/
public class Main {
public static void main(String[] args) {
new BuyDumplingsByAbstractFactory(new BFDumplingsAbstractFactory());
}
}
3、结论
抽象工厂模式:定义一个interface
用于创建相关或有依赖关系的对象,而无需指明具体的类
抽象工厂模式就是对简单工厂模式的改进(进一步的抽象)
抽象工厂模式将工厂抽象成两层,AbsFactory(抽象工厂)和具体实现的工厂子类。我们可以根据创建对象类型使用对应的工厂子类