上学的时候学习设计模式糊里糊涂,现在学习MVP模式,感觉自己的基础太薄,所有拿出了以前的教材书,花点时间重新理解,文字给出的简介均是来源于百度词条。代码则是根据自己的理解写出的小Demo。类名的话我尽量用了其包含角色的英文名来命名,,这样的话一看便知道这个类属于什么角色了。也做了一些注释,巩固了自己的Java基础。
源代码已经上传到了GitHub.
https://github.com/tanglonghui/DesignPatterns
设计模式简单小例子(二)结构型模式:
https://blog.csdn.net/qq_40687864/article/details/81094414
设计模式简单小例子(三)行为型模式:
https://blog.csdn.net/qq_40687864/article/details/82148887
一,简单工厂模式
package CreationalPatterns.SimpleFactory;
/*
* 简单工厂模式是属于创建型模式,又叫做静态工厂方法(Static Factory Method)模式,
* 但不属于23种GOF设计模式之一。简单工厂模式是由一个工厂对象决定创建出哪一种产品类的实例。
* 简单工厂模式是工厂模式家族中最简单实用的模式,可以理解为是不同工厂模式的一个特殊实现。
*/
/*
* 包含角色:
* 1.Factory(工厂角色)
* 2.Product(抽象产品角色)
* 3.ConcreteProduct(具体产品角色)
*/
class Test {
public static void main(String[] args) {
//建立工厂
Factory factory=new Factory();
//生产A
factory.produce("A").say();
//生产B
factory.produce("B").say();
/*
* ps:Product类中可用 interface 关键词修饰,效果相同
*/
}
}
class Factory{
Product produce(String chose) {
if(chose.equals("A")) {
return new ConcreteProductA();
}else if(chose.equals("B")) {
return new ConcreteProductB();
}else {
System.out.println("输入的参数不对,没有该类");
return null;
}
}
}
abstract class Product{
abstract void say();
}
class ConcreteProductA extends Product{
@Override
void say() {
// TODO Auto-generated method stub
System.out.println("我是产品A!!!");
}
}
class ConcreteProductB extends Product{
@Override
void say() {
// TODO Auto-generated method stub
System.out.println("我是产品B!!!");
}
}
二,工厂方法模式
package CreationalPatterns.FactoryMethod;
/*
* 工厂方法模式(FACTORY METHOD)是一种常用的对象创建型设计模式,此模式的核心精神是封装类中不变的部分,
* 提取其中个性化善变的部分为独立类,通过依赖注入以达到解耦、复用和方便后期维护拓展的目的。
*/
/*
* 包含角色:
* 1.Product(抽象产品)
* 2.ConCreteProduct(具体产品)
* 3.Factory(抽象工厂)
* 4.ConcreteFactory(具体工厂)
*/
class Test {
public static void main(String[] args) {
new ConcreteFactoryA().produce().say();
new ConcreteFactoryB().produce().say();
/*工厂生产中将ProductA 向上转型成了Product
* 所以要使具体产品变量获得引用,需要向下转型。
*/
Product p=new ConcreteFactoryA().produce();
ProductA p1=(ProductA) new ConcreteFactoryA().produce();
p.say();
p1.say();
}
}
interface Product{
void say();
}
class ProductA implements Product{
@Override
public void say() {
// TODO Auto-generated method stub
System.out.println("产品A");
}
}
class ProductB implements Product{
@Override
public void say() {
// TODO Auto-generated method stub
System.out.println("产品B");
}
}
interface Factory{
Product produce();
}
class ConcreteFactoryA implements Factory{
@Override
public Product produce() {
// TODO Auto-generated method stub
System.out.print("工厂A正在生产:");
//这里向上转型了
return new ProductA();
}
}
class ConcreteFactoryB implements Factory{
@Override
public Product produce() {
// TODO Auto-generated method stub
System.out.print("工厂B正在生产:");
//这里向上转型了
return new ProductB();
}
}
三,抽象工厂模式
package CreationalPatterns.AbstractFactory;
/*
* 工厂方法模式的进化版
* 抽象工厂模式:
* 提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类
* 抽象工厂模式是所有形态的工厂模式中最为抽象和最具一般性的一种形态。
* 抽象工厂模式是指当有多个抽象角色时,使用的一种工厂模式。
* 抽象工厂模式可以向客户端提供一个接口,使客户端在不必指定产品的具体的情况下,创建多个产品族中的产品对象。
* 根据里氏替换原则,任何接受父类型的地方,都应当能够接受子类型。
* 因此,实际上系统所需要的,仅仅是类型与这些抽象产品角色相同的一些实例,而不是这些抽象产品的实例。
* 换言之,也就是这些抽象产品的具体子类的实例。工厂类负责创建抽象产品的具体子类的实例。
*/
/*
* 包含角色:
* AbstractFactory(抽象工厂)
* ConcreteFactory(具体工厂)
* AbstractProduct(抽象产品)
* ConcreteProduct(具体产品)
*/
public class Test {
public static void main(String[] args) {
new ConcreteFactory1().produceA().whatAConDo();
new ConcreteFactory2().produceA().whatAConDo();
}
}
/*
* 其实这种类似于行跟列的关系 一个是品牌 一个是具体什么类的产品
* A B 表示具体是什么类的产品 1 2 数字表示品牌
*/
interface AbstractProductA{
void whatAConDo();
}
interface AbstractProductB{
void whatBConDo();
}
class ConcreteProductA1 implements AbstractProductA{
@Override
public void whatAConDo() {
// TODO Auto-generated method stub
System.out.println("我是A类型,1品牌的产品");
}
}
class ConcreteProductA2 implements AbstractProductA{
@Override
public void whatAConDo() {
// TODO Auto-generated method stub
System.out.println("我是A类型,2品牌的产品");
}
}
class ConcreteProductB1 implements AbstractProductB{
@Override
public void whatBConDo() {
// TODO Auto-generated method stub
System.out.println("我是B类型,1品牌的产品");
}
}
class ConcreteProductB2 implements AbstractProductB{
@Override
public void whatBConDo() {
// TODO Auto-generated method stub
System.out.println("我是B类型,2品牌的产品");
}
}
interface AbstractFactory{
AbstractProductA produceA();
AbstractProductB produceB();
}
class ConcreteFactory1 implements AbstractFactory{
//1 品牌产品的专属工厂
@Override
public AbstractProductA produceA() {
// TODO Auto-generated method stub
System.out.print("1品牌工厂正在生产A类产品:");
return new ConcreteProductA1();
}
@Override
public AbstractProductB produceB() {
// TODO Auto-generated method stub
System.out.print("1品牌工厂正在生产B类产品:");
return new ConcreteProductB1();
}
}
class ConcreteFactory2 implements AbstractFactory{
//1 品牌产品的专属工厂
@Override
public AbstractProductA produceA() {
// TODO Auto-generated method stub
System.out.print("2品牌工厂正在生产A类产品:");
return new ConcreteProductA2();
}
@Override
public AbstractProductB produceB() {
// TODO Auto-generated method stub
System.out.print("2品牌工厂正在生产B类产品:");
return new ConcreteProductB2();
}
}
四,建造者模式
package CreationalPatterns.Builder;
/*
* 建造者模式是设计模式的一种,将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。
* 什么是复杂对象:
* 就像一栋大楼,这是一个很复杂的东西,有地基,楼体,楼顶等。它可以有不同样式。
/*
* 包含角色:
* 1.Builder(抽象建造者)
* 2.ConcreteBuider(具体建造者)
* 3.Product(产品角色)
* 4.Director(指挥者)
*/
public class Test {
public static void main(String[] args) {
Builder builder=new ConcreteBuilder();
Director director=new Director(builder);
Product product=director.construct();
System.out.println(product.getPartA());
System.out.println(product.getPartB());
System.out.println(product.getPartC());
//我们可以建造不同价格的大楼,通过匿名内部类在这里自定义
Director director2=new Director(new Builder() {
@Override
public Product getResult() {
// TODO Auto-generated method stub
return product;
}
@Override
public void buildPartC() {
// TODO Auto-generated method stub
product.setPartC("100万");
}
@Override
public void buildPartB() {
// TODO Auto-generated method stub
product.setPartB("100万");
}
@Override
public void buildPartA() {
// TODO Auto-generated method stub
product.setPartA("100万");
}
});
Product product2= director2.construct();
System.out.println("下面是一百万的房子");
System.out.println(product2.getPartA());
System.out.println(product2.getPartB());
System.out.println(product2.getPartC());
}
}
class Product{
/*
* ABC三个部分可以是任意类型
* 我们在这里假设A是地基 B是楼体 C是楼顶 建造顺序必须按照ABC的顺序来
*/
private String partA;
private String partB;
private String partC;
//一个具体的产品类模型应该做好封装包含get set 方法
public String getPartA() {
return partA;
}
public String getPartB() {
return partB;
}
public String getPartC() {
return partC;
}
public void setPartA(String partA) {
this.partA = partA;
}
public void setPartB(String partB) {
this.partB = partB;
}
public void setPartC(String partC) {
this.partC = partC;
}
}
interface Builder{
Product product=new Product();
void buildPartA();
void buildPartB();
void buildPartC();
//获得结果的方法
Product getResult();
}
class Director{
private Builder builder;
Director(Builder builder) {
// TODO Auto-generated constructor stub
this.builder=builder;
}
public void setBuilder(Builder builder) {
this.builder = builder;
}
Product construct() {
//这里指定构造顺序
builder.buildPartA();
builder.buildPartB();
builder.buildPartC();
return builder.getResult();
}
}
class ConcreteBuilder implements Builder{
@Override
public void buildPartA() {
// TODO Auto-generated method stub
product.setPartA("这是500万的地基");
}
@Override
public void buildPartB() {
// TODO Auto-generated method stub
product.setPartB("这是500万的楼体");
}
@Override
public void buildPartC() {
// TODO Auto-generated method stub
product.setPartC("这是500万的楼顶");
}
@Override
public Product getResult() {
// TODO Auto-generated method stub
return product;
}
}
五,原型模式
package CreationalPatterns.Prototype;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
/*
* 原型模式(Prototype Pattern)是用于创建重复的对象,
* 同时又能保证性能。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。
这种模式是实现了一个原型接口,该接口用于创建当前对象的克隆。
当直接创建对象的代价比较大时,则采用这种模式。
例如,一个对象需要在一个高代价的数据库操作之后被创建。
我们可以缓存该对象,在下一个请求时返回它的克隆,在需要的时候更新数据库,以此来减少数据库调用。
*/
/*原型模式有两种
* 关键接口 Cloneable 标识当前类 支持类的复制
* 深克隆接口 serialization
* 一个支持序列化的接口,具体使用请百度。
* 1.浅克隆
* ps:不复制其成员对象,也就是说其成员变量都持有相同对象的引用
* 2.深克隆
* ps:连成员对象一起复制,值相同,但其成员对象持有引用不同
*
*/
/*
* 包含角色:
* 1.Prototype(抽象原型类)
* 2.ConcretePrototype(具体原型类)
*/
class Test {
public static void main(String[] args) throws CloneNotSupportedException, ClassNotFoundException, IOException {
Prototype p1=new Prototype();
p1.msg="hahaaaaaaaaaaaaaaaaaaaaaaaa";
//clone的值传递
Prototype p2=(Prototype) p1.clone();
//普通的引用传递
Prototype p3=p1;
//深克隆
Prototype p4=(Prototype) p1.deepClone();
/*
* 可以看到浅克隆下
* 其成员对象没有进行复制,
* 只是传递了引用,p1,p2,p2,指向的都是同一个msg对象
* 另外 还可以手动深克隆,其在克隆对象的成员对象的类中也实现clone方法;
* 在本例中的话便是是msg实现克隆方法
*/
System.out.println("*************************************");
System.out.println("浅克隆");
System.out.println("p1和p2的引用相同么?"+(p1==p2));
System.out.println("p1和p3的引用相同么?"+(p1==p3));
System.out.println("p1和p2 msg的引用相同么?"+(p1.msg==p2.msg));
System.out.println("p1和p3 msg的引用相同么?"+(p1.msg==p3.msg));
System.out.println("*************************************");
System.out.println("*************************************");
System.out.println("深克隆");
System.out.println("深:p1和p4的引用相同么?"+(p1==p4));
System.out.println("浅:p1和p2的引用相同么?"+(p1==p2));
System.out.println("深:p1和p4 msg的引用相同么?"+(p1.msg==p4.msg));
System.out.println("浅:p1和p2 msg的引用相同么?"+(p1.msg==p2.msg));
System.out.println("*************************************");
}
}
/*
* java中多重继承接口的语法不要搞错了
*/
@SuppressWarnings("serial")
class Prototype implements Cloneable,Serializable{
String msg;
//使该类支持克隆方法
@Override
protected Object clone() throws CloneNotSupportedException {
// TODO Auto-generated method stub
return super.clone();
}
//支持深克隆
Object deepClone() throws IOException, ClassNotFoundException {
/*创建一个缓冲流用以缓存
* 此类实现了一个输出流,其中的数据被写入一个 byte 数组。
* 缓冲区会随着数据的不断写入而自动增长。
* 可使用 toByteArray() 和 toString() 获取数据。
*/
ByteArrayOutputStream bos = new ByteArrayOutputStream();
//创建写入指定流的对象流,流中是个经典的装饰模式
ObjectOutputStream oos = new ObjectOutputStream(bos);
//写 当前对象
oos.writeObject(this);
//输入流
ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());
ObjectInputStream ois = new ObjectInputStream(bis);
return ois.readObject();
}
}
六、单例模式
package CreationalPatterns.Singleton;
/*
* 单例模式,是一种常用的软件设计模式。在它的核心结构中只包含一个被称为单例的特殊类。
* 通过单例模式可以保证系统中,应用该模式的类一个类只有一个实例。即一个类只有一个对象实例
*/
/*
* 包含角色
* Singleton(单例类)需要实现单例类的类
* 要点:
* 1.私有构造函数
* 2.提供一个自身的静态私有成员变量,并在类本身给其一个实例化的引用。
* 3.提供一个静态的获得这个变量的方法
*/
class Test {
public static void main(String[] args) {
Singleton1 s1=Singleton1.getSingleton1();
Singleton1 s2=Singleton1.getSingleton1();
Singleton2 s3=Singleton2.getSingleton2();
Singleton2 s4=Singleton2.getSingleton2();
Singleton3 s5=Singleton3.getSingleton3();
Singleton3 s6=Singleton3.getSingleton3();
System.out.println("s1 s2 的引用相同么"+(s1==s2) );
System.out.println("s3 s4 的引用相同么"+(s3==s4) );
System.out.println("s5 s6 的引用相同么"+(s5==s6) );
}
}
//饿汉式 eagerly load(急切地加载)
class Singleton1{
public static Singleton1 singleton1=new Singleton1();
private Singleton1() {}
public static Singleton1 getSingleton1() {
return singleton1;
}
}
//懒汉式 lazy load (延迟加载)
class Singleton2{
public static Singleton2 singleton2;
private Singleton2(){}
public static Singleton2 getSingleton2() {
//线程不安全
if(singleton2!=null) {
return singleton2;
}else {
singleton2=new Singleton2();
return singleton2;
}
}
}
class Singleton3{
//双重判断实现了线程安全
private static volatile Singleton3 singleton3;
private Singleton3() {}
public static Singleton3 getSingleton3() {
if (singleton3 == null) {
synchronized (Singleton3.class) {
if (singleton3 == null) {
singleton3 = new Singleton3();
}
}
}
return singleton3;
}
}
参考资料:
《设计模式》 刘伟主编
菜鸟教程 :http://www.runoob.com/
百度百科