极客大学架构师训练营 框架开发 第三次作业

发布于: 2020 年 06 月 25 日

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

说明:笔者拍照实现饿汉式单例类,也就是应用一启动,就会把单例对象加载到内存。

问什么要试用 Singleton

Singleton 模式保证产生单一实例,就是说一个类只产生一个实例。试用 Singleton 有两个原因

  • 是因为只有一个实例,可以减少实例频繁创建和销毁带来的资源消耗。

  • 是当多个用户试用这个实例的时候,便于进行统一控制(比如打印机对象)。

前者是性能需求,后者是功能需求。

饿汉式 Singleton

public class HungrySingleton {
private static HungrySingleton instance = new HungrySingleton();
private HungrySingleton() {
}
public static HungrySingleton getInstance() {
return instance;
}
}

注意:一定要有私有的构造函数,保证实例只能通过getInstance() 方法获得。

尽量使用饿汉式构造单实例。单例中的成员变量是多线程重用的,可能会产生意想不到的结果,因此尽量将单例设计为无状态对象(只提供服务,不保存状态)。

饿汉式 Singleton 的问题是,应用一启动就加载对象进内存,就算从来未被用过。

懒汉式 Singleton

publci class LazySingleton {
private static LazySingleton instance = null;
private LazySingleton() {
}
public static synchronized LazySingleton getInstance() {
if (instance == null) {
instance = new LazySingleton();
}
return instance;
}
}

注意: getInstance() 的修饰符 synchronized 一定要加上,否则可能会产生多重实例。

懒汉式Singleton解决了饿汉式Singleton,当调用的时候才去加载对象到内存。但是引发了另外一个性能问题,每次访问对象都要加锁。

提升性能的 懒汉式 Singleton

publci class LazySingleton {
private static LazySingleton instance = null;
private LazySingleton() {
}
public static LazySingleton getInstance() {
if (instance == null) {
instance = LazySingleton.buildInstance();
}
return instance;
}
private static synchronized LazySingleton buildInstance() {
if (instance == null) {
instance = new LazySingleton();
}
return instance;
}
}

只有当对象为null的时候,才去加锁创建对象。

2. 请用组合设计模式编写程序

打印输出图 1 的窗口,窗口组件的树结构如图 2 所示,打印输出示例参考图 3。

组合模式的类图:

package structure;
import java.util.ArrayList;
import java.util.List;
interface Item {
void print();
String getName();
void setName(String name);
List<Item> getChilds();
int addChild(Item item);
}
abstract class Component implements Item {
private List<Item> childs = new ArrayList<>();
private String name;
@Override
public String getName() {
return name;
}
@Override
public void setName(String name) {
this.name = name;
}
@Override
public List<Item> getChilds() {
return childs;
}
@Override
public void print() {
String className = this.getClass().getSimpleName();
System.out.println("print " + className + "(" + getName() + ")");
List<Item> childs = getChilds();
for (Item item: childs) {
item.print();
}
}
@Override
public int addChild(Item item) {
List<Item> childs = getChilds();
if (childs == null) {
return 0;
}
if (item != null) {
childs.add(item);
}
return childs.size();
}
}
class WinForm extends Component { }
class Button extends Component { }
class CheckBox extends Component { }
class Frame extends Component { }
class Label extends Component { }
class LinkLabel extends Component { }
class PasswordBox extends Component { }
class Picture extends Component { }
class TextBox extends Component { }
public class Composition {
public static void main(String[] args) throws IllegalAccessException, InstantiationException {
Item mainForm = createChild("WINDOW窗口", WinForm.class);
addChilds(mainForm);
mainForm.print();
}
static <T> Item createChild(String name, Class<T> clazz) throws IllegalAccessException, InstantiationException {
Item child = (Item)clazz.newInstance();
child.setName(name);
return child;
}
static void addChilds(Item mainForm) throws InstantiationException, IllegalAccessException {
mainForm.addChild(createChild("LOGO图片", Picture.class));
mainForm.addChild(createChild("登录", Button.class));
mainForm.addChild(createChild("注册", Button.class));
Item frame = createChild("FRAME1", Frame.class);
mainForm.addChild(frame);
frame.addChild(createChild("用户名", Label.class));
frame.addChild(createChild("文本框", TextBox.class));
frame.addChild(createChild("密码", Label.class));
frame.addChild(createChild("密码框", PasswordBox.class));
frame.addChild(createChild("复选框", CheckBox.class));
frame.addChild(createChild("记住用户名", TextBox.class));
frame.addChild(createChild("忘记密码", LinkLabel.class));
}
}

输出结果

print WinForm(WINDOW窗口)
print Picture(LOGO图片)
print Button(登录)
print Button(注册)
print Frame(FRAME1)
print Label(用户名)
print TextBox(文本框)
print Label(密码)
print PasswordBox(密码框)
print CheckBox(复选框)
print TextBox(记住用户名)
print LinkLabel(忘记密码)

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

John(易筋)

关注

问渠那得清如许?为有源头活水来 2018.07.17 加入

前阿里巴巴资深无线开发,目前汇丰银行专家。客户端架构师,全栈工程师。擅长算法、数据结构、设计模式、iOS、Java、 Spring Boot、Spring Cloud、Docker

评论

发布
暂无评论
极客大学架构师训练营 框架开发 第三次作业