写点什么

架构师训练营第三周作业

用户头像
Jerry Tse
关注
发布于: 2020 年 06 月 24 日

题目一:

请在草稿纸上手写一个单例模式的实现代码,拍照提交作业。

作答:

写法比较多,就写两种吧,平时基本上就用这两种。两种都是现成安全的。

1. 双检测写法



这里提一点,有些人会在 instance 变量上加 volatile 修饰符,其实是非必须,synchronized 关键字已经保证了 instance 变量的可见性和 synchronized 代码段中包含代码段的原子性。


如果加上 volatile,保证了 instance 的可见性。避免这样一种情况:某个线程已经为 instance 赋值,而另一个线程因 instance 可见性问题没有看到 instance 最新的值,再次通过了第一次 instance 为空判断的语句。但就像上面所说,及时通过了第一次 instance 为空判断,进入 synchronized 代码段后还有一次为空判断,依然线程安全。


但上面那种情况发生概率不大,即使发生了也没有同步问题。volatile 修饰略显多余。


2.静态内部类写法


Sigleton 类加载的时候,内部的 SigletonHolder 类不会被加载,只有在调用 getInstance 方法的时候 SigletonHolder 才会被加载并初始化,且由 classloader 保证了线程安全。

题目二:

请用组合设计模式编写程序,打印输出图 1 的窗口,窗口组件的树结构如图 2 所示,打印输出示例参考下图。


作答:

1. 类图:



  • 定义一个 Component 接口,Composite 和 Leaf 这个接口。

  • Composite 表示组合节点,可以包含其他节点的节点,Leaf 表示叶子节点,叶子节点不能包含其他节点了。感觉这样会违反 LSP,但是也没有想到更好的实现。

  • Composite 有一个 Component 类型的容器成员变量,就是它支持了 Composite 可以包含其他节点的能力。

  • ComponentType 其实是个枚举,表示节点的类型。不属于组合模式的类。

2. 代码

2.1 Component 接口

public interface Component {    void add(Component component);    void print();}
复制代码

2.2 ComponentType 枚举类

public enum ComponentType {    WinForm,Picture,Button,Frame,Lable,TextBox,PasswordBox,CheckBox,LinkLable}
复制代码


2.3 Composite 组合节点类

public class Composite implements Component {    private List<Component> components;    private String name;    private ComponentType type;
public Composite(String name, ComponentType type) { this.components = new ArrayList<Component>(); this.name = name; this.type = type; }
@Override public void add(Component component) { components.add(component); }
@Override public void print() { System.out.println(String.format("print %s(%s)",type.name(),name)); for (Component component:components) { component.print(); } }}
复制代码


2.4 Leaf 叶子节点类

public class Leaf implements Component {    private String name;    private ComponentType type;
public Leaf(String name, ComponentType type) { this.name = name; this.type = type; }
@Override public void add(Component component) { throw new UnsupportedOperationException(); } @Override public void print() { System.out.println(String.format("print %s(%s)",type.name(),name)); }}
复制代码


2.5 Client 应用程序类

public class Client {    public static void main(String[] args) {        Component winForm=new Composite("WINDOW窗口",ComponentType.WinForm);        Component picture=new Leaf("LOGO窗口",ComponentType.Picture);        Component button1=new Leaf("登录",ComponentType.Button);        Component button2=new Leaf("注册",ComponentType.Button);        Component frame=new Composite("FRAME1",ComponentType.Frame);        Component lable1=new Leaf("用户名",ComponentType.Lable);        Component textBox1=new Leaf("文本框",ComponentType.TextBox);        Component lable2=new Leaf("密码",ComponentType.Lable);        Component passwordBox=new Leaf("密码框",ComponentType.PasswordBox);;        Component checkBox=new Leaf("复选框",ComponentType.CheckBox);        Component textBox2=new Leaf("记住用户名",ComponentType.TextBox);        Component linkLable=new Leaf("忘记密码",ComponentType.LinkLable);        frame.add(lable1);        frame.add(textBox1);        frame.add(lable2);        frame.add(passwordBox);        frame.add(checkBox);        frame.add(textBox2);        frame.add(linkLable);        winForm.add(picture);        winForm.add(button1);        winForm.add(button2);        winForm.add(frame);        winForm.print();    }}
复制代码


发布于: 2020 年 06 月 24 日阅读数: 60
用户头像

Jerry Tse

关注

还未添加个人签名 2018.11.02 加入

还未添加个人简介

评论

发布
暂无评论
架构师训练营第三周作业