目录
首先说明,设计模式是独立于具体编程语言的,在具体实现上,会由于编程语言的特性不同而有所不同。
创建型模式主要关注如何&何时创建对象,使得在调用方法时,不需要了解对象具体的类型,只需要了解抽象类型。(可以理解为,想买苹果,只需要去水果店,不用去专门、只卖苹果的地方)
工厂方法模式、抽象工厂模式都属于创建型模式;简单工厂不属于 23 种标准模式之一,但它是工厂家族中最简单的模式。
简单工厂模式
简单工厂模式主要包括:
1个抽象产品Product(父类)、
n个具体产品类xProduct(子类、继承抽象产品)、
1个工厂类(用于生成产品,其中的方法返回类型为Product,其中的核心为 Product product = new xProduct())
案例:以一个简单的计算器程序为例:
(1)抽象产品(父类)
public abstract class Computer {
private String a;
private String b;
public String getA(){
return a;
}
public void setA(String a) {
this.a = a;
}
public String getB() {
return b;
}
public void setB(String b) {
this.b = b;
}
public String getResult(){
return "";
}
}
(2)具体产品(子类)
子类都继承了抽象类Computer,并重写了getResult方法
public class OperationAdd extends Computer {
@Override
public String getResult(){
return Double.toString( Double.valueOf(getA()) + Double.valueOf(getB()));
}
}
public class OperationSub extends Computer{
@Override
public String getResult(){
return Double.toString( Double.valueOf(getA()) - Double.valueOf(getB()));
}
}
public class OperationMul extends Computer{
@Override
public String getResult(){
return Double.toString( Double.valueOf(getA()) * Double.valueOf(getB()));
}
}
public class OperationDiv extends Computer{
@Override
public String getResult(){
if(Double.valueOf(getB())==0) {
return "除数不能为0";
}
else{
return Double.toString(Double.valueOf(getA()) / Double.valueOf(getB()));
}
}
}
(3)工厂类
工厂类的CreateOperation方法生产对象,根据Operate对应生产不同的子类对象,但对外展现的类型为父类Computer类。
public class OperationFactory {
public static Computer CreateOperation(String Operate){
Computer operation = null;
switch (Operate){
case "+":
operation = new OperationAdd();
break;
case "-":
operation = new OperationSub();
break;
case "*":
operation = new OperationMul();
break;
case "/":
operation = new OperationDiv();
break;
}
return operation;
}
}
(4)test
public class test {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
System.out.print("请输入数字A: ");
String strNumberA = input.nextLine();
System.out.print("请选择运算符号(+、-、*、/): ");
String strOperate = input.nextLine();
System.out.print("请输入数字B: ");
String strNumberB = input.nextLine();
Computer operation = OperationFactory.CreateOperation(strOperate);
operation.setA(strNumberA);
operation.setB(strNumberB);
String strResult = operation.getResult();
if (strResult.equals("除数不能为0")){
System.out.println("除数不能为0");
}
else {
System.out.println("结果为"+strResult);
}
}
}
工厂方法模式
在具体产品经常变化时,简单工厂方法不适用,违反了开放封闭原则(可以加功能,不能改功能),这时,可以使用工厂方法模式。
工厂方法模式:有1个抽象工厂(抽象类/接口,定义工厂的返回类型)、n个具体工厂、1个抽象产品(抽象类/接口)、n个具体产品;在抽象工厂类中,定义一个方法用于生产产品(这个方法叫工厂方法),该方法由具体工厂实现。
这样,在需要新增具体产品时,只需要新增具体产品类、具体工厂类,原来的代码不用修改,符合开放封闭原则。
案例:
(1)抽象产品
public interface Clothe {
void style();
}
(2)具体产品
public class Pants implements Clothe{
@Override
public void style() {
System.out.println("Pants");
}
}
public class Tshirt implements Clothe{
@Override
public void style() {
System.out.println("T-shirt");
}
}
(3)抽象工厂
public interface ClotheFactory {
Clothe clothe();
}
(4)具体工厂
public class PantsFactory implements ClotheFactory{
public Clothe clothe(){
return new Pants();
}
}
public class TshirtFactory implements ClotheFactory{
public Clothe clothe(){
return new Tshirt();
}
}
(5)test
public class test {
public static void main(String[] args) {
ClotheFactory factory = new PantsFactory();
Clothe clothe = factory.clothe();
clothe.style();
}
}
抽象工厂模式
抽象工厂模式跟工厂方法模式最大的区别在于:
工厂方法模式是一个具体工厂对应生产一个具体产品。(对应到现实,可以理解为一个专一化的工厂,比如裤子厂房只生产裤子)
而抽象工厂方法模式是一个具体工厂生产多种具体产品。(对应到现实来说,一个a牌子的服装工厂会生产a牌子的裤子、a牌子的上衣;b牌子的服装工厂则会生产b牌子的裤子、上衣)
案例:
(1)抽象产品
public interface PantsProduct {
void producePants();
}
public interface TshirtProduct {
void produceTshirt();
}
(2)具体产品
a牌子的产品:
public class aPants implements PantsProduct {
@Override
public void producePants() {
System.out.println("生产a牌牛仔裤");
}
}
public class aTshirt implements TshirtProduct {
@Override
public void produceTshirt() {
System.out.println("生产a牌T恤");
}
}
b牌子的产品:
public class bPants implements PantsProduct {
@Override
public void producePants() {
System.out.println("生产b牌牛仔裤");
}
}
public class bTshirt implements TshirtProduct {
@Override
public void produceTshirt() {
System.out.println("生产b牌T恤");
}
}
(3)抽象工厂
public interface IClotheFactory {
void start();
PantsProduct Pants();
TshirtProduct Tshirt();
}
(4)具体工厂
a牌工厂
public class aFactory implements IClotheFactory{
@Override
public void start() {
System.out.println("这里是a工厂");
}
@Override
public PantsProduct Pants() {
return new aPants();
}
@Override
public TshirtProduct Tshirt() {
return new aTshirt();
}
}
b牌工厂
public class bFactory implements IClotheFactory{
@Override
public void start(){
System.out.println("这里是b工厂");
}
@Override
public PantsProduct Pants() {
return new bPants();
}
@Override
public TshirtProduct Tshirt() {
return new bTshirt();
}
}
(5)test
public class test {
public static void main(String[] args) {
IClotheFactory clotheFactory = new aFactory();
clotheFactory.start();
clotheFactory.Pants().producePants();
clotheFactory.Tshirt().produceTshirt();
System.out.println("————");
IClotheFactory clotheFactory1 = new bFactory();
clotheFactory1.start();
clotheFactory1.Pants().producePants();
clotheFactory1.Tshirt().produceTshirt();
}
}
但是,工厂模式仍然需要在客户端(如以上出现的test类)中,根据需要生产的产品,修改部分代码,在一定程度上违反了开放封闭原则,这就需要使用到反射机制了(继续学习!)