设计模式笔记——对象创建(纯笔记,JAVA)
2016-10-03 本文已影响15人
RMaple_Qiu
历览前贤国与家,成由勤俭破由奢。
何须琥珀方为枕,岂得真珠始是车。
运去不逢青海马,力穷难拔蜀山蛇。
几人曾预南薰曲,终古苍梧哭翠华。
——《咏史二首·其二》李商隐
听网络课程后的笔记,还不是很理解,小弟先记下,待未来小有理解后再来完善。
一、工厂方法
在软件系统中,经常面临着创建对象的工作;由于需求的变化,需要创建的对象的具体类型经常变化。工厂方法的就是定义一个用于创建对象的接口,让子类决定实例化哪一个类。工厂方法使得一个类的实例化延迟。
工厂方法—分析图根据分析图可以看到工厂方法必须先要有产品与产品工厂的接口,再由我们去实习接口,继承同一个接口的不同产品每个产品都应该有一个工厂类。
interface Product {
}
interface Factory {
Product createProduct();
}
public class Client {
public static void main(String[] args) {
FactoryA fa = new FactoryA();
FactoryB fb = new FactoryB();
Product a = fa.createProduct();
Product b = fb.createProduct();
}
}
class ProductA implements Product {
ProductA() {
System.out.println("这是产品A,由A工厂创建");
}
}
class FactoryA implements Factory {
@Override
public Product createProduct() {
return new ProductA();
}
}
class ProductB implements Product {
ProductB() {
System.out.println("这是产品B,由B工厂创建");
}
}
class FactoryB implements Factory {
@Override
public Product createProduct() {
return new ProductB();
}
}
总结
- 工厂方法模式用于隔离类对象的使用者和具体类型之间的耦合关系。面对一个经常变化的具体类型,紧耦合(new)会导致软件脆弱。
- 工厂方法模式通过面向对象的手法,将所要创建的具体类型工作延迟到子类,从而实现一种扩展而非更改的策略,较好地解决了这种紧耦合关系。
- 工厂方法模式解决单个对象的需求变化。缺点在于要求创建方法/参数相同。
由此可知当我们要创建一些外壳相同(创建方法/参数相同),内部需求变化的对象,就可以是用工厂方法。记住每一个具体对象要有一个工厂类。
二、抽象工厂模式
在软件系统中,经常面临着“一系列相互依赖的对象”的创建工作;同时由于需求的变化,往往存在更多系列对象的创建工作。
抽象工厂—分析图
与工厂方法模式不同的是,抽象工厂适合于“一系列相互依赖的对象”,而工厂不只是生产单一产品,而是从零件到完成品一条龙生产。小弟做了个肉串工厂(羊肉串,牛肉串),嘻嘻
public class Client {
public static void main(String[] args) {
KebabFactory factory1 = new MuttonKebabFactory();
Meat mutton = factory1.purchaseMeat("顶级");
Seasoning muttonSeasoning = factory1.makeSeasoning("微辣");
Kebab muttonKebab = factory1.produceKebab(mutton, muttonSeasoning);
System.out.println(muttonKebab.getKebabInfo());
//
KebabFactory factory2 = new BeefKebabFactory();
Meat beef = factory2.purchaseMeat("五星");
Seasoning beefSeasoning = factory2.makeSeasoning("黑椒");
Kebab beefKebab = factory2.produceKebab(beef, beefSeasoning);
System.out.println(beefKebab.getKebabInfo());
}
}
//肉的基类
abstract class Meat {
abstract String getLevel();
}
//特制调料的基类
abstract class Seasoning {
abstract String getFlavor();
}
//肉串基类
abstract class Kebab {
abstract String getKebabInfo();
}
/**
* 抽象肉串工厂类
*/
abstract class KebabFactory {
public abstract Meat purchaseMeat(String level);
public abstract Seasoning makeSeasoning(String flavor);
public abstract Kebab produceKebab(Meat meat, Seasoning seasoning);
}
//羊肉类
class Mutton extends Meat {
private String level;
Mutton(String level) {
this.level = level;
}
@Override
public String getLevel() {
return level;
}
}
//特制羊肉调料
class MuttonSeasoning extends Seasoning {
private String flavor;
MuttonSeasoning(String flavor) {
this.flavor = flavor;
}
@Override
public String getFlavor() {
return flavor;
}
}
//羊肉串类
class MuttonKebab extends Kebab {
private Meat meat;
private Seasoning seasoning;
MuttonKebab(Meat meat, Seasoning seasoning) {
this.meat = meat;
this.seasoning = seasoning;
}
@Override
public String getKebabInfo() {
return meat.getLevel() + seasoning.getFlavor() + "羊肉串";
}
}
/**
* 羊肉串加工厂
* (具体工厂类)
*/
class MuttonKebabFactory extends KebabFactory {
@Override
public Meat purchaseMeat(String level) {
return new Mutton(level);
}
@Override
public Seasoning makeSeasoning(String flavor) {
return new MuttonSeasoning(flavor);
}
@Override
public Kebab produceKebab(Meat meat, Seasoning seasoning) {
return new MuttonKebab(meat, seasoning);
}
}
//牛肉类
class Beef extends Meat {
private String level;
Beef(String level) {
this.level = level;
}
@Override
public String getLevel() {
return level;
}
}
//特制牛肉调料类
class BeefSeasoning extends Seasoning {
private String flavor;
BeefSeasoning(String flavor) {
this.flavor = flavor;
}
@Override
public String getFlavor() {
return flavor;
}
}
//牛肉串类
class BeefKebab extends Kebab {
private Meat meat;
private Seasoning seasoning;
BeefKebab(Meat meat, Seasoning seasoning) {
this.meat = meat;
this.seasoning = seasoning;
}
@Override
public String getKebabInfo() {
return meat.getLevel() + seasoning.getFlavor() + "牛肉串";
}
}
/**
* 牛肉串加工厂
* (具体工厂类)
*/
class BeefKebabFactory extends KebabFactory {
@Override
public Meat purchaseMeat(String level) {
return new Beef(level);
}
@Override
public Seasoning makeSeasoning(String flavor) {
return new BeefSeasoning(flavor);
}
@Override
public Kebab produceKebab(Meat meat, Seasoning seasoning) {
return new BeefKebab(meat, seasoning);
}
}
按照分析图走,我首先创建了产品(肉,调料,肉串)和工厂的接口,由于不同的需求(牛肉串、羊肉串),又分别创建了各自的具体类与具体工厂类,而肉串最终是由肉和调料一起加工而成,加工过程都是在工厂中完成,一条龙服务呀。
总结
- 如果没有应对“多系列对象构建”的需求变化,则没有必要使用抽象工厂模式,这时候使用简单工厂就行
- “系列对象”指的是在某一特定系列下的对象之间相互依赖、或作用的关系。不同系列的对象之间不能相互依赖。
- 抽象工厂模式主要在于应对“新系列”的需求变动。其缺点在于难以应对“新对象”的需求变化。