设计模式-工厂模式

1.抽象工厂

1.图示:
工厂是抽象的,产品是抽象的,每个实际工厂负责创建一系列产品。
在这里插入图片描述
2. 示例代码:
假设我们希望为用户提供一个Markdown文本转换为HTML和Word的服务,它的接口定义如下:

  1. 抽象工厂
public interface AbstractFactory {
    // 创建Html文档:
    HtmlDocument createHtml(String md);
    // 创建Word文档:
    WordDocument createWord(String md);
}
  1. 抽象产品
两个抽象产品
// Html文档接口:
public interface HtmlDocument {
    String toHtml();
    void save(Path path) throws IOException;
}
// Word文档接口:
public interface WordDocument {
    void save(Path path) throws IOException;
}
  1. 实际工厂
实际工厂1
public class FastFactory implements AbstractFactory {

	@Override
	public HtmlDocument createHtml(String md) {
		return new FastHtmlDocument(md);
	}

	@Override
	public WordDocument createWord(String md) {
		return new FastWordDocument(md);
	}
}

实际工厂2
public class GoodFactory implements AbstractFactory {

	@Override
	public HtmlDocument createHtml(String md) {
		return new GoodHtmlDocument(md);
	}

	@Override
	public WordDocument createWord(String md) {
		return new GoodWordDocument(md);
	}
}

  1. 实际工厂1 负责生产的实际产品,
产品A1
public class FastHtmlDocument implements HtmlDocument {

	private String md;

	public FastHtmlDocument(String md) {
		this.md = md;
	}

	@Override
	public String toHtml() {
		return md.lines().map(s -> {
			if (s.startsWith("#")) {
				return "<h1>" + s.substring(1) + "</h1>";
			}
			return "<p>" + s + "</p>";
		}).reduce("", (acc, s) -> acc + s + "\n");
	}

	@Override
	public void save(Path path) throws IOException {
		Files.write(path, toHtml().getBytes("UTF-8"));
	}
}


产品B1
public class FastWordDocument implements WordDocument {

	private String md;

	public FastWordDocument(String md) {
		this.md = md;
	}

	@Override
	public void save(Path path) throws IOException {
		String doc = "{\\rtf1\\ansi\n{\\fonttbl\\f0\\fswiss\\fcharset0 Helvetica-Bold;\\f1\\fswiss\\fcharset0 Helvetica;}\n";
		String body = md.lines().map(s -> {
			if (s.startsWith("#")) {
				return String.format("\\f0\\b\\fs24 \\cf0%s\\par\n", s.substring(1));
			}
			return String.format("\\f1\\b0%s\\par\n", s);
		}).reduce("", (acc, s) -> acc + s);
		String content = doc + body + "}";
		Files.write(path, content.getBytes("UTF-8"));
	}
}
  1. 实际工厂2 负责生产的实际产品
产品A2
public class GoodHtmlDocument implements HtmlDocument {
	private String md;
	public GoodHtmlDocument(String md) {
		this.md = md;
	}

	@Override
	public String toHtml() {
		//todo
	}

	@Override
	public void save(Path path) throws IOException {
		//todo
	}
}

产品B2
public class GoodWordDocument implements HtmlDocument {
    ...
}
  1. 实际调用
public static void main(String[] args) throws IOException {
		AbstractFactory fastFactory = new FastFactory();
		HtmlDocument fastHtml = fastFactory.createHtml("#Hello\nHello, world!");
		System.out.println(fastHtml.toHtml());
		fastHtml.save(Paths.get(".", "fast.html"));
		WordDocument fastWord = fastFactory.createWord("#Hello\nHello, world!");
		fastWord.save(Paths.get(".", "fast.doc"));

		AbstractFactory goodFactory = new GoodFactory();
		HtmlDocument goodHtml = goodFactory.createHtml("#Hello\nHello, world!");
		System.out.println(goodHtml.toHtml());
		goodHtml.save(Paths.get(".", "good.html"));
		WordDocument goodWord = goodFactory.createWord("#Hello\nHello, world!");
		goodWord.save(Paths.get(".", "good.doc"));
	}

2.工厂方法

先创建出某一具体工厂,再用工厂创建实现某一接口的具体产品。
1.图示:
在这里插入图片描述
2.代码示例
2.1 抽象产品:
Number 抽象产品
在这里插入图片描述
2.2 实际产品
BigDecimal 实际产品
在这里插入图片描述

2.2 工厂接口:

public interface NumberFactory {
    Number parse(String s);
}

2.3 工厂实现类

public class NumberFactoryImpl implements NumberFactory {
    public Number parse(String s) {
        return new BigDecimal(s);
    }
}

2.4 实际调用

NumberFactory factory = NumberFactory.getFactory();
Number result = factory.parse("123.456");

2.5 静态工厂方法
例如:Integer既是产品又是静态工厂。它提供了静态方法valueOf()来创建Integer。
代码示例:

不需要抽象工厂,通过工厂的静态方法直接返回产品。
public class LocalDateFactory {

	private static Map<Integer, LocalDate> cache = new HashMap<>();

	public static LocalDate fromInt(int yyyyMMdd) {
		if (yyyyMMdd >= 20200101 && yyyyMMdd <= 20301231) {
			LocalDate result = cache.get(yyyyMMdd);
			if (result == null) {
				result = create(yyyyMMdd);
				cache.put(yyyyMMdd, result);
			}
			return result;
		}
		return create(yyyyMMdd);
	}

	private static LocalDate create(int yyyyMMdd) {
		return LocalDate.of(yyyyMMdd / 10000, yyyyMMdd / 100 % 100, yyyyMMdd % 100);
	}
}

public class Main {

	public static void main(String[] args) throws NoSuchAlgorithmException {
		LocalDate ld = LocalDateFactory.fromInt(20200202);
		System.out.println(ld);
		LocalDate ld2 = LocalDateFactory.fromInt(20200202);
		System.out.println(ld == ld2);
	}
}

3.简单工厂

一个工厂,根据不同的参数创建出实现产品接口某一具体产品。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值