工厂模式
1.简单工厂模式(静态工厂模式)
1.不向客户端暴露创建对象逻辑,提供公共接口指向创建的对象
2.调用者创建对象,只需要知道该对象的名称
3.每次增加产品都要增加具体产品类和工厂类中else-if,不满足开闭原则,工厂方法模式解决该问题,但一般情况下简单工厂模式使用的较多
- 类图
- 讲解
1.实现Shape接口实现Shape接口的实体类
2.定义工厂类ShapeFactory,根据传入的类型名创建Shape的具体实现类
3.FactoryPatternDemo类使用ShapeFactory来获取Shape对象,它将向ShapeFactory传递信息
public interface Shape{
void draw();
}
public class Circle implements Shape {
@Override
public void draw() {
System.out.println("Circle-draw");
}
}
public class Square implements Shape {
@Override
public void draw() {
System.out.println("Square-draw");
}
}
public class Rectangle implements Shape{
@Override
public void draw() {
System.out.println("Rectangle-draw");
}
}
public class ShapeFactory {
public Shape getShape(String shapeType){
if(shapeType == null) return null;
if(shapeType.equalsIgnoreCase("CIRCLE")){
return new Circle();
} else if(shapeType.equalsIgnoreCase("RECTANGLE")){
return new Rectangle();
} else if(shapeType.equalsIgnoreCase("SQUARE")){
return new Square();
}
return null;
}
}
----------------------------------------
main(){
Shape circle1 = new Circle();
Shape square1 = new Square();
Shape rectangle1 = new Rectangle();
circle1.draw();
square1.draw();
rectangle1.draw();
----------------------
Shape circle2 = ShapeFactory.getShape("Circle");
Shape square2 = ShapeFactory.getShape("Square");
Shape rectangle2 = ShapeFactory.getShape("Rectangle");
circle2.draw();
square2.draw();
rectangle2.draw();
}
2.工厂方法模式
1.解决简单工厂不满足开闭原则的问题,每次增加产品只需扩展相应的产品工厂实现工厂类即可
2.在简单工厂基础上对每个产品建立对应的工厂实现类来创建对应的产品
3.类的数量大大增加
- 类图
- 实现
public interface Shape{
void draw();
}
public class Circle implements Shape {
@Override
public void draw() {
System.out.println("Circle-draw");
}
}
public class Square implements Shape {
@Override
public void draw() {
System.out.println("Square-draw");
}
}
public class Rectangle implements Shape{
@Override
public void draw() {
System.out.println("Rectangle-draw");
}
}
public interface ShapeFactory {
Shape getShape();
}
public class CircleFactory implements ShapeFactory {
@Override
public Shape getShape() {
return new Circle();
}
}
public class RectangleFactory implements ShapeFactory {
@Override
public Shape getShape() {
return new Circle();
}
}
public class SquareFactory implements ShapeFactory {
@Override
public Shape getShape() {
return new Square();
}
}
----------------------------------------
main(){
Shape circle1 = new CircleFactory().getShape();
Shape square1 = new SquareFactory().getShape();
Shape rectangle1 = new RectangleFactory().getShape();
circle1.draw();
square1.draw();
rectangle1.draw();
}
1.结构复杂度:simple
2.代码复杂度:simple
3.编程复杂度:simple
4.管理复杂度:simple
根据设计模式:工厂方法模式
根据实际业务:简单工厂模式
学习思想,不一定满足设计原则,但是实际应用的更多
3.抽象工厂模式
1.围绕超级工厂创建其他工厂(工厂的工厂),接口主要负责创建相应对象的工厂,但上边两种模式是创建产品的
2.无需关心创建细节,将同一系列产品一起创建
3.违反开闭原则,产品稳定的话使用抽象工厂更佳,否则难以维护,不如使用简单工厂模式
- 区分产品族与产品等级
- 类图
- 实现
public interface IphoneProduct {
void start();
void shutdown();
void call();
}
public interface IrouterProduct {
void start();
void shutdown();
void openwifi();
}
public class XiaomiPhone implements IphoneProduct {
@Override
public void start() {
System.out.println("小米手机开机");
}
@Override
public void shutdown() {
System.out.println("小米手机关机");
}
@Override
public void call() {
System.out.println("小米手机打电话");
}
}
public class HuaweiPhone implements IphoneProduct {
@Override
public void start() {
System.out.println("华为手机开机");
}
@Override
public void shutdown() {
System.out.println("华为手机关机");
}
@Override
public void call() {
System.out.println("华为手机打电话");
}
}
public class XiaomiRouter implements IrouterProduct {
@Override
public void start() {
System.out.println("小米路由器开机");
}
@Override
public void shutdown() {
System.out.println("小米路由器关机");
}
@Override
public void openwifi() {
System.out.println("小米路由器打开WiFi");
}
}
public class HuaweiRouter implements IrouterProduct {
@Override
public void start() {
System.out.println("华为路由器开机");
}
@Override
public void shutdown() {
System.out.println("华为路由器关机");
}
@Override
public void openwifi() {
System.out.println("华为路由器打开WiFi");
}
}
public interface AbstractProductFactory {
IphoneProduct iphoneProduct();
IrouterProduct irouterProduct();
}
public class XiaomiFactory implements AbstractProductFactory {
@Override
public IphoneProduct iphoneProduct() {
return new XiaomiPhone();
}
@Override
public IrouterProduct irouterProduct() {
return new XiaomiRouter();
}
}
public class HuaweiFactory implements AbstractProductFactory {
@Override
public IphoneProduct iphoneProduct() {
return new HuaweiPhone();
}
@Override
public IrouterProduct irouterProduct() {
return new HuaweiRouter();
}
}
----------------------------------------
main(){
System.out.println("===小米系列===");
XiaomiFactory xiaomiFactory = new XiaomiFactory();
IphoneProduct xiaomiPhone = xiaomiFactory.iphoneProduct();
xiaomiPhone.start();
IrouterProduct xiaomiRouter = xiaomiFactory.irouterProduct();
xiaomiRouter.start();
System.out.println("===华为系列===");
HuaweiFactory huaweiFactory = new HuaweiFactory();
IphoneProduct huaweiPhone = huaweiFactory.iphoneProduct();
huaweiPhone.start();
IrouterProduct huaweiRouter = huaweiFactory.irouterProduct();
huaweiRouter.start();
}
建造者模式
1.用于构建复杂对象,子对象常由算法构成,由于需求变化,复杂对象的各个子对象面临剧烈变化,但将子对象组合的算法相对稳定
2.将变与不变分离,符合开闭原则
3.产品差异较大就不能使用,适用于有较多属性(零件)的对象(产品)的创建过程
- 类图
- 讲解
盖房子需要建筑公司或承包商(指挥者),承包商指挥工人(具体建造者)怎样造房子
public class Product {
private String buildA;
private String buildB;
private String buildC;
private String buildD;
set+get
}
public abstract class Buider {
abstract void buildA();
abstract void buildB();
abstract void buildC();
abstract void buildD();
abstract Product getProduct();
}
public class Worker extends Buider {
private Product product;
public Worker() {
this.product = new Product();
}
@Override
void buildA() {
product.setBuildA("地基");
System.out.println("地基");
}
@Override
void buildB() {
product.setBuildB("钢筋");
System.out.println("钢筋");
}
@Override
void buildC() {
product.setBuildC("电线");
System.out.println("电线");
}
@Override
void buildD() {
product.setBuildD("粉刷");
System.out.println("粉刷");
}
@Override
public Product getProduct() {
return product;
}
}
public class Director {
public Product build(Buider buider) {
buider.buildA();
buider.buildB();
buider.buildC();
buider.buildD();
return buider.getProduct();
}
}
----------------------------------------
main(){
Director director = new Director();
Product product = director.build(new Worker());
System.out.println(product.toString());
}
public class Product {
private String buildA = "汉堡";
private String buildB = "可乐";
private String buildC = "薯条";
private String buildD = "甜点";
set/get
}
public abstract class Buider {
abstract Buider buildA(String msg);
abstract Buider buildB(String msg);
abstract Buider buildC(String msg);
abstract Buider buildD(String msg);
abstract Product getProduct();
}
public class Worker extends Buider {
private Product product;
public Worker() {
this.product = new Product();
}
@Override
Buider buildA(String msg) {
product.setBuildA(msg);
return this;
}
@Override
Buider buildB(String msg) {
product.setBuildB(msg);
return this;
}
@Override
Buider buildC(String msg) {
product.setBuildC(msg);
return this;
}
@Override
Buider buildD(String msg) {
product.setBuildD(msg);
return this;
}
@Override
public Product getProduct() {
return product;
}
}
----------------------------------------
main(){
Worker worker = new Worker();
Product product = worker.getProduct();
System.out.println(product.toString());
System.out.println("===================");
product = worker.buildA("全家桶").buildB("雪碧").getProduct();
System.out.println(product.toString());
}
原型模式
1.创建重复对象的同时保证性能
2.原型对象用于创建该对象的克隆,因为直接创建对象的代价太大,克隆对象在运行期间创建和删除
- 实现—浅拷贝
public class Video implements Cloneable {
private String name;
private Date createTime;
@Override
protected Object clone() throws CloneNotSupportedException {
return super.clone();
}
}
- 实现—深拷贝
public class Video implements Cloneable {
private String name;
private Date createTime;
@Override
protected Object clone() throws CloneNotSupportedException {
Video video = (Video) super.clone();
video.createTime = (Date) this.createTime.clone();
return video;
}
}
public class Bilibili {
public static void main(String[] args) throws CloneNotSupportedException, InterruptedException {
Date date = new Date();
Video prototype = new Video("狂神说", date);
System.out.println("原型:" + prototype);
System.out.println("hash:" + prototype.hashCode());
Video clone = (Video) prototype.clone();
System.out.println("克隆:" + clone);
System.out.println("hash:" + clone.hashCode());
clone.setName("我的视频");
System.out.println(clone);
System.out.println();
date.setTime(311565611);
System.out.println("原型:" + prototype);
System.out.println("克隆:" + clone);
}
}