趣学Java设计模式

一 工厂方法模式

1.解决的问题

将创建具体类的工作统一交给工厂来做,别的类概不负责。

2.类图

这里写图片描述

3.对应类图源码

/**
 * 蛋糕接口 
 */
public interface Cake {
}

/**
 * 奶油蛋糕
 */
public class CreamCake implements Cake {
}

/**
 * 水果蛋糕
 */
public class FruitCake implements Cake {
}

/**
 * 蛋糕工厂
 */
public class CakeFactory {
    /*
     * 创建水果蛋糕
     */
    public Cake createFruitCake(){
        return new FruitCake();
    }
    /*
     * 创建奶油蛋糕
     */
    public Cake createCreamCake(){
        return new CreamCake();
    }
}

/**
 *客户端调用
 */
 public class Client {
    public static void main(String[] args) {
        CakeFactory factory = new CakeFactory();
        Cake fruitcake = factory.createFruitCake();
        Cake creamCake = factory.createCreamCake();
    }
}

4.变体:静态工厂方法

将工厂中的方法修改为静态的,则变体为静态工厂方法。
/**
 * 蛋糕工厂
 */
public class CakeFactory {
    /*
     * 创建水果蛋糕
     */
    public static Cake createFruitCake(){
        return new FruitCake();
    }
    /*
     * 创建奶油蛋糕
     */
    public static Cake createCreamCake(){
        return new CreamCake();
    }
}

/**
 *客户端调用
 */
public class Client {
    public static void main(String[] args) {
        Cake fruitcake = CakeFactory.createFruitCake();
        Cake creamCake = CakeFactory.createCreamCake();
    }
}

二 抽象工厂模式

1.解决的问题

在遵守开闭原则的情况下,使用工厂方法,可以动态的创建新的产品而不需要改动工厂类。

2.类图

这里写图片描述

3.对应类图源码

注:蛋糕、水果蛋糕、奶油蛋糕与工厂方法相同。
/**
 * 蛋糕工厂
 */
public interface AbstractCakeFactory {
    /*
     * 制造蛋糕
     */
    public Cake makeCake();
}

/**
 * 水果蛋糕工厂
 */
public class FruitCakeFactory implements AbstractCakeFactory {
    @Override
    public Cake makeCake() {
        /*
         * 创建水果蛋糕
         */
        return new FruitCake();
    }
}

/**
 * 奶油蛋糕工厂
 */
public class CreamCakeFactory implements AbstractCakeFactory {
    @Override
    public Cake makeCake() {
        /*
         * 创建奶油蛋糕
         */
        return new CreamCake();
    }
}

public class Client {
    public static void main(String[] args) {
        //想要水果蛋糕,先造一个水果蛋糕工厂,制出来的就是水果蛋糕
        AbstractCakeFactory fruitfactory = new FruitCakeFactory();
        fruitfactory.makeCake();

        //想要奶油蛋糕,先造一个奶油蛋糕工厂,制出来的就是奶油蛋糕
        AbstractCakeFactory creamfactory = new CreamCakeFactory();
        creamfactory.makeCake();
    }
}

三 单例模式

1.解决的问题

让整个系统中只有一个实例,就像一个国家只能有一个皇帝。

2.源码一(双重锁检查写法)

/**
 * 皇帝单例
 */
public class Emperor {
    //构造器私有
    private Emperor(){}
    //实例私有
    private static Emperor instance;

    public static Emperor getEmperor(){
        if(null == instance){
            synchronized(instance){
                if(null == instance){
                    instance = new Emperor();
                }
            }
        }
        return instance;
    }
}

注:也有人把同步块抽取出一个方法来,这里不加赘述。

3.源码二(内部类写法)

/**
 * 皇帝单例
 */
public class Emperor {
    //构造器私有
    private Emperor(){}
    //私有内部类
    private static class EmperorVoter{
        private static Emperor instance = new Emperor();
    }

    public static Emperor getEmperor(){
        return EmperorVoter.instance;
    }
}

4.源码三(枚举写法)

/**
 * 皇帝单例
 */
public enum Emperor {
    INSTANCE
}

四 建造者模式

1.解决的问题

使用建造者可以实现产品的定制化功能。

2.类图

这里写图片描述

3.源码

/**
 * 可定制的蛋糕 
 */
public class ChosenCake {
    //豆沙
    private String dousha;
    //水果块
    private String shuiguo;

    public String getDousha() {
        return dousha;
    }
    public void setDousha(String dousha) {
        this.dousha = dousha;
    }
    public String getShuiguo() {
        return shuiguo;
    }
    public void setShuiguo(String shuiguo) {
        this.shuiguo = shuiguo;
    }
}

/**
 * 蛋糕制作者
 */
public interface CakeMaker {
    /*
     * 加豆沙
     */
    public void addDousha();
    /*
     * 加水果块儿
     */
    public void addShuiguo();
    /*
     * 交付蛋糕
     */
    public ChosenCake finishCake();
}

/**
 * 蛋糕师傅
 */
public class CakeMaster implements CakeMaker {

    //默认制作一个什么都不加的蛋糕
    private ChosenCake cake = new ChosenCake();

    @Override
    public void addDousha() {
        cake.setDousha("按您的要求加入了===豆沙===");
    }

    @Override
    public void addShuiguo() {
        cake.setShuiguo("按您的要求加入了===水果块儿===");
    }
    @Override
    public ChosenCake finishCake(){
        return cake;
    }
}

/**
 * 客人
 */
public class Guest {
    public static void main(String[] args) {
        //选一个蛋糕师傅
        CakeMaker maker = new CakeMaster();
        //给我加点儿豆沙
        maker.addDousha();
        //给我加点儿水果块
        maker.addShuiguo();
        //把蛋糕给我吧
        ChosenCake cake = maker.finishCake();
    }
}

五 原型模式

1.解决的问题

不同程度的来复用已有的对象(深复用、潜复用)。

2.类图

这里写图片描述

3.对应类图源码

/**
  * 开保险箱的方法
  */
public interface OpenBox extends Cloneable{
    /*
     * 告诉你密码你就可以开(浅复制)
     */
    public Object getPassword();
    /*
     * 配钥匙才可以开(深复制) 
     */
    public Object copyKey();
}

/**
 * 会开保险箱的人 
 */
public class BoxOpener implements OpenBox{
    /*
     * 浅复制,相当于你知道密码了,大家使用的都是同一串密码
     */
    @Override
    public Object getPassword() {
        BoxOpener opener = null;
        try {
            opener = (BoxOpener)super.clone();
        } catch (CloneNotSupportedException e) {
            e.printStackTrace();
        }
        return opener;
    }

    /*
     * 深复制,相当于你配了一把钥匙,用的不是一个东西
     */
    @Override
    public Object copyKey() {
        BoxOpener opener = null;
        try {
            ByteArrayOutputStream baos = new ByteArrayOutputStream();
            ObjectOutputStream oos = new ObjectOutputStream(baos);
            oos.writeObject(this);

            ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
            ObjectInputStream ois = new ObjectInputStream(bais);
            opener = (BoxOpener) ois.readObject();

        } catch (Exception e) {
            e.printStackTrace();
        }
        return opener;
    }
}

/**
 * 测试流程
 */
public class Test {
    public static void main(String[] args) {
        //保险箱有一个管理者
        OpenBox boxKeeper = new BoxOpener();
        //领导要开保险箱(浅复制)
        OpenBox leader = (OpenBox)boxKeeper.getPassword();
        //来了一个新管理员,配把钥匙(深复制)
        OpenBox newKeeper = (OpenBox)boxKeeper.copyKey();
    }
}

六 适配器模式

1.解决的问题

用来消除由于接口不匹配所造成的类的兼容性问题。

2.类扩展适配器

这里写图片描述

3.类扩展适配器源码

public class TriphaseBoard {
    /*
     * 有三相插口
     */
    public boolean hasTriphase(){
        System.out.println("==三相插板自带三相输出==");
        return true;
    }
}

/**
 * 多功能插口
 */
public interface MultiSocket {
    /*
     * 有三相插口
     */
    public boolean hasTriphase();
    /*
     * 有两相插口
     */
    public boolean hasTwoPhase();
}

public class MultiPhaseBoard extends TriphaseBoard implements MultiSocket{
    /*
     * 有两相插口
     */
    public boolean hasTwoPhase(){
        System.out.println("==多功能插板实现两口的功能==");
        return true;
    }
}

/**
 * 测试流程
 */
public class Test {
    public static void main(String[] args) {
        MultiSocket board = new MultiPhaseBoard();
        board.hasTriphase();
        board.hasTwoPhase();
    }
}

4.对象扩展适配器

这里写图片描述

5.对象扩展适配器源码

/**
 * 功能要求
 */
public interface FunctionInterface {
    /*
     * 能做软件
     */
    public boolean canDoSoft();
    /*
     * 能修硬件
     */
    public boolean canFixhardward();
}

/**
 * 软件公司
 */
public class SoftwareCompany {
    public boolean canDoSoft(){
        System.out.println("软件公司专业做软件");
        return true;
    }
}

/**
 * 硬件公司
 */
public class HardwareCompany implements FunctionInterface{
    //外包一家软件公司
    private SoftwareCompany softwareCompany;

    public HardwareCompany(SoftwareCompany softwareCompany){
        this.softwareCompany = softwareCompany;
    }
    /*
     * 用软件公司做软件
     */
    @Override
    public boolean canDoSoft() {
        return softwareCompany.canDoSoft();
    }
    /*
     * 自己修硬件
     */
    @Override
    public boolean canFixhardward() {
        System.out.println("我是硬件公司修硬件没问题");
        return true;
    }
}

/**
 * 测试流程
 */
public class Test {
    public static void main(String[] args) {
        FunctionInterface function = new HardwareCompany(new SoftwareCompany());
        function.canDoSoft();
        function.canFixhardward();
    }
}

6.接口适配器

这里写图片描述

7.接口适配器源码

/**
 * 多方法接口
 */
public interface MultiMethod {
    public void method1();
    public void method2();
    public void method3();
    public void methodN();
}

/**
 * 抽象类为所有接口方法提供空实现
 */
public class AbstractMultiMethod implements MultiMethod {
    @Override
    public void method1() {}
    @Override
    public void method2() {}
    @Override
    public void method3() {}
    @Override
    public void methodN() {}
}

/**
 * 只用方法1的类
 */
public class UserMethod1 extends AbstractMultiMethod{
    @Override
    public void method1() {
        System.out.println("我只用这个方法,我就重写这个方法就可以了");
    }
}

/**
 * 只用方法N的类
 */
public class UserMethodN extends AbstractMultiMethod{

    @Override
    public void methodN() {
        System.out.println("我只用这个方法,我就重写这个方法就可以了");
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值