软件设计师——设计模式笔记上(创造型5种)
设计模式的主要目的
复用成功的设计
设计模式的原则
- 开闭原则
- 里氏代换原则
- 依赖倒转原则
- 接口隔离原则
- 迪米特法则
- 合成复用原则
- 单一职责原则
1、工厂方法模式(类模式)
意图
定义一个创建对象的接口,让其子类自己决定实例化哪一个工厂类,工厂模式使其创建过程延迟到子类进行。(子类决定实例化)
适用性
- 当一个类不知道它所必须创建的对象的类的时候。
- 当一个类希望由它的子类来指定它所创建的对象的时候。
- 当类将创建对象的职责委托给多个帮助子类中的某一个,并且你希望将哪一个帮助子类是代理者这一信息局部化的时候。
代码实现
//1 工厂方法模式
public class FactoryMethod {
public static void main(String[] args) {
Factory factoryA = new FactoryA();
Product productA = factoryA.createProduct();
productA.info();
Factory factoryB = new FactoryB();
Product productB = factoryB.createProduct();
productB.info();
}
}
interface Factory {
public Product createProduct();
}
class FactoryA implements Factory {
@Override
public Product createProduct() {
return new ProductA();
}
}
class FactoryB implements Factory {
@Override
public Product createProduct() {
return new ProductB();
}
}
interface Product {
public void info();
}
class ProductA implements Product {
@Override
public void info() {
System.out.println("产品的信息:A");
}
}
class ProductB implements Product {
@Override
public void info() {
System.out.println("产品的信息:B");
}
}
运行结果
产品的信息:A
产品的信息:B
2、抽象工厂模式(对象模式)
意图
提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类。(抽象接口)
适用性
- 一个系统要独立于它的产品的创建、组合和表示时。
- 一个系统要由多个产品系列中的一个来配置时。
- 当要强调一系列相关的产品对象的设计以便进行联合使用时。
- 当提供一个产品类库,只想显示它们的接口而不是实现时。
代码实现
//2 抽象工厂模式
public class AbstractFactory {
public static void main(String[] args) {
Factory factory1 = new Factory1();
ProductA productA1 = factory1.createProductA();
ProductB productB1 = factory1.createProductB();
productA1.info();
productB1.info();
Factory factory2 = new Factory2();
ProductA productA2 = factory2.createProductA();
ProductB productB2 = factory2.createProductB();
productA2.info();
productB2.info();
}
}
interface Factory {
public ProductA createProductA();
public ProductB createProductB();
}
//用工厂1来生产产品1类
class Factory1 implements Factory {
@Override
public ProductA createProductA() {
return new ProductA1();
}
@Override
public ProductB createProductB() {
return new ProductB1();
}
}
//用工厂2来生产产品2类
class Factory2 implements Factory {
@Override
public ProductA createProductA() {
return new ProductA2();
}
@Override
public ProductB createProductB() {
return new ProductB2();
}
}
interface ProductA {
public void info();
}
//产品A分为产品A1类和产品A2类
class ProductA1 implements ProductA {
@Override
public void info() {
System.out.println("产品的信息:A1");
}
}
class ProductA2 implements ProductA {
@Override
public void info() {
System.out.println("产品的信息:A2");
}
}
interface ProductB {
public void info();
}
//产品B分为产品B1类和产品B2类
class ProductB1 implements ProductB {
@Override
public void info() {
System.out.println("产品的信息:B1");
}
}
class ProductB2 implements ProductB {
@Override
public void info() {
System.out.println("产品的信息:B2");
}
}
运行结果
产品的信息:A1
产品的信息:B1
产品的信息:A2
产品的信息:B2
3、生成器模式(对象模式)
意图
将一个复杂的构建与其表示相分离,使得同样的构建过程可以创建不同的表示。(类和构造分离)
适用性
- 当创建复杂对象的算法应该独立于该对象的组成部分以及它们的装配方式时。
- 当构造过程必须允许被构造的对象有不同的表示时。
代码实现
//3 生成器模式
import java.util.*;
public class Main {
public static void main(String[] args) {
Director director = new Director();
Builder builder1 = new Builder1();
//管理者创建了一个生成器1
director.Construct(builder1);
Product product1 = builder1.getResult();
product1.show();
Builder builder2 = new Builder2();
//管理者创建了一个生成器2
director.Construct(builder2);
Product product2 = builder2.getResult();
product2.show();
}
}
//管理者
class Director {
public void Construct(Builder builder) {
builder.BuildPart();
}
}
//生成器
abstract class Builder {
public abstract void BuildPart();
public abstract Product getResult();
}
//生成器1
class Builder1 extends Builder {
Product product = new Product();
@Override
public void BuildPart() {
product.Add("A");
product.Add("B");
product.Add("C");
product.Add("D");
product.Add("E");
product.Add("F");
}
@Override
public Product getResult() {
return product;
}
}
//生成器2
class Builder2 extends Builder {
Product product = new Product();
@Override
public void BuildPart() {
product.Add("A");
product.Add("B");
product.Add("C");
}
@Override
public Product getResult() {
return product;
}
}
//产品管理
class Product {
List<String> parts = new ArrayList<String>();
//添加到列表
public void Add(String part) {
parts.add(part);
}
//显示
public void show() {
System.out.print("产品的组成:");
for (String s : parts)
System.out.print(s + " ");
System.out.print("\n");
}
}
运行结果
产品的组成:A B C D E F
产品的组成:A B C D
4、原型模式(对象模式)
意图
用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象。(原型实例,拷贝)
适用性
- 当一个系统应该独立于它的产品创建、构成和表示时。
- 当要实例化的类是在运行时刻指定时,例如,通过动态装载。
- 为了避免创建一个与产品类层次平行的工厂类层次时。
- 当一个类的实例只能有几个不同状态组合中的一种时。 建立相应数目的原型并克隆它们,可能比每次用合适的状态手工实例化该类更方便一 些。
代码实现
//4 原型模式
public class Main {
public static void main(String[] args) {
Day day1 = new Day(2001, 1.21);
System.out.println("日期1" + day1.getYear() + " " + day1.getMonth());
//day2克隆day1的参数
Day day2 = (Day) day1.Clone();
System.out.println("日期2" + day2.getYear() + " " + day2.getMonth());
//day3克隆day1的参数
Day day3 = (Day) day1.Clone();
System.out.println("日期3" + day3.getYear() + " " + day3.getMonth());
}
}
interface Prototype {
public Object Clone();
}
class Day implements Prototype {
private int year;
private double month;
public Day() {}
public Day(int year, double month) {
this.year = year;
this.month = month;
}
public int getYear() {
return year;
}
public double getMonth() {
return month;
}
@Override
public Object Clone() {
//克隆对象
Day object = new Day();
object.year = this.year;
object.month = this.month;
return object;
}
}
运行结果
日期1:2001 1.21
日期2:2001 1.21
日期3:2001 1.21
5、单例模式(对象模式)
意图
保证一个类仅有一个实例,并提供一个访问它的全局访问点。(唯一实例)
适用性
- 当类只能有一个实例而且客户可以从一个众所周知的访问点访问它时。
- 当这个唯一实例应该是通过子类化可扩展的,并且客户无须更改代码就能使用一个扩展的实例时。
代码实现
//5 单例模式
public class SingletonPattern {
public static void main(String[] args) {
Singleton singleton1 = Singleton.getInstance();
Singleton singleton2 = Singleton.getInstance();
Singleton singleton3 = Singleton.getInstance();
System.out.println(singleton1.getNumber() + " " + singleton2.getNumber() + " " + singleton3.getNumber());
singleton1.setNumber(121);
System.out.println(singleton1.getNumber() + " " + singleton2.getNumber() + " " + singleton3.getNumber());
}
}
class Singleton {
private int number = 2001;
public void setNumber(int number) {
this.number = number;
}
public int getNumber() {
return number;
}
//创建仅有的一个对象
private static Singleton instance = new Singleton();
private Singleton() {}
public static Singleton getInstance() {
return instance;
}
}
运行结果
2001 2001 2001
121 121 121