mirror of
https://github.com/LCTT/TranslateProject.git
synced 2025-01-25 23:11:02 +08:00
Merge remote-tracking branch 'LCTT/master'
This commit is contained in:
commit
aab0b84132
364
sources/tech/20190715 Understanding software design patterns.md
Normal file
364
sources/tech/20190715 Understanding software design patterns.md
Normal file
@ -0,0 +1,364 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: ( )
|
||||
[#]: reviewer: ( )
|
||||
[#]: publisher: ( )
|
||||
[#]: url: ( )
|
||||
[#]: subject: (Understanding software design patterns)
|
||||
[#]: via: (https://opensource.com/article/19/7/understanding-software-design-patterns)
|
||||
[#]: author: (Bryant Son https://opensource.com/users/brsonhttps://opensource.com/users/erezhttps://opensource.com/users/brson)
|
||||
|
||||
Understanding software design patterns
|
||||
======
|
||||
Design patterns help eliminate redundant coding. Learn how to use the
|
||||
singleton pattern, factory pattern, and observer pattern using Java.
|
||||
![clouds in the sky with blue pattern][1]
|
||||
|
||||
If you are a programmer or a student pursuing computer science or a similar discipline, sooner or later, you will encounter the term "software design pattern." According to Wikipedia, _"a [software design pattern][2] is a general, reusable solution to a commonly occurring problem within a given context in software design."_ Here is my take on the definition: When you have been working on a coding project for a while, you often begin to think, "Huh, this seems redundant. I wonder if I can change the code to be more flexible and accepting of changes?" So, you begin to think about how to separate what stays the same from what needs to change often.
|
||||
|
||||
> A **design pattern** is a way to make your code easier to change by separating the part that stays the same and the part that needs constant changes.
|
||||
|
||||
Not surprisingly, everyone who has worked on a programming project has probably had the same thought. Especially for any industry-level project, where it's common to work with dozens or even hundreds of developers; the collaboration process suggests that there have to be some standards and rules to make the code more elegant and adaptable to changes. That is why we have [object-oriented programming][3] (OOP) and [software framework tools][4]. A design pattern is somewhat similar to OOP, but it goes further by considering changes as part of the natural development process. Basically, the design pattern leverages some ideas from OOP, like abstractions and interfaces, but focuses on the process of changes.
|
||||
|
||||
When you start to work on a project, you often hear the term _refactoring_, which means _to change the code to be more elegant and reusable;_ this is where the design pattern shines. Whenever you're working on existing code (whether built by someone else or your past self), knowing the design patterns helps you begin to see things differently—you will discover problems and ways to improve the code.
|
||||
|
||||
There are numerous design patterns, but three popular ones, which I'll present in this introductory article, are singleton pattern, factory pattern, and observer pattern.
|
||||
|
||||
### How to follow this guide
|
||||
|
||||
I want this tutorial to be as easy as possible for anyone to understand, whether you are an experienced programmer or a beginner to coding. The design pattern concept is not exactly easy to understand, and reducing the learning curve when you start a journey is always a top priority. Therefore, in addition to this article with diagrams and code pieces, I've also created a [GitHub repository][5] you can clone and run the code to implement the three design patterns on your own. You can also follow along with the following [YouTube video][6] I created.
|
||||
|
||||
#### Prerequisites
|
||||
|
||||
If you just want to get the idea of design patterns in general, you do not need to clone the sample project or install any of the tools. However, to run the sample code, you need to have the following installed:
|
||||
|
||||
* **Java Development Kit (JDK):** I highly recommend [OpenJDK][7].
|
||||
* **Apache Maven:** The sample project is built using [Apache Maven][8]; fortunately, many IDEs come with Maven installed.
|
||||
* **Interactive development editor (IDE):** I use [IntelliJ Community Edition][9], but you can use [Eclipse IDE][10] or any other Java IDE of your choice
|
||||
* **Git:** If you want to clone the project, you need a [Git][11] client.
|
||||
|
||||
|
||||
|
||||
To clone the project and follow along, run the following command after you install Git:
|
||||
|
||||
|
||||
```
|
||||
`git clone https://github.com/bryantson/OpensourceDotComDemos.git`
|
||||
```
|
||||
|
||||
Then, in your favorite IDE, you can import the code in the TopDesignPatterns repo as an Apache Maven project.
|
||||
|
||||
I am using Java, but you can implement the design pattern using any programming language that supports the [abstraction principle][12].
|
||||
|
||||
### Singleton pattern: Avoid creating an object every single time
|
||||
|
||||
The [singleton pattern][13] is a very popular design pattern that is also relatively simple to implement because you need just one class. However, many developers debate whether the singleton design pattern's benefits outpace its problems because it lacks clear benefits and is easy to abuse. Few developers implement singleton directly; instead, programming frameworks like Spring Framework and Google Guice have built-in singleton design pattern features.
|
||||
|
||||
But knowing about singleton is still tremendously useful. The singleton pattern makes sure that a class is created only once and provides a global point of access to it.
|
||||
|
||||
> **Singleton pattern:** Ensures that only one instantation is created and avoids creating multiple instances of the same object.
|
||||
|
||||
The diagram below shows the typical process for creating a class object. When the client asks to create an object, the constructor creates, or instantiates, an object and returns to the class with the caller method. However, this happens every single time an object is requested—the constructor is called, a new object is created, and it returns with a unique object. I guess the creators of the OOP language had a reason behind creating a new object every single time, but the proponents of the singleton process say this is redundant and a waste of resources.
|
||||
|
||||
![Normal class instantiation][14]
|
||||
|
||||
The following diagram creates the object using the singleton pattern. Here, the constructor is called only when the object is requested the first time through a designated getInstance() method. This is usually done by checking the null value, and the object is saved inside the singleton class as a private field value. The next time the getInstance() is called, the class returns the object that was created the first time. No new object is created; it just returns the old one.
|
||||
|
||||
![Singleton pattern instantiation][15]
|
||||
|
||||
The following script shows the simplest possible way to create the singleton pattern:
|
||||
|
||||
|
||||
```
|
||||
package org.opensource.demo.singleton;
|
||||
|
||||
public class OpensourceSingleton {
|
||||
|
||||
private static OpensourceSingleton uniqueInstance;
|
||||
|
||||
private OpensourceSingleton() {
|
||||
}
|
||||
|
||||
public static OpensourceSingleton getInstance() {
|
||||
if (uniqueInstance == null) {
|
||||
uniqueInstance = new OpensourceSingleton();
|
||||
}
|
||||
return uniqueInstance;
|
||||
}
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
On the caller side, here is how the singleton class will be called to get an object:
|
||||
|
||||
|
||||
```
|
||||
Opensource newObject = Opensource.getInstance();
|
||||
```
|
||||
|
||||
This code demonstrates the idea of a singleton well:
|
||||
|
||||
1. When getInstance() is called, it checks whether the object was already created by checking the null value.
|
||||
2. If the value is null, it creates a new object, saves it into the private field, and returns the object to the caller. Otherwise, it returns the object that was created previously.
|
||||
|
||||
|
||||
|
||||
The main problem with this singleton implementation is its disregard for parallel processes. When multiple processes using threads access the resource simultaneously, a problem occurs. There is one solution to this, and it is called _double-checked locking_ for multithread safety, which is shown here:
|
||||
|
||||
|
||||
```
|
||||
package org.opensource.demo.singleton;
|
||||
|
||||
public class ImprovedOpensourceSingleton {
|
||||
|
||||
private volatile static ImprovedOpensourceSingleton uniqueInstance;
|
||||
|
||||
private ImprovedOpensourceSingleton() {}
|
||||
|
||||
public static ImprovedOpensourceSingleton getInstance() {
|
||||
if (uniqueInstance == null) {
|
||||
synchronized (ImprovedOpensourceSingleton.class) {
|
||||
if (uniqueInstance == null) {
|
||||
uniqueInstance = new ImprovedOpensourceSingleton();
|
||||
}
|
||||
}
|
||||
}
|
||||
return uniqueInstance;
|
||||
}
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
Just to emphasize the previous point, make sure to implement your singleton directly only when you believe is a safe option to do so. The best way is to leverage the singleton feature is by using a well-made programming framework.
|
||||
|
||||
### Factory pattern: Delegate object creation to the factory class to hide creation logic
|
||||
|
||||
The [factory pattern][16] is another well-known design pattern, but it is a little more complex. There are several ways to implement the factory pattern, but the following sample code demonstrates the simplest possible way. The factory pattern defines an interface for creating an object but lets the subclasses decide which class to instantiate.
|
||||
|
||||
> **Factory pattern:** Delegates object creation to the factory class so it hides the creation logic.
|
||||
|
||||
The diagram below shows how the simplest factory pattern is implemented.
|
||||
|
||||
![Factory pattern][17]
|
||||
|
||||
Instead of the client directly calling the object creation, the client asks the factory class for a certain object, type x. Based on the type, the factory pattern decides which object to create and to return.
|
||||
|
||||
In this code sample, OpensourceFactory is the factory class implementation that takes the _type_ from the caller and decides which object to create based on that input value:
|
||||
|
||||
|
||||
```
|
||||
package org.opensource.demo.factory;
|
||||
|
||||
public class OpensourceFactory {
|
||||
|
||||
public OpensourceJVMServers getServerByVendor([String][18] name) {
|
||||
if(name.equals("Apache")) {
|
||||
return new Tomcat();
|
||||
}
|
||||
else if(name.equals("Eclipse")) {
|
||||
return new Jetty();
|
||||
}
|
||||
else if (name.equals("RedHat")) {
|
||||
return new WildFly();
|
||||
}
|
||||
else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
And OpenSourceJVMServer is a 100% abstraction class (or an interface class) that indicates what to implement, not how:
|
||||
|
||||
|
||||
```
|
||||
package org.opensource.demo.factory;
|
||||
|
||||
public interface OpensourceJVMServers {
|
||||
public void startServer();
|
||||
public void stopServer();
|
||||
public [String][18] getName();
|
||||
}
|
||||
```
|
||||
|
||||
Here is a sample implementation class for OpensourceJVMServers. When "RedHat" is passed as the type to the factory class, the WildFly server is created:
|
||||
|
||||
|
||||
```
|
||||
package org.opensource.demo.factory;
|
||||
|
||||
public class WildFly implements OpensourceJVMServers {
|
||||
public void startServer() {
|
||||
[System][19].out.println("Starting WildFly Server...");
|
||||
}
|
||||
|
||||
public void stopServer() {
|
||||
[System][19].out.println("Shutting Down WildFly Server...");
|
||||
}
|
||||
|
||||
public [String][18] getName() {
|
||||
return "WildFly";
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Observer pattern: Subscribe to topics and get notified about updates
|
||||
|
||||
Finally, there is the [observer pattern][20]_._ Like the singleton pattern, few professional programmers implement the observer pattern directly. However, many messaging queue and data service implementations borrow the observer pattern concept. The observer pattern defines one-to-many dependencies between objects so that when one object changes state, all of its dependents are notified and updated automatically.
|
||||
|
||||
> **Observer pattern:** Subscribe to the topics/subjects where the client can be notified if there is an update.
|
||||
|
||||
The easiest way to think about the observer pattern is to imagine a mailing list where you can subscribe to any topic, whether it is open source, technologies, celebrities, cooking, or anything else that interests you. Each topic maintains a list of its subscribers, which is equivalent to an "observer" in the observer pattern. When a topic is updated, all of its subscribers (observers) are notified of the changes. And a subscriber can always unsubscribe from a topic.
|
||||
|
||||
As the following diagram shows, the client can be subscribed to different topics and add the observer to be notified about new information. Because the observer listens continuously to the subject, the observer notifies the client about any change that occurs.
|
||||
|
||||
![Observer pattern][21]
|
||||
|
||||
Let's look at the sample code for the observer pattern, starting with the subject/topic class:
|
||||
|
||||
|
||||
```
|
||||
package org.opensource.demo.observer;
|
||||
|
||||
public interface Topic {
|
||||
|
||||
public void addObserver([Observer][22] observer);
|
||||
public void deleteObserver([Observer][22] observer);
|
||||
public void notifyObservers();
|
||||
}
|
||||
```
|
||||
|
||||
This code describes an interface for different topics to implement the defined methods. Notice how an observer can be added, removed, or notified.
|
||||
|
||||
Here is an example implementation of the topic:
|
||||
|
||||
|
||||
```
|
||||
package org.opensource.demo.observer;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.ArrayList;
|
||||
|
||||
public class Conference implements Topic {
|
||||
private List<Observer> listObservers;
|
||||
private int totalAttendees;
|
||||
private int totalSpeakers;
|
||||
private [String][18] nameEvent;
|
||||
|
||||
public Conference() {
|
||||
listObservers = new ArrayList<Observer>();
|
||||
}
|
||||
|
||||
public void addObserver([Observer][22] observer) {
|
||||
listObservers.add(observer);
|
||||
}
|
||||
|
||||
public void deleteObserver([Observer][22] observer) {
|
||||
int i = listObservers.indexOf(observer);
|
||||
if (i >= 0) {
|
||||
listObservers.remove(i);
|
||||
}
|
||||
}
|
||||
|
||||
public void notifyObservers() {
|
||||
for (int i=0, nObservers = listObservers.size(); i < nObservers; ++ i) {
|
||||
[Observer][22] observer = listObservers.get(i);
|
||||
observer.update(totalAttendees,totalSpeakers,nameEvent);
|
||||
}
|
||||
}
|
||||
|
||||
public void setConferenceDetails(int totalAttendees, int totalSpeakers, [String][18] nameEvent) {
|
||||
this.totalAttendees = totalAttendees;
|
||||
this.totalSpeakers = totalSpeakers;
|
||||
this.nameEvent = nameEvent;
|
||||
notifyObservers();
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
This class defines the implementation of a particular topic. When a change happens, this implementation is where it is invoked. Notice that this takes the number of observers, which is stored as the list, and can both notify and maintain the observers.
|
||||
|
||||
Here is an observer class:
|
||||
|
||||
|
||||
```
|
||||
package org.opensource.demo.observer;
|
||||
|
||||
public interface [Observer][22] {
|
||||
public void update(int totalAttendees, int totalSpeakers, [String][18] nameEvent);
|
||||
}
|
||||
```
|
||||
|
||||
This class defines an interface that different observers can implement to take certain actions.
|
||||
|
||||
For example, the observer implementation can print out the number of attendees and speakers at a conference:
|
||||
|
||||
|
||||
```
|
||||
package org.opensource.demo.observer;
|
||||
|
||||
public class MonitorConferenceAttendees implements [Observer][22] {
|
||||
private int totalAttendees;
|
||||
private int totalSpeakers;
|
||||
private [String][18] nameEvent;
|
||||
private Topic topic;
|
||||
|
||||
public MonitorConferenceAttendees(Topic topic) {
|
||||
this.topic = topic;
|
||||
topic.addObserver(this);
|
||||
}
|
||||
|
||||
public void update(int totalAttendees, int totalSpeakers, [String][18] nameEvent) {
|
||||
this.totalAttendees = totalAttendees;
|
||||
this.totalSpeakers = totalSpeakers;
|
||||
this.nameEvent = nameEvent;
|
||||
printConferenceInfo();
|
||||
}
|
||||
|
||||
public void printConferenceInfo() {
|
||||
[System][19].out.println(this.nameEvent + " has " + totalSpeakers + " speakers and " + totalAttendees + " attendees");
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Where to go from here?
|
||||
|
||||
Now that you've read this introductory guide to design patterns, you should be in a good place to pursue other design patterns, such as facade, template, and decorator. There are also concurrent and distributed system design patterns like the circuit breaker pattern and the actor pattern.
|
||||
|
||||
However, I believe it's best to hone your skills first by implementing these design patterns in your side projects or just as practice. You can even begin to contemplate how you can apply these design patterns in your real projects. Next, I highly recommend checking out the [SOLID principles][23] of OOP. After that, you will be ready to look into the other design patterns.
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://opensource.com/article/19/7/understanding-software-design-patterns
|
||||
|
||||
作者:[Bryant Son][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[译者ID](https://github.com/译者ID)
|
||||
校对:[校对者ID](https://github.com/校对者ID)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://opensource.com/users/brsonhttps://opensource.com/users/erezhttps://opensource.com/users/brson
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/rh_003601_05_mech_osyearbook2016_cloud_cc.png?itok=XSV7yR9e (clouds in the sky with blue pattern)
|
||||
[2]: https://en.wikipedia.org/wiki/Software_design_pattern
|
||||
[3]: https://en.wikipedia.org/wiki/Object-oriented_programming
|
||||
[4]: https://en.wikipedia.org/wiki/Software_framework
|
||||
[5]: https://github.com/bryantson/OpensourceDotComDemos/tree/master/TopDesignPatterns
|
||||
[6]: https://www.youtube.com/watch?v=VlBXYtLI7kE&feature=youtu.be
|
||||
[7]: https://openjdk.java.net/
|
||||
[8]: https://maven.apache.org/
|
||||
[9]: https://www.jetbrains.com/idea/download/#section=mac
|
||||
[10]: https://www.eclipse.org/ide/
|
||||
[11]: https://git-scm.com/
|
||||
[12]: https://en.wikipedia.org/wiki/Abstraction_principle_(computer_programming)
|
||||
[13]: https://en.wikipedia.org/wiki/Singleton_pattern
|
||||
[14]: https://opensource.com/sites/default/files/uploads/designpatterns1_normalclassinstantiation.jpg (Normal class instantiation)
|
||||
[15]: https://opensource.com/sites/default/files/uploads/designpatterns2_singletonpattern.jpg (Singleton pattern instantiation)
|
||||
[16]: https://en.wikipedia.org/wiki/Factory_method_pattern
|
||||
[17]: https://opensource.com/sites/default/files/uploads/designpatterns3_factorypattern.jpg (Factory pattern)
|
||||
[18]: http://www.google.com/search?hl=en&q=allinurl%3Adocs.oracle.com+javase+docs+api+string
|
||||
[19]: http://www.google.com/search?hl=en&q=allinurl%3Adocs.oracle.com+javase+docs+api+system
|
||||
[20]: https://en.wikipedia.org/wiki/Observer_pattern
|
||||
[21]: https://opensource.com/sites/default/files/uploads/designpatterns4_observerpattern.jpg (Observer pattern)
|
||||
[22]: http://www.google.com/search?hl=en&q=allinurl%3Adocs.oracle.com+javase+docs+api+observer
|
||||
[23]: https://en.wikipedia.org/wiki/SOLID
|
@ -0,0 +1,193 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: ( )
|
||||
[#]: reviewer: ( )
|
||||
[#]: publisher: ( )
|
||||
[#]: url: ( )
|
||||
[#]: subject: (What is POSIX? Richard Stallman explains)
|
||||
[#]: via: (https://opensource.com/article/19/7/what-posix-richard-stallman-explains)
|
||||
[#]: author: (Seth Kenlon https://opensource.com/users/seth)
|
||||
|
||||
What is POSIX? Richard Stallman explains
|
||||
======
|
||||
Discover what's behind the standards for operating system compatibility
|
||||
from a pioneer of computer freedom.
|
||||
![Scissors cutting open access to files][1]
|
||||
|
||||
What is [POSIX][2], and why does it matter? It's a term you've likely seen in technical writing, but it often gets lost in a sea of techno-initialisms and jargon-that-ends-in-X. I emailed Dr. [Richard Stallman][3] (better known in hacker circles as RMS) to find out more about the term's origin and the concept behind it.
|
||||
|
||||
Richard Stallman says "open" and "closed" are the wrong way to classify software. Stallman classifies programs as _freedom-respecting_ ("free" or "libre") and _freedom-trampling_ ("non-free" or "proprietary"). Open source discourse typically encourages certain practices for the sake of practical advantages, not as a moral imperative.
|
||||
|
||||
The free software movement, which Stallman launched in 1984, says more than _advantages_ are at stake. Users of computers _deserve_ control of their computing, so programs denying users control are an injustice to be rejected and eliminated. For users to have control, the program must give them the [four essential freedoms][4]:
|
||||
|
||||
* The freedom to run the program as you wish, for any purpose (freedom 0).
|
||||
* The freedom to study how the program works and change it so it does your computing as you wish (freedom 1). Access to the source code is a precondition for this.
|
||||
* The freedom to redistribute copies so you can help others (freedom 2).
|
||||
* The freedom to distribute copies of your modified versions to others (freedom 3). By doing this you can give the whole community a chance to benefit from your changes. Access to the source code is a precondition for this.
|
||||
|
||||
|
||||
|
||||
### About POSIX
|
||||
|
||||
**Seth:** The POSIX standard is a document released by the [IEEE][5] that describes a "portable operating system." As long as developers write programs to match this description, they have produced a POSIX-compliant program. In the tech industry, we call this a "specification" or "spec" for short. That's mostly understandable, as far as tech jargon goes, but what makes an operating system "portable"?
|
||||
|
||||
**RMS:** I think it was the _interface_ that was supposed to be portable (among systems), rather than any one _system_. Indeed, various systems that are different inside do support parts of the POSIX interface spec.
|
||||
|
||||
**Seth:** So if two systems feature POSIX-compliant programs, then they can make assumptions about one another, enabling them to know how to "talk" to one another. I read that it was you who came up with the name "POSIX." How did you come up with the term, and how was it adopted by the IEEE?
|
||||
|
||||
**RMS:** The IEEE had finished developing the spec but had no concise name for it. The title said something like "portable operating system interface," though I don't remember the exact words. The committee put on "IEEEIX" as the concise name. I did not think that was a good choice. It is ugly to pronounce—it would sound like a scream of terror, "Ayeee!"—so I expected people would instead call the spec "Unix."
|
||||
|
||||
Since [GNU's Not Unix][6], and it was intended to replace Unix, I did not want people to call GNU a "Unix system." I, therefore, proposed a concise name that people might actually use. Having no particular inspiration, I generated a name the unclever way: I took the initials of "portable operating system" and added "ix." The IEEE adopted this eagerly.
|
||||
|
||||
**Seth:** Does "operating system" in the POSIX acronym refer only to Unix and Unix-like systems such as GNU, or is the intent to encompass all operating systems?
|
||||
|
||||
**RMS:** The term "operating system," in the abstract, covers systems that are not at all like Unix, not at all close to the POSIX spec. However, the spec is meant for systems that are a lot like Unix; only such systems will fit the POSIX spec.
|
||||
|
||||
**Seth:** Are you involved in reviewing or updating the current POSIX standards?
|
||||
|
||||
**RMS:** Not now.
|
||||
|
||||
**Seth:** The GNU Autotools toolchain does a lot to make applications easier to port, at least in terms of when it comes time to build and install. Is Autotools an important part of building a portable infrastructure?
|
||||
|
||||
**RMS:** Yes, because even among systems that follow POSIX, there are lots of little differences. The Autotools make it easier for a program to adapt to those differences. By the way, if anyone wants to help in the development of the Autotools, please email me.
|
||||
|
||||
**Seth:** I imagine, way back when GNU was just starting to make people realize that a (not)Unix liberated from proprietary technology was possible, there must have been a void of clarity about how free software could possibly work together.
|
||||
|
||||
**RMS:** I don't think there was any void or any uncertainty. I was simply going to follow the interfaces of BSD.
|
||||
|
||||
**Seth:** Some GNU applications are POSIX-compliant, while others have GNU-specific features either not in the POSIX spec or lack features required by the spec. How important is POSIX compliance to GNU applications?
|
||||
|
||||
**RMS:** Following a standard is important to the extent it serves users. We do not treat a standard as an authority, but rather as a guide that may be useful to follow. Thus, we talk about following standards rather than "complying" with them. See the section [Non-GNU Standards][7] in the GNU Coding Standards.
|
||||
|
||||
We strive to be compatible with standards on most issues because, on most issues, that serves users best. But there are occasional exceptions.
|
||||
|
||||
For instance, POSIX specifies that some utilities measure disk space in units of 512 bytes. I asked the committee to change this to 1K, but it refused, saying that a bureaucratic rule compelled the choice of 512. I don't recall much attempt to argue that users would be pleased with that decision.
|
||||
|
||||
Since GNU's second priority, after users' freedom, is users' convenience, we made GNU programs measure disk space in blocks of 1K by default.
|
||||
|
||||
However, to defend against potential attacks by competitors who might claim that this deviation made GNU "noncompliant," we implemented optional modes that follow POSIX and ISO C to ridiculous extremes. For POSIX, setting the environment variable POSIXLY_CORRECT makes programs specified by POSIX list disk space in terms of 512 bytes. If anyone knows of a case of an actual use of POSIXLY_CORRECT or its GCC counterpart **\--pedantic** that provides an actual benefit to some user, please tell me about it.
|
||||
|
||||
**Seth:** Are POSIX-compliant free software projects easier to port to other Unix-like systems?
|
||||
|
||||
**RMS:** I suppose so, but I decided in the 1980s not to spend my time on porting software to systems other than GNU. I focused on advancing the GNU system towards making it unnecessary to use any non-free software and left the porting of GNU programs to non-GNU-like systems to whoever wanted to run them on those systems.
|
||||
|
||||
**Seth:** Is POSIX important to software freedom?
|
||||
|
||||
**RMS:** At the fundamental level, it makes no difference. However, standardization by POSIX and ISO C surely made the GNU system easier to migrate to, and that helped us advance more quickly towards the goal of liberating users from non-free software. That was achieved in the early 1990s, when Linux was made free software and then filled the kernel-shaped gap in GNU.
|
||||
|
||||
### GNU innovations adopted by POSIX
|
||||
|
||||
I also asked Dr. Stallman whether any GNU-specific innovations or conventions had later become adopted as a POSIX standard. He couldn't recall specific examples, but kindly emailed several developers on my behalf.
|
||||
|
||||
Developers Giacomo Catenazzi, James Youngman, Eric Blake, Arnold Robbins, and Joshua Judson Rosen all responded with memories of previous POSIX iterations as well as ones still in progress. POSIX is a "living" standard, so it's being updated and reviewed by industry professionals continuously, and many developers who work on GNU projects propose the inclusion of GNU features.
|
||||
|
||||
For the sake of historical interest, here' are some popular GNU features that have made their way into POSIX.
|
||||
|
||||
#### Make
|
||||
|
||||
Some GNU **Make** features have been adopted into POSIX's definition of **make**. The relevant [specification][8] provides detailed attribution for features borrowed from existing implementations.
|
||||
|
||||
#### Diff and patch
|
||||
|
||||
Both the **[diff][9]** and **[patch][10]** commands have gotten **-u** and **-U** options added directly from GNU versions of those tools.
|
||||
|
||||
#### C library
|
||||
|
||||
Many features of the GNU C library, **glibc**, have been adopted in POSIX. Lineage is sometimes difficult to trace, but James Youngman wrote:
|
||||
|
||||
> "I'm pretty sure there are a number of features of ISO C which were pioneered by GCC. For example, **_Noreturn** is new in C11, but GCC-1.35 had this feature (one used the **volatile** modifier on a function declaration). Also—though I'm not certain about this—GCC-1.35 supported Arrays of Variable Length which seem to be very similar to modern C's conformant arrays."
|
||||
|
||||
Giacomo Catenazzi cites the Open Group's [**strftime** article][11], pointing to this attribution: "This is based on a feature in some versions of GNU libc's **strftime()**."
|
||||
|
||||
Eric Blake notes that the **getline()** and various ***_l()** locale-based functions were definitely pioneered by GNU.
|
||||
|
||||
Joshua Judson Rosen adds to this, saying he clearly remembers being impressed by the adoption of **getline** functions after witnessing strangely familiar GNU-like behavior from code meant for a different OS entirely.
|
||||
|
||||
"Wait…that's GNU-specific… isn't it? Oh—not anymore, apparently."
|
||||
|
||||
Rosen pointed me to the [**getline** man page][12], which says:
|
||||
|
||||
> Both **getline()** and **getdelim()** were originally GNU extensions. They were standardized in POSIX.1-2008.
|
||||
|
||||
Eric Blake sent me a list of other extensions that may be added in the next POSIX revision (codenamed Issue 8, currently due around 2021):
|
||||
|
||||
* [ppoll][13]
|
||||
* [pthread_cond_clockwait et al.][14]
|
||||
* [posix_spawn_file_actions_addchdir][15]
|
||||
* [getlocalename_1][16]
|
||||
* [reallocarray][17]
|
||||
|
||||
|
||||
|
||||
### Userspace extensions
|
||||
|
||||
POSIX doesn't just define functions and features for developers. It defines standard behavior for userspace as well.
|
||||
|
||||
#### ls
|
||||
|
||||
The **-A** option is used to exclude the **.** (representing the current location) and **..** (representing the opportunity to go back one directory) notation from the results of an **ls** command. This was adopted for POSIX 2008.
|
||||
|
||||
#### find
|
||||
|
||||
The **find** command is a useful tool for ad hoc [**for** loops][18] and as a gateway into [parallel][19] processing.
|
||||
|
||||
A few conveniences made their way from GNU to POSIX, including the **-path** and **-perm** options.
|
||||
|
||||
The **-path** option lets you filter search results matching a filesystem path pattern and was available in GNU's version of **find** since before 1996 (the earliest record in **findutil**'s Git repository). James Youngman notes that [HP-UX][20] also had this option very early on, so whether it's a GNU or an HP-UX innovation (or both) is uncertain.
|
||||
|
||||
The **-perm** option lets you filter search results by file permission. This was in GNU's version of **find** by 1996 and arrived later in the POSIX standard "IEEE Std 1003.1, 2004 Edition."
|
||||
|
||||
The **xargs** command, part of the **findutils** package, had a **-p** option to put **xargs** into an interactive mode (the user is prompted whether to continue or not) by 1996, and it arrived in POSIX in "IEEE Std 1003.1, 2004 Edition."
|
||||
|
||||
#### Awk
|
||||
|
||||
Arnold Robbins, the maintainer of GNU **awk** (the **gawk** command in your **/usr/bin** directory, probably the destination of the symlink **awk**), says that **gawk** and **mawk** (another GPL **awk** implementation) allow **RS** to be a regular expression, which is the case when **RS** has a length greater than 1. This isn't a feature in POSIX yet, but there's an [indication that it will be][21]:
|
||||
|
||||
> _The undefined behavior resulting from NULs in extended regular expressions allows future extensions for the GNU gawk program to process binary data._
|
||||
>
|
||||
> _The unspecified behavior from using multi-character RS values is to allow possible future extensions based on extended regular expressions used for record separators. Historical implementations take the first character of the string and ignore the others._
|
||||
|
||||
This is a significant enhancement because the **RS** notation defines a separator between records. It might be a comma or a semicolon or a dash or any such character, but if it's a _sequence_ of characters, then only the first character is used unless you're working in **gawk** or **mawk**. Imagine parsing a document of IP addresses with records separated by an ellipsis (three dots in a row), only to get back results parsed at every dot in every IP address.
|
||||
|
||||
**[Mawk][22]** supported the feature first, but it was without a maintainer for several years, leaving **gawk** to carry the torch. (**Mawk** has since gained a new maintainer, so arguably credit can be shared for pushing this feature into the collective expectation.)
|
||||
|
||||
### The POSIX spec
|
||||
|
||||
In general, Giacomo Catenzzi points out, "…because GNU utilities were used so much, a lot of other options and behaviors were aligned. At every change in shell, Bash is used as comparison (as a first-class citizen)." There's no requirement to cite GNU or any other influence when something is rolled into the POSIX spec, and it can safely be assumed that influences to POSIX come from many sources, with GNU being only one of many.
|
||||
|
||||
The significance of POSIX is consensus. A group of technologists working together toward common specifications to be shared by hundreds of uncommon developers lends strength to the greater movement toward software independence and developer and user freedom.
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://opensource.com/article/19/7/what-posix-richard-stallman-explains
|
||||
|
||||
作者:[Seth Kenlon][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[译者ID](https://github.com/译者ID)
|
||||
校对:[校对者ID](https://github.com/校对者ID)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://opensource.com/users/seth
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/document_free_access_cut_security.png?itok=ocvCv8G2 (Scissors cutting open access to files)
|
||||
[2]: https://pubs.opengroup.org/onlinepubs/9699919799.2018edition/
|
||||
[3]: https://stallman.org/
|
||||
[4]: https://www.gnu.org/philosophy/free-sw.en.html
|
||||
[5]: https://www.ieee.org/
|
||||
[6]: http://gnu.org
|
||||
[7]: https://www.gnu.org/prep/standards/html_node/Non_002dGNU-Standards.html
|
||||
[8]: https://pubs.opengroup.org/onlinepubs/9699919799/utilities/make.html
|
||||
[9]: https://pubs.opengroup.org/onlinepubs/9699919799/utilities/diff.html
|
||||
[10]: https://pubs.opengroup.org/onlinepubs/9699919799/utilities/patch.html
|
||||
[11]: https://pubs.opengroup.org/onlinepubs/9699919799/functions/strftime.html
|
||||
[12]: http://man7.org/linux/man-pages/man3/getline.3.html
|
||||
[13]: http://austingroupbugs.net/view.php?id=1263
|
||||
[14]: http://austingroupbugs.net/view.php?id=1216
|
||||
[15]: http://austingroupbugs.net/view.php?id=1208
|
||||
[16]: http://austingroupbugs.net/view.php?id=1220
|
||||
[17]: http://austingroupbugs.net/view.php?id=1218
|
||||
[18]: https://opensource.com/article/19/6/how-write-loop-bash
|
||||
[19]: https://opensource.com/article/18/5/gnu-parallel
|
||||
[20]: https://www.hpe.com/us/en/servers/hp-ux.html
|
||||
[21]: https://pubs.opengroup.org/onlinepubs/9699919799/utilities/awk.html
|
||||
[22]: https://invisible-island.net/mawk/
|
@ -0,0 +1,170 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: ( )
|
||||
[#]: reviewer: ( )
|
||||
[#]: publisher: ( )
|
||||
[#]: url: ( )
|
||||
[#]: subject: (How to Use BleachBit to Optimize Ubuntu Linux)
|
||||
[#]: via: (https://itsfoss.com/use-bleachbit-ubuntu/)
|
||||
[#]: author: (Sergiu https://itsfoss.com/author/sergiu/)
|
||||
|
||||
How to Use BleachBit to Optimize Ubuntu Linux
|
||||
======
|
||||
|
||||
[BleachBit][1] is a cross-platform, free and [open source tool for helping you get rid of junk files][2] on your machine. It is powerful and easy to use, allowing you to not only delete junk files, but also to shred and wipe files. This is useful for keeping your keeping system clean and organized, as well as offering you well-deserved privacy.
|
||||
|
||||
In this article, I’m going to guide you through the installation process and show you how to make basic usage of BleachBit, while also including screenshots where needed.
|
||||
|
||||
![][3]
|
||||
|
||||
**Note:** _I’ll be using_ _**Ubuntu**_*, but the steps are similar for most Linux distributions.*
|
||||
|
||||
### Installing BleachBit on Ubuntu
|
||||
|
||||
The simplest way to install BleachBit is using the package manager or the software. Here you can search for **BleachBit** and when you find it, click on it and then press **Install**. Removing it is as simple as searching for it again and pressing **Remove**.
|
||||
|
||||
![BleachBit in Ubuntu Software Center][4]
|
||||
|
||||
If you are terminal lover, you can [use apt command][5] to install BleachBit:
|
||||
|
||||
```
|
||||
sudo apt install bleachbit -y
|
||||
```
|
||||
|
||||
However, this won’t install the latest version of BleachBit. At the time of writing this article, the [Ubuntu repositories][6] contain version 2.0, while the latest version is 2.2.
|
||||
|
||||
To get the latest version, you first of all have to go to the [official download page][7]:
|
||||
|
||||
![BleachBit Download Page][8]
|
||||
|
||||
Here, download the right package for your system (in my case it’s **Ubuntu 18.04 LTS**) by clicking on the corresponding link. It will download a .deb file. [Installing packages from deb files][9] is simple. Simply double click on it and it will run in the software center. Just click on install here.
|
||||
|
||||
### Using BleachBit to clean your system
|
||||
|
||||
Search for BleachBit and clcik on the **bleachbit** icon in the **Applications Menu**:
|
||||
|
||||
![Bleachbit In Applications Menu][10]
|
||||
|
||||
**Note:** _To run **BleachBit** with administrator privileges, click on the second icon (**BleachBit as Administrator/root)**._
|
||||
|
||||
Either of this methods should open up the **start screen**:
|
||||
|
||||
![BleachBit Start Screen][11]
|
||||
|
||||
This is the **Preferences** menu and you can open it up at any time by clicking **Edit > Prefrences**.
|
||||
|
||||
[][12]
|
||||
|
||||
Suggested read Top 5 CAD Software Available for Linux
|
||||
|
||||
Some **important options** include:
|
||||
|
||||
* **Overwrite contents of files to prevent recovery**: although slower, this will actually **shred** your files. Files are normally marked as deleted and allowed to be overwritten if there isn’t any space left. However, selecting this options will fill the space with junk (that will still act as a deleted file), making the shredded file irrecoverable. Keep in mind that this process is slower.
|
||||
* **Languages**: here you can choose which languages to keep (although they don’t really take up that much space).
|
||||
* **Drives:** in this sub-menu you can add directories where all free space should be replaced with junk (as when shredding files), making sure no file can be recovered from those locations.
|
||||
|
||||
|
||||
|
||||
Closing the **Preferences** menu will leave you in the **Main Menu**:
|
||||
|
||||
![BleachBit Menu][13]
|
||||
|
||||
On the **left side**, you can select what type of files you want to delete (this includes system-wide files and application-specific files). Some of them require **administrator privileges** (such as APT cache and System-related options), and some of them will prompt warnings (such as Firefox warning you that your saved passwords will be deleted).
|
||||
|
||||
After making your selection, I suggest clicking on the **Preview** (the magnifying glass icon). This will show you exactly what is going to be deleted:
|
||||
|
||||
![BleachBit Preview][14]
|
||||
|
||||
By pressing **Clean** (the red circle), you are going to start the deleting process. You’ll get a message when **BleachBit** finishes:
|
||||
|
||||
![BleachBit Clean][15]
|
||||
|
||||
Another thing you can do is **quickly shred** or **wipe** a specific directory or file:
|
||||
|
||||
![BleachBit Quick Shred][16]
|
||||
|
||||
### Using BleachBit in command line
|
||||
|
||||
You can also use BleachBit in the terminal. To **list cleaners** run:
|
||||
|
||||
```
|
||||
bleachbit -l
|
||||
```
|
||||
|
||||
This will produce output in the vein of:
|
||||
|
||||
```
|
||||
...
|
||||
thunderbird.index
|
||||
thunderbird.passwords
|
||||
thunderbird.vacuum
|
||||
transmission.blocklists
|
||||
transmission.history
|
||||
transmission.torrents
|
||||
tremulous.cache
|
||||
vim.history
|
||||
vlc.mru
|
||||
vuze.backup_files
|
||||
vuze.cache
|
||||
vuze.logs
|
||||
vuze.tmp
|
||||
warzone2100.logs
|
||||
wine.tmp
|
||||
winetricks.temporary_files
|
||||
x11.debug_logs
|
||||
xine.cache
|
||||
yum.clean_all
|
||||
yum.vacuum
|
||||
...
|
||||
```
|
||||
|
||||
Now you can run any cleaner or group of cleaners. For example:
|
||||
|
||||
```
|
||||
bleachbit -c google_chrome* thunderbird.passwords
|
||||
```
|
||||
|
||||
This command will delete all Google Chrome saved data and all saved Thunderbird passwords.
|
||||
|
||||
The CLI is useful because you can write bash scripts that execute BleachBit commands and you can even schedule cleaning actions using tools such as CRON.
|
||||
|
||||
[][17]
|
||||
|
||||
Suggested read Use Evernote on Linux with These Tools
|
||||
|
||||
**Wrapping Up**
|
||||
|
||||
There are [ways to clean up Ubuntu][18] but having a dedicated GUI tool is always handy. Whether you are simply looking for a neat way to keep your system clean of any unnecessary data, optimizing your machine, or trying to keep your personal details safe, **BleachBit** is a tool that will surely come in handy, being so easy to get the hang of (while still being powerful).
|
||||
|
||||
Do you use any system cleaner? If so, which one and how? Let us know in the comments!
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://itsfoss.com/use-bleachbit-ubuntu/
|
||||
|
||||
作者:[Sergiu][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[译者ID](https://github.com/译者ID)
|
||||
校对:[校对者ID](https://github.com/校对者ID)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://itsfoss.com/author/sergiu/
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://www.bleachbit.org/
|
||||
[2]: https://itsfoss.com/ccleaner-alternatives-ubuntu-linux/
|
||||
[3]: https://i2.wp.com/itsfoss.com/wp-content/uploads/2019/07/how_to_use_bleachbit_to_optimize_ubuntu-e1563200895890-800x450.png?resize=800%2C450&ssl=1
|
||||
[4]: https://i2.wp.com/itsfoss.com/wp-content/uploads/2019/07/bleachbit_ubuntu_software_center.png?fit=800%2C369&ssl=1
|
||||
[5]: https://itsfoss.com/apt-command-guide/
|
||||
[6]: https://itsfoss.com/ubuntu-repositories/
|
||||
[7]: https://www.bleachbit.org/download/linux
|
||||
[8]: https://i0.wp.com/itsfoss.com/wp-content/uploads/2019/07/bleachbit_download_page.png?fit=800%2C455&ssl=1
|
||||
[9]: https://itsfoss.com/install-deb-files-ubuntu/
|
||||
[10]: https://i2.wp.com/itsfoss.com/wp-content/uploads/2019/07/bleachbit_in_applications_menu.jpg?fit=800%2C276&ssl=1
|
||||
[11]: https://i1.wp.com/itsfoss.com/wp-content/uploads/2019/07/bleachbit_start_screen.png?fit=800%2C656&ssl=1
|
||||
[12]: https://itsfoss.com/cad-software-linux/
|
||||
[13]: https://i1.wp.com/itsfoss.com/wp-content/uploads/2019/07/bleachbit_menu.png?fit=800%2C659&ssl=1
|
||||
[14]: https://i1.wp.com/itsfoss.com/wp-content/uploads/2019/07/bleachbit_preview.png?fit=800%2C650&ssl=1
|
||||
[15]: https://i1.wp.com/itsfoss.com/wp-content/uploads/2019/07/bleachbit_clean.png?fit=800%2C653&ssl=1
|
||||
[16]: https://i0.wp.com/itsfoss.com/wp-content/uploads/2019/07/bleachbit_shred.png?fit=800%2C435&ssl=1
|
||||
[17]: https://itsfoss.com/evernote-on-linux/
|
||||
[18]: https://itsfoss.com/free-up-space-ubuntu-linux/
|
Loading…
Reference in New Issue
Block a user