Singleton Pattern是一種軟體設計模式,其目的在於確保一個類別只有一個實例,並提供一個全域唯一的訪問點。
舉例來說,一個應用程式可能需要一個設置管理器(例如全局配置設置),為了確保不會意外地創建多個實例,可以使用Singleton Pattern來確保該設置管理器只有一個實例存在。
以下為一個簡單的Singleton Pattern的範例:
class MySingleton:
__instance = None
def __init__(self):
if MySingleton.__instance != None:
raise Exception("Singleton class, use get_instance() instead")
else:
MySingleton.__instance = self
@staticmethod
def get_instance():
if MySingleton.__instance == None:
MySingleton()
return MySingleton.__instance
在上面的範例中,我們創建了一個Singleton類別MySingleton
,它具有一個私有的實例變量__instance
。
在__init__
函數中,我們檢查實例變量是否為None。如果它不是None,則意味著一個實例已經存在,並引發異常。否則,將__instance
設置為當前的實例。
在get_instance()
方法中,我們檢查實例變量是否為None。如果為None,則創建一個新的MySingleton
實例並設置__instance
。如果不為None,我們直接回傳__instance
即可。
這樣一來,無論如何都只會存在一個MySingleton
實例。
可以透過以下方式獲取MySingleton
實例:
my_singleton = MySingleton.get_instance()
如果嘗試創建更多的實例,即使直接創建實例也會引發異常,因為__instance
變數已被設置為相應的實例。
Singleton模式是一種創建型設計模式,它確保一個類只有一個實例,並提供一個全局訪問點。
Singleton模式需要私有化構造函數,以防止該類被實例化多次。
Singleton模式需要提供一個靜態方法來獲取該類的唯一實例,通常是getInstance()方法。
Singleton的實例通常是延遲加載的,在需要的時候才創建。
Singleton模式提供了一種更好的控制全局狀態的方式,但也具有一些缺點,例如難以測試、可能會導致不必要的耦合等。
Singleton模式有多種實現方式,包括靜態字段、枚舉、內部類等。選擇哪種方式取決於具體需求以及編程語言的特性。
答案:
public class Cache {
private static final long DEFAULT_TIMEOUT = 3600;
private static final int MAX_CAPACITY = 1000;
private static Cache instance;
private Map<String, Object> cacheMap = new HashMap<>();
private Map<String, Long> timeoutMap = new HashMap<>();
private LinkedList<String> keys = new LinkedList<>();
private Cache() {}
public static Cache getInstance() {
if (instance == null) {
synchronized (Cache.class) {
if (instance == null) {
instance = new Cache();
}
}
}
return instance;
}
public void put(String key, Object value, long timeout) {
synchronized (cacheMap) {
if (keys.size() >= MAX_CAPACITY) {
String firstKey = keys.getFirst();
remove(firstKey);
}
cacheMap.put(key, value);
timeoutMap.put(key, System.currentTimeMillis() + timeout);
keys.add(key);
}
}
public void put(String key, Object value) {
put(key, value, DEFAULT_TIMEOUT);
}
public Object get(String key) {
synchronized (cacheMap) {
if (!cacheMap.containsKey(key)) {
return null;
}
if (timeoutMap.get(key) < System.currentTimeMillis()) {
remove(key);
return null;
}
return cacheMap.get(key);
}
}
public void remove(String key) {
synchronized (cacheMap) {
cacheMap.remove(key);
timeoutMap.remove(key);
keys.remove(key);
}
}
public void cleanup() {
synchronized (cacheMap) {
Iterator<String> it = keys.iterator();
while (it.hasNext()) {
String key = it.next();
if (timeoutMap.get(key) < System.currentTimeMillis()) {
it.remove();
cacheMap.remove(key);
timeoutMap.remove(key);
}
}
}
}
}
答案:
public class ConfigurationManager {
private static ConfigurationManager instance;
private Map<String, String> config = new HashMap<>();
private DateFormat dateFormat = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
private ConfigurationManager() {}
public static ConfigurationManager getInstance() {
if (instance == null) {
synchronized (ConfigurationManager.class) {
if (instance == null) {
instance = new ConfigurationManager();
}
}
}
return instance;
}
public synchronized boolean load(String filename) {
try {
// read config file
Properties properties = new Properties();
try (InputStream input = new FileInputStream(filename)) {
properties.load(input);
}
// parse config file
for (String name : properties.stringPropertyNames()) {
String value = properties.getProperty(name);
config.put(name, value);
}
// record last modified time
File configFile = new File(filename);
config.put("last_modified_time", dateFormat.format(configFile.lastModified()));
return true;
} catch (IOException e) {
System.err.println("Failed to load configuration file: " + filename);
return false;
}
}
public synchronized boolean save(String filename) {
try {
// write config file
Properties properties = new Properties();
for (Map.Entry<String, String> entry : config.entrySet()) {
properties.setProperty(entry.getKey(), entry.getValue());
}
try (OutputStream output = new FileOutputStream(filename)) {
properties.store(output, /* comments = */ null);
}
// record last modified time
File configFile = new File(filename);
config.put("last_modified_time", dateFormat.format(configFile.lastModified()));
return true;
} catch (IOException e) {
System.err.println("Failed to save configuration file: " + filename);
return false;
}
}
public synchronized String get(String name) {
return config.get(name);
}
public synchronized void set(String name, String value) {
config.put(name, value);
}
public synchronized String getLastModifiedTime() {
return config.get("last_modified_time");
}
}
答案:
public class ChartTool {
private static ChartTool instance;
private ChartTool() {}
public static ChartTool getInstance() {
if (instance == null) {
synchronized (ChartTool.class) {
if (instance == null) {
instance = new ChartTool();
}
}
}
return instance;
}
public void drawLineChart(List<XYPoint> points, Color color, String title) {
// draw line chart
}
public void drawBarChart(List<XYPoint> points, Color color, String title) {
// draw bar chart
}
// add other drawing methods as needed
public void setFont(Font font) {
// set font
}
public void setColor(Color color) {
// set color
}
public void setTitle(String title) {
// set title
}
public void addCurve(List<XYPoint> points, Color color) {
// add curve
}
public void addLabel(String text, XYPoint position) {
// add label
}
}
答案:
public class LogManager {
private static LogManager instance;
private List<LogOutput> logOutputs = new ArrayList<>();
private LogLevel logLevel = LogLevel.INFO;
private LogManager() {}
public static LogManager getInstance() {
if (instance == null) {
synchronized (LogManager.class) {
if (instance == null) {
instance = new LogManager();
}
}
}
return instance;
}
public void addLogOutput(LogOutput logOutput) {
logOutputs.add(logOutput);
}
public void setLogLevel(LogLevel logLevel) {
this.logLevel = logLevel;
}
public void debug(String message) {
log(LogLevel.DEBUG, message);
}
public void info(String message) {
log(LogLevel.INFO, message);
}
public void warn(String message) {
log(LogLevel.WARN, message);
}
public void error(String message) {
log(LogLevel.ERROR, message);
}
private void log(LogLevel level, String message) {
if (level.compareTo(logLevel) >= 0) {
String formattedMessage = String.format("%s [%s] %s",
new Date(), level.toString(), message);
for (LogOutput logOutput : logOutputs) {
logOutput.write(formattedMessage);
}
}
}
}
public interface LogOutput {
void write(String message);
}
public enum LogLevel {
DEBUG, INFO, WARN, ERROR;
}
答案:
public class ShoppingCart {
private static ShoppingCart instance;
private List<Item> items = new ArrayList<>();
private ShoppingCart() {}
public static ShoppingCart getInstance() {
if (instance == null) {
synchronized (ShoppingCart.class) {
if (instance == null) {
instance = new ShoppingCart();
}
}
}
return instance;
}
public void addItem(Item item) {
items.add(item);
}
public void removeItem(Item item) {
items.remove(item);
}
public void updateItemQuantity(Item item, int quantity) {
item.setQuantity(quantity);
}
public List<Item> getItems() {
return Collections.unmodifiableList(items);
}
public double getTotalPrice() {
return items.stream()
.mapToDouble(item -> item.getPrice() * item.getQuantity())
.sum();
}
public void saveToDatabase() {
// save items to database
}
}
public class Item {
private String id;
private String name;
private double price;
private int quantity;
public Item(String id, String name, double price, int quantity) {
this.id = id;
this.name = name;
this.price = price;
this.quantity = quantity;
}
// getters and setters
}