创建模式概述
通过创建模式可以让创建产品对象的客户端不再依赖具体产品,通过工厂获取产品对象,实现客户与产品之间的解耦,也是封装变化原则的一种体现.
uml图
工厂方法模式案例Uml图
工厂方法模式
定义:定义一个创建对象的接口,由子类决定具体创建哪个对象,它让实例化延迟到子类上.
应用范围:1.一个类不知道要创建哪个产品.
2.一个类希望由子类来指定创建具体产品对象.
应用案例:现有两家公司生产同类产品,a公司能生成ProductA和ProductB,b公司能生成ProductC和ProductD原料的初始成本一致,但是经过加工后获取的价格不一致.现有代码如下.
/**
* 抽象产品 默认原始价格一致
*/
public abstract class AbstractProduct {
protected String companyMame;
protected String productNumber;
protected double price = 5;
public abstract void machining();//加工方法
public double getPrice() {
return price;
}
}
/**
具体产品a
*/
public class ProductA extends AbstractProduct {
public ProductA(String productNumber,String companyMame) {
this.productNumber = productNumber;
this.companyMame = companyMame;
}
@Override
public void machining() {
System.out.println("公司="+companyMame+"产品编号="+productNumber+"产出");
this.price *=2;
}
}
/**
产品B
*/
public class ProductB extends AbstractProduct {
public ProductB(String companyName,String productNumber) {
this.companyMame = companyName;
this.productNumber=productNumber;
}
@Override
public void machining() {
System.out.println("公司="+companyMame+"产品编号="+productNumber+"产出");
this.price *=2.5;
}
}
/**
B公司生成的产品C
*/
public class ProductC extends AbstractProduct {
public ProductC(String companyName,String productNumber) {
this.companyMame = companyName;
this.productNumber=productNumber;
}
@Override
public void machining() {
System.out.println("公司="+companyMame+"产品编号="+productNumber+"产出");
this.price *=3;
}
}
/*
B公司生成的产品d
*/
public class ProductD extends AbstractProduct {
public ProductD(String companyName,String productNumber) {
this.companyMame = companyName;
this.productNumber=productNumber;
}
@Override
public void machining() {
System.out.println("公司="+companyMame+"产品编号="+productNumber+"产出");
this.price *=3;
}
}
/*
将客户端和创建者(抽象工厂结合起来)
*/
public abstract class CreatorAndClient {
//获取产品报价
public double getProductPrice(String type){
//以下算是对抽象工厂调用的客户端
AbstractProduct p = createProdut(type);
p.machining();
return p.getPrice();
}
/**
*(抽象工厂对应的方法)生成产品的抽象方法
*/
public abstract AbstractProduct createProdut(String type);
}
/*具体工厂类a 由该类实现生产何种产品
*/
public class CreatorAndClient1 extends CreatorAndClient {
//具体工厂根据产品类型生产不同的产品 该工厂只生成a公司产品
@Override
public AbstractProduct createProdut(String type) {
AbstractProduct product = null;
if("p1".equals(type)){
product = new ProductA("p1","a");
}else if("p2".equals(type)){
product = new ProductB("p2","a");
}
return product;
}
}
/*具体工厂类b 由该类实现生产何种产品
*/
public class CreatorAndClient2 extends CreatorAndClient {
//具体工厂根据产品类型生产不同的产品 该工厂只生成b公司产品
@Override
public AbstractProduct createProdut(String type) {
AbstractProduct product = null;
if("p1".equals(type)){
product = new ProductC("p1","b");
}else if("p2".equals(type)){
product = new ProductD("p2","b");
}
return product;
}
}
以上为工厂方法的一个案例:这里讲客户端溶于抽象工厂里,获取产品价格中对createProdut(type)方法的调用就是实际对工厂的调用,实际生产的产品是哪类产品由子类决定.
工厂方法模式的优点:1.符合部分开闭原则(对拓展开放,对修改关闭),如果有新从产品添加进来,只需要继承抽象产品类,需要用到新的产品只需要在通过新的工厂类继承抽象工厂便可使用,拓展新产品比较方便.2.实现客户端与具体产品的解耦.3.更符合设计原则 依赖倒转,依赖于抽象不依赖与具体实现(都依赖AbstarctProduct 低层组件想要被使用就必须是AbstarctProduct的子类,而本身客户端也依赖于AbstarctProduct去做操作).
工厂方法模式的缺点:1.如果新增产品在原先的工厂方法类中使用到还是需要修改.
uml图
抽象工厂模式案例图
抽象工厂模式
定义:定义一个接口,用于创建相关或依赖的产品家族,而不需要指定具体类
应用范围:1.系统独立与产品创建,组合.
2.需要强调产品系列的设计以进行联合使用
3.想提供一个产品类库,只想显示接口的时候
应用案例:现有一家公司能生成多钟类型的手机配件,比如手机外壳,手机芯片(暂时假定手机由这两种配件组装成)
//手机外壳抽象类
public abstract class PhoneShell {
protected PhoneChip chip;
public void setChip(PhoneChip chip) {
this.chip = chip;
}
}
//手机外壳种类1
public class PhoneShell1 extends PhoneShell {
public PhoneShell1(){
System.out.println("手机外壳种类1创建");
}
}
//手机外壳种类2
public class PhoneShell2 extends PhoneShell {
public PhoneShell2(){
System.out.println("手机外壳芯片2创建");
}
}
//手机芯片抽象类
public abstract class PhoneChip {
}
//手机芯片种类1
public class PhoneChip1 extends PhoneChip {
public PhoneChip1(){
System.out.println("手机芯片类型1");
}
}
//手机芯片种类2
public class PhoneChip2 extends PhoneChip {
public PhoneChip2(){
System.out.println("手机芯片类型2创建");
}
}
//手机工厂抽象类接口
public interface PhoneAbstractFactory {
//创建手机外壳
PhoneShell createPhoneShell();
//创建手机芯片
PhoneChip createPhoneChip();
}
//手机工厂类1
public class PhoneFactory1 implements PhoneAbstractFactory {
@Override
public PhoneShell createPhoneShell() {
return new PhoneShell1();
}
@Override
public PhoneChip createPhoneChip() {
return new PhoneChip1();
}
}
//手机及工厂类2
public class PhoneFactory2 implements PhoneAbstractFactory {
@Override
public PhoneShell createPhoneShell() {
return new PhoneShell2();
}
@Override
public PhoneChip createPhoneChip() {
return new PhoneChip2();
}
}
//客户端调用代码及测试
public class PhoneClient {
public static void createPhone(PhoneAbstractFactory factory){
PhoneChip chip = factory.createPhoneChip();
PhoneShell shell = factory.createPhoneShell();
shell.setChip(chip);
}
public static void main(String[] args){
PhoneAbstractFactory factory = new PhoneFactory1();
createPhone(factory);
}
}
抽象工厂模式的优点:1.符合部分开闭原则:如果是原有的产品种类即使拓展新的类型只需要创建一个新工厂实现抽象工厂即可.2.实现客户端与具体产品的解耦.3.符合依赖倒转原则,
缺点:如果有新的产品种类添加进来,还是需要在抽象工厂中添加一个方法在子类实现
比较
两者之间的比较:
相同点:都有抽象工厂类,在子类中实现具体对象的创建.
不同点:1.工厂方法针对的是一类产品,抽象工厂针对的是一个产品族 多个产品的对象创建.2.工厂方法模式一般采用继承,而抽象工厂模式也是通过子类实现创建具体类对象,但在使用的时候多用组合 通过指定一个工厂就可以创建多种产品类型的对象
如有转载请注明出处,希望浅薄见解能帮助到您