diff --git a/LANGS.md b/LANGS.md index 78db73c4..a57c777f 100644 --- a/LANGS.md +++ b/LANGS.md @@ -1,2 +1,4 @@ * [English](en) * [русский язык](ru) +* [Türkçe](tr) +* [Persian(فارسی)](fa) diff --git a/en/thing_01/README.md b/en/thing_01/README.md index 3604026b..ba22a46c 100644 --- a/en/thing_01/README.md +++ b/en/thing_01/README.md @@ -12,4 +12,4 @@ If you schedule repayment of the debt in the next iteration, the cost will be mi Pay off technical debt as soon as possible. It would be imprudent to do otherwise. -By [Seb Rose](http://programmer.97things.oreilly.com/wiki/index.php/Seb_Rose) \ No newline at end of file +By [Seb Rose's GitHub profile](https://github.com/sebrose) / [Seb Rose's LinkedIn Profile](https://www.linkedin.com/in/sebrose) \ No newline at end of file diff --git a/en/thing_09/README.md b/en/thing_09/README.md index 01195778..112231cb 100644 --- a/en/thing_09/README.md +++ b/en/thing_09/README.md @@ -11,7 +11,7 @@ Assuming the tools are widely used, mature, and employed in various technology s Given how rare compiler bugs are, you are far better putting your time and energy into finding the error in your code than proving the compiler is wrong. All the usual debugging advice applies, so isolate the problem, stub out calls, surround it with tests; check calling conventions, shared libraries, and version numbers; explain it to someone else; look out for stack corruption and variable type mismatches; try the code on different machines and different build configurations, such as debug and release. Question your own assumptions and the assumptions of others. Tools from different vendors might have different assumptions built into them — so too might different tools from the same vendor. -When someone else is reporting a problem you cannot duplicate, go and see what they are doing. They maybe doing something you never thought of or are doing something in a different order. +When someone else is reporting a problem you cannot duplicate, go and see what they are doing. They may be doing something you never thought of or are doing something in a different order. As a personal rule if I have a bug I can't pin down, and I'm starting to think it's the compiler, then it's time to look for stack corruption. This is especially true if adding trace code makes the problem move around. @@ -19,4 +19,4 @@ Multi-threaded problems are another source of bugs to turn hair gray and induce So before you rush to blame the compiler, remember Sherlock Holmes' advice, "Once you eliminate the impossible, whatever remains, no matter how improbable, must be the truth," and prefer it to Dirk Gently's, "Once you eliminate the improbable, whatever remains, no matter how impossible, must be the truth." -By [Allan Kelly](http://programmer.97things.oreilly.com/wiki/index.php/Allan_Kelly) \ No newline at end of file +By [Allan Kelly](http://programmer.97things.oreilly.com/wiki/index.php/Allan_Kelly) diff --git a/en/thing_15/README.md b/en/thing_15/README.md index 6f4cd3c6..69af4e71 100644 --- a/en/thing_15/README.md +++ b/en/thing_15/README.md @@ -8,7 +8,7 @@ A section should be chosen so that at each endpoint the *state of the program* ( Many of the coding practices that are well known (although perhaps less well followed) and considered 'good' make reasoning easier. Hence, just by intending to reason about your code, you already start thinking toward a better style and structure. Unsurprisingly, most of these practices can be checked by static code analyzers: -1. Avoid using goto statements, as they make remote sections highly interdependent. +- Avoid using goto statements, as they make remote sections highly interdependent. - Avoid using modifiable global variables, as they make all sections that use them dependent. - Each variable should have the smallest possible scope. For example, a local object can be declared right before its first usage. - Make objects *immutable* whenever relevant. @@ -22,4 +22,4 @@ Many of the coding practices that are well known (although perhaps less well fol As well as reasoning about its correctness, arguing about your code gives you understanding of it. Communicate the insights you gain for everyone's benefit. -By [Yechiel Kimchi](http://programmer.97things.oreilly.com/wiki/index.php/Yechiel_Kimchi) \ No newline at end of file +By [Yechiel Kimchi](http://programmer.97things.oreilly.com/wiki/index.php/Yechiel_Kimchi) diff --git a/en/thing_20/README.md b/en/thing_20/README.md index cdbe5c30..e9596868 100644 --- a/en/thing_20/README.md +++ b/en/thing_20/README.md @@ -8,8 +8,8 @@ Starting your project with an installation process will give you time to evolve Putting deployment last means that the deployment process may need to be more complicated to work around assumptions in the code. What seemed a great idea in an IDE, where you have full control over an environment, might make for a much more complicated deployment process. It is better to know all the trade-offs sooner rather than later. -While "being able to deploy" doesn't seem to have a lot of business value early on as compared to seeing an application run on a developer's laptop, the simple truth is that until you can demonstrate you application on the target environment, there is a lot of work to do before you can deliver business value. If your rationale for putting off a deployment process is that it is trivial, then do it anyway since it is low cost. If it's too complicated, or if there are too many uncertainties, do what you would do with application code: experiment, evaluate, and refactor the deployment process as you go. +While "being able to deploy" doesn't seem to have a lot of business value early on as compared to seeing an application run on a developer's laptop, the simple truth is that until you can demonstrate your application on the target environment, there is a lot of work to do before you can deliver business value. If your rationale for putting off a deployment process is that it is trivial, then do it anyway since it is low cost. If it's too complicated, or if there are too many uncertainties, do what you would do with application code: experiment, evaluate, and refactor the deployment process as you go. The installation/deployment process is essential to the productivity of your customers or your professional services team, so you should be testing and refactoring this process as you go. We test and refactor the source code throughout a project. The deployment deserves no less. -By [Steve Berczuk](http://programmer.97things.oreilly.com/wiki/index.php/Steve_Berczuk) \ No newline at end of file +By [Steve Berczuk](http://programmer.97things.oreilly.com/wiki/index.php/Steve_Berczuk) diff --git a/en/thing_26/README.md b/en/thing_26/README.md index aa1ee494..0cecf78d 100644 --- a/en/thing_26/README.md +++ b/en/thing_26/README.md @@ -33,7 +33,7 @@ Not handling errors leads to: - **Brittle code.** Code that's filled with exciting, hard-to-find bugs. - **Insecure code.** Crackers often exploit poor error handling to break into software systems. -- **Poor structure.** If there are errors from your code that are tedious to deal with continually, you have probably have a poor interface. Express it so that the errors are less intrusive and the their handling is less onerous. +- **Poor structure.** If there are errors from your code that are tedious to deal with continually, you probably have a poor interface. Express it so that the errors are less intrusive and the their handling is less onerous. Just as you should check all potential errors in your code, you need to expose all potentially erroneous conditions in your interfaces. Do not hide them, pretending that your services will always work. @@ -44,4 +44,4 @@ Why don't we check for errors? There are a number of common excuses. Which of th - I know that this function call will *never* return an error (printf always works, malloc always returns new memory — if it fails we have bigger problems...). - It's only a toy program, and needn't be written to a production-worthy level. -By [Pete Goodliffe](http://programmer.97things.oreilly.com/wiki/index.php/Pete_Goodliffe) \ No newline at end of file +By [Pete Goodliffe](http://programmer.97things.oreilly.com/wiki/index.php/Pete_Goodliffe) diff --git a/en/thing_53/README.md b/en/thing_53/README.md index ee2136a8..af6960a3 100644 --- a/en/thing_53/README.md +++ b/en/thing_53/README.md @@ -3,13 +3,13 @@ Depressingly often (happened to me again just before I wrote this), the view many programmers have of the process of going from source code to a statically linked executable in a compiled language is: 1. Edit source code -- Compile source code into object files -- Something magical happens -- Run executable +2. Compile source code into object files +3. Something magical happens +4. Run executable Step 3 is, of course, the linking step. Why would I say such an outrageous thing? I've been doing tech support for decades, and I get the following questions again and again: -1. The linker says def is defined more than once. +- The linker says def is defined more than once. - The linker says abc is an unresolved symbol. - Why is my executable so large? @@ -49,4 +49,4 @@ To determine why an executable is the size it is, take a look at the map file th Although it is not always immediately obvious why you get a particular linker message, there is nothing magical about linkers. The mechanics are straightforward; it's the details you have to figure out in each case. -By [Walter Bright](http://creativecommons.org/licenses/by/3.0/us/) \ No newline at end of file +By [Walter Bright](http://creativecommons.org/licenses/by/3.0/us/) diff --git a/en/thing_54/README.md b/en/thing_54/README.md index dbc66e05..3a117d54 100644 --- a/en/thing_54/README.md +++ b/en/thing_54/README.md @@ -19,15 +19,15 @@ The answer depends on your project, and on your personal stake in the production So what can we do if we see a problem? 1. Avoid creating an interim solution in the first place. -- Change the forces that influence the decision of the project manager. -- Leave it as is. +2. Change the forces that influence the decision of the project manager. +3. Leave it as is. Let's examine these options more closely: 1. Avoidance does not work in most places. There is an actual problem to solve, and the standards have turned out to be too restrictive. You might spend some energy trying to change the standards. An honorable albeit tedious endeavor... and that change will not be effective in time for your problem at hand. -- The forces are rooted in the project culture, which resists volitional change. It could be successful in very small projects — especially if it's just you — and you just happen to clean the mess without asking in advance. It could also be successful if the project is such a mess that it is visibly stalled and some time for cleaning up is commonly accepted. -- The status quo automatically applies if the previous option does not. +2. The forces are rooted in the project culture, which resists volitional change. It could be successful in very small projects — especially if it's just you — and you just happen to clean the mess without asking in advance. It could also be successful if the project is such a mess that it is visibly stalled and some time for cleaning up is commonly accepted. +3. The status quo automatically applies if the previous option does not. You will create many solutions, some of them will be interim, most of them will be useful. The best way to overcome interim solutions is to make them superfluous, to provide a more elegant and useful solution. May you be granted the [serenity](http://en.wikipedia.org/wiki/Serenity_prayer) to accept the things you cannot change, courage to change the things you can, and wisdom to know the difference. -By [Klaus Marquardt](http://programmer.97things.oreilly.com/wiki/index.php/Klaus_Marquardt) \ No newline at end of file +By [Klaus Marquardt](http://programmer.97things.oreilly.com/wiki/index.php/Klaus_Marquardt) diff --git a/en/thing_65/README.md b/en/thing_65/README.md index 75575b39..0bb9df7d 100644 --- a/en/thing_65/README.md +++ b/en/thing_65/README.md @@ -20,7 +20,7 @@ Some_Number:= Distance + Velocity; -- Will be caught by the compiler as a type e Developers in less demanding domains might also benefit from applying more domain-specific typing, where they might otherwise continue to use the primitive data types offered by the language and its libraries, such as strings and floats. In Java, C++, Python, and other modern languages the abstract data type is known as class. Using classes such as `Velocity_In_Knots` and `Distance_In_Nautical_Miles` adds a lot of value with respect to code quality: -1. The code becomes more readable as it expresses concepts of a domain, not just Float or String. +- The code becomes more readable as it expresses concepts of a domain, not just Float or String. - The code becomes more testable as the code encapsulates behavior that is easily testable. - The code facilitates reuse across applications and systems. @@ -28,4 +28,4 @@ The approach is equally valid for users of both statically and dynamically typed The moral is to start exploring domain-specific types for the purpose of developing quality software. -By [Einar Landre](http://programmer.97things.oreilly.com/wiki/index.php/Einar_Landre) \ No newline at end of file +By [Einar Landre](http://programmer.97things.oreilly.com/wiki/index.php/Einar_Landre) diff --git a/en/thing_76/README.md b/en/thing_76/README.md index a2d41280..6929cc1b 100644 --- a/en/thing_76/README.md +++ b/en/thing_76/README.md @@ -36,6 +36,6 @@ The simple partitioning shown above resolves the issues. Each of these classes c The astute reader will see that there are still dependencies in the above solution. That `Employee` is still depended upon by the other classes. So if `Employee` is modified, the other classes will likely have to be recompiled and redeployed. Thus, `Employee` cannot be modified and then independently deployed. However, the other classes can be modified and independently deployed. No modification of one of them can force any of the others to be recompiled or redeployed. Even `Employee` could be independently deployed through a careful use of the *Dependency Inversion Principle* (DIP), but that's a topic for a [different book](http://www.amazon.com/dp/0135974445/). -Careful application of the SRP, separating things that change for different reasons, is one if the keys to creating designs that have an independently deployable component structure. +Careful application of the SRP, separating things that change for different reasons, is one of the keys to creating designs that have an independently deployable component structure. -by [Uncle Bob](http://programmer.97things.oreilly.com/wiki/index.php/Uncle_Bob) \ No newline at end of file +by [Uncle Bob](http://programmer.97things.oreilly.com/wiki/index.php/Uncle_Bob) diff --git a/en/thing_83/README.md b/en/thing_83/README.md index c3fe3d09..52ad01a5 100644 --- a/en/thing_83/README.md +++ b/en/thing_83/README.md @@ -6,6 +6,6 @@ Compared to "hard" engineering, the software development world is at about the s Testing "hard" things is tough because you have to build them to test them, which discourages speculative building just to see what will happen. But the building process in software is ridiculously cheap. We've developed an entire ecosystem of tools that make it easy to do just that: unit testing, mock objects, test harnesses, and lots of other stuff. Other engineers would love to be able to build something and test it under realistic conditions. As software developers, we should embrace testing as the primary (but not the only) verification mechanism for software. Rather than waiting for some sort of calculus for software, we already have the tools at our disposal to ensure good engineering practices. Viewed in this light, we now have ammunition against managers who tell us "We don't have time to test." A bridge builder would never hear from their boss "Don't bother doing structural analysis on that building — we have a tight deadline." The recognition that testing is indeed the path to reproducibility and quality in software allows us as developers to push back on arguments against it as professionally irresponsible. -Testing takes time, just like structural analysis takes time. Both activities ensure the quality of the end product. It's time for software developers to take up the mantle of responsibility for what they produce. Testing alone isn't sufficient, but it is necessary. Testing * **is** * the engineering rigor of software development. +Testing takes time, just like structural analysis takes time. Both activities ensure the quality of the end product. It's time for software developers to take up the mantle of responsibility for what they produce. Testing alone isn't sufficient, but it is necessary. Testing *is* the engineering rigor of software development. -By [Neal Ford](http://programmer.97things.oreilly.com/wiki/index.php/Neal_Ford) \ No newline at end of file +By [Neal Ford](http://programmer.97things.oreilly.com/wiki/index.php/Neal_Ford) diff --git a/en/thing_95/README.md b/en/thing_95/README.md index 1a95f56c..7ba49719 100644 --- a/en/thing_95/README.md +++ b/en/thing_95/README.md @@ -5,11 +5,11 @@ You are writing automated tests for some or all of your production code. Congrat Good tests act as documentation for the code they are testing. They describe how the code works. For each usage scenario the test(s): 1. Describe the context, starting point, or preconditions that must be satisfied -- Illustrate how the software is invoked -- Describe the expected results or postconditions to be verified +2. Illustrate how the software is invoked +3. Describe the expected results or postconditions to be verified Different usage scenarios will have slightly different versions of each of these. The person trying to understand your code should be able to look at a few tests and by comparing these three parts of the tests in question, be able to see what causes the software to behave differently. Each test should clearly illustrate the cause and effect relationship between these three parts. This implies that what isn't visible in the test is just as important as what is visible. Too much code in the test distracts the reader with unimportant trivia. Whenever possible hide such trivia behind meaningful method calls — the Extract Method refactoring is your best friend. And make sure you give each test a meaningful name that describes the particular usage scenario so the test reader doesn't have to reverse engineer each test to understand what the various scenarios are. Between them, the names of the test class and class method should include at least the starting point and how the software is being invoked. This allows the test coverage to be verified via a quick scan of the method names. It can also be useful to include the expected results in the test method names as long as this doesn't cause the names to be too long to see or read. It is also a good idea to test your tests. You can verify they detect the errors you think they detect by inserting those errors into the production code (your own private copy that you'll throw away, of course). Make sure they report errors in a helpful and meaningful way. You should also verify that your tests speak clearly to a person trying to understand your code. The only way to do this is to have someone who isn't familiar with your code read your tests and tell you what they learned. Listen carefully to what they say. If they didn't understand something clearly it probably isn't because they aren't very bright. It is more likely that you weren't very clear. (Go ahead and reverse the roles by reading their tests!) -by [Gerard Meszaros](http://programmer.97things.oreilly.com/wiki/index.php/Gerard_Meszaros) \ No newline at end of file +by [Gerard Meszaros](http://programmer.97things.oreilly.com/wiki/index.php/Gerard_Meszaros) diff --git a/en/thing_96/README.md b/en/thing_96/README.md index d6cc6dcc..58a880ff 100644 --- a/en/thing_96/README.md +++ b/en/thing_96/README.md @@ -1,4 +1,4 @@ -# You Gotta Care about the Code +# You Gotta Care About the Code It doesn't take Sherlock Holmes to work out that good programmers write good code. Bad programmers... don't. They produce monstrosities that the rest of us have to clean up. You want to write the good stuff, right? You want to be a good programmer. @@ -20,4 +20,4 @@ You want to write good code. You want to be a good programmer. So, you care abou Fortunately, you're reading this collection of advice because you do care about code. It interests you. It's your passion. Have fun programming. Enjoy cutting code to solve tricky problems. Produce software that makes you proud. -By [Pete Goodliffe](http://programmer.97things.oreilly.com/wiki/index.php/Pete_Goodliffe) \ No newline at end of file +By [Pete Goodliffe](http://programmer.97things.oreilly.com/wiki/index.php/Pete_Goodliffe) diff --git a/fa/README.md b/fa/README.md new file mode 100644 index 00000000..3539d24c --- /dev/null +++ b/fa/README.md @@ -0,0 +1,11 @@ +97 چیزی که هر برنامه نویس باید بداند +====== + +*مروارید حکمت برای برنامه نویسان جمع آوری شده از تمرین کنندگان برجسته.* + + +این یک [گیت بوک](https://www.gitbook.io) بر اساس کتاب [97 Things Every Programmer Should Know project](http://programmer.97things.oreilly.com/wiki/index.php/97_Things_Every_Programmer_Should_Know) است. + +[فهرست کتاب](SUMMARY.md) + +همه محتوا تحت مجوز [Creative Commons Attribution Non Commercial Share Alike 3.0 license](http://creativecommons.org/licenses/by-nc-sa/3.0/) است. نسخه های چاپی کتاب را میتوانید در [Amazon.com](http://www.amazon.com/Things-Every-Programmer-Should-Know/dp/0596809484) بیابید. diff --git a/fa/SUMMARY.md b/fa/SUMMARY.md new file mode 100644 index 00000000..647809fb --- /dev/null +++ b/fa/SUMMARY.md @@ -0,0 +1,100 @@ +# فهرست چیزها! + +* [مقدمه](README.md) +1. [ بدهی فنی](thing_01/README.md) +1. [به کار گیری اصولی توابع برنامه نویسی](thing_02/README.md) +1. [نیاز کاربر چیست؟](thing_03/README.md) +1. [ استاندارهای کدنویسی](thing_04/README.md) +1. [زیبایی در سادگی است](thing_05/README.md) +1. [قبل از انجام ریفکتورینگ دقت کنید](thing_06/README.md) +1. [در دستکاری کدها و منابع مشترک بین پروژه ها محتاط باشید.(نظافت را رعایت کنید!)](thing_07/README.md) +1. [پیش از آن که دیگران را متهم کنید، کد خود را چک کنید!](thing_08/README.md) +1. [انتخاب ابزار مناسب](thing_09/README.md) +1. [برنامه های خود را به زبان مشتریان بنویسید!](thing_10/README.md) +1. [طرح‌های خود را بی‌نقص کنید](thing_11/README.md) +1. [به چیدمان کدها توجه کنید!](thing_12/README.md) +1. [نقد و بررسی کدها](thing_13/README.md) +1. [کامنت‌گذاری را فراموش نکنید](thing_14/README.md) +1. [تنها توضیحاتی را بنویسید که کدهایتان قادر به شرح آنها نباشند!](thing_15/README.md) +1. [از کدهای قبلی خود در شرایط مناسب مجدداً استفاده کنید](thing_16/README.md) +1. [همواره در حال یادگیری موضوعات جدید باشید](thing_17/README.md) +1. [ویژگی‌های یک API با طراحی مناسب](thing_18/README.md) +1. [از ابتدای کار توسعهٔ اپلیکیشن خود روی فرآیند نصب و دیپلوی آن به طور پیوسته کار کنید](thing_19/README.md) +1. [مدیریت اکسپشن‌ها](thing_20/README.md) +1. [ تمرین آگاهانه لازمهٔ حرفه‌ای شدن است!](thing_21/README.md) +1. [ پشت هر خط از کد شما می‌بایست یک منطق وجود داشته باشد!](thing_22/README.md) +1. [مفهوم DSL چیست و چرا آشنایی با آن در حوزهٔ برنامه‌نویسی اهمیت دارد؟](thing_23/README.md) +1. [از ساختارشکنی نترسید!](thing_24/README.md) +1. [برای تست نرم‌افزار از دیتای واقعی استفاده کنید](thing_25/README.md) +1. [حتی یک ارور را هم نادیده نگیرید!](thing_26/README.md) +1. [فرهنگ استفاده از یک زبان برنامه‌نویسی را در کنار سینتکس آن بیاموزید](thing_27/README.md) +1. [اکسپش‌ها را به راحت‌ترین شکل ممکن هَندل کنید](thing_28/README.md) +1. [فرایند توسعه یک نرم‌افزار خوب اصلاً شانسی نیست](thing_29/README.md) +1. [آشنایی با قانون DRY](thing_30/README.md) +1. [شنایی با مراحل توسعهٔ نرم‌افزار](thing_31/README.md) +1. [به‌کارگیری درست از اصول برنامه‌نویسی شیٔ‌گرا](thing_32/README.md) +1. [اعداد اعشاری با خطای محاسباتی در کامپیوتر ذخیره می‌شوند](thing_33/README.md) +1. [جاه طلبی خود را با شرکت در پروژه های متن باز برآروده کنید.](thing_34/README.md) +1. [قانون طلایی طراحی API](thing_35/README.md) +1. [اسطوره ها!](thing_36/README.md) +1. [کار سخت نتیجه همیشه بهترین نتیجه را نمی دهد](thing_37/README.md) +1. [چگونه به یک باگ نگاه کنیم؟](thing_38/README.md) +1. [کد را با حذف آن بهبود دهید!](thing_39/README.md) +1. [من را نصب کن](thing_40/README.md) +1. [تعداد بالای فرآیندهای داخلی برنامه قطعاً روی کارایی برنامه تاثیر خواهند داشت](thing_41/README.md) +1. [نظافت را رعایت کنید](thing_42/README.md) +1. [نحوه استفاده از ابزارهای خط فرمان را بیاموزید](thing_43/README.md) +1. [بیش از دو زبان برنامه نویسی را به خوبی بلد باشید](thing_44/README.md) +1. [به IDE خود مسلط باشید](thing_45/README.md) +1. [محدودیت های خود را بشناسید](thing_46/README.md) +1. [با آگاهی از قدم بعدی قدم فعلی را بردارید](thing_47/README.md) +1. [داده های بزرگ به هم پیوسته متعلق به یک پایگاه داده](thing_48/README.md) +1. [زبان های خارجی را یاد بگیرید، حداقل انگلیسی](thing_49/README.md) +1. [تخمین زدن را بیاموزید](thing_50/README.md) +1. [گاهی مسائل و مشکلات بزرگ را به قسمت های کوچکتر بشکنید و با تکه های کوچک سعی و خطا کنید!](thing_51/README.md) +1. [طوری کد بزنید که پروژه ی شما خودش معرف خودش باشد](thing_52/README.md) +1. [چیزهای اضافی را لود نکنید!](thing_53/README.md) +1. [چه‌موقع و چگونه از راه‌کارهای موقتی در کدنویسی استفاده کنیم؟](thing_54/README.md) +1. [سعی کنید Interface ها را طوری بنویسید که برای استفاده ی صحیح آسان باشند و برای استفاده ی ناصحیح سخت!](thing_55/README.md) +1. [موارد نامرئی را بیشتر قابل مشاهده(شفاف سازی) کنید](thing_56/README.md) +1. [ضرورت آشنایی با مفاهیم کانکارنسی و پاراللیزم](thing_57/README.md) +1. [یافتن راه‌کارهای ساده برای مشکلات سخت](thing_58/README.md) +1. [دولوپری که نداند Polymorphism چیست، دولوپر نیست!](thing_59/README.md) +1. [اخبار عجیب و غریب : تستر دوست شماست!🤣](thing_60/README.md) +1. [همواره یک نسخه از نرم‌افزار برای ریلیس داشته باشید](thing_61/README.md) +1. [فقط کد حقیقت را می گوید](thing_62/README.md) +1. [فقط کد نزنید بلکه Build Process را نیز مدنظر قرار دهید](thing_63/README.md) +1. [اهمیت برنامه‌نویسی دونفره](thing_64/README.md) +1. [آشنایی با تفاوت Static Typing و Dynamic Typing در برنامه‌نویسی](thing_65/README.md) +1. [تا حد ممکن از نمایش ارورها برای کاربر اجتناب کنید!ا](thing_66/README.md) +1. [برنامه نویس حرفه ای](thing_67/README.md) +1. [همه چیز را روی سییستم های کنترل نسخه قرار بدهید](thing_68/README.md) +1. [ماوس را زمین بگذارید و از صفحه کلید فاصله بگیرید!](thing_69/README.md) +1. [کد را بخوانید](thing_70/README.md) +1. [علوم انسانی بخوانید!](thing_71/README.md) +1. [تا حد ممکن دست به اختراع مجدد چرخ نزنید!](thing_72/README.md) +1. [در مقابل وسوسه الگوی Singleton مقاومت کنید](thing_73/README.md) +1. [وابستگی‌های زیاد دشمن ریفکتورینگ هستند!](thing_74/README.md) +1. [سادگی از اختصار می آید(کم گوی و گزیده گوی!)](thing_75/README.md) +1. [آشنایی با قانون Single Responsibility](thing_76/README.md) +1. [همه‌ چیز با یک آری شروع می‌شود!](thing_77/README.md) +1. [تا حد ممکن همه‌ چیز را خودکار کنید](thing_78/README.md) +1. [از مزایای ابزارهای تحلیل کد بهره ببرید](thing_79/README.md) +1. [در تست نرم‌افزار فقط رفتار مورد انتظار را بسنجید](thing_80/README.md) +1. [تست‌ها علاوه بر صحیح بودن، می‌بایست دقیق هم باشند](thing_81/README.md) +1. [تست نرم‌افزار و سورس‌کد را آخر شب‌ها و آخر هفته‌ها انجام دهید!](thing_82/README.md) +1. [مقایسه‌ای مابین مهندسین نرم‌افزار و دیگر مهندسان](thing_83/README.md) +1. [از نوشتن کدهای اضافی پرهیز کنید](thing_84/README.md) +1. [اهمیت برنامه‌نویسی دونفره در کدنویسی را هرگز نادیده نگیرید](thing_85/README.md) +1. [منفی در مفنی می‌شود مثبت!](thing_86/README.md) +1. [کدنویسی تمیز و اصولی یک باید است](thing_87/README.md) +1. [ ابزارهای یونیکسی دوست دولوپرها هستند!](thing_88/README.md) +1. [استفادهٔ درست از الگوریتم‌ها و دیتا استراکچرها](thing_89/README.md) +1. [با لاگ‌گیری Verbose دچار دردسر خواهید شد!](thing_90/README.md) +1. [درک تفاوت مفاهیم DRY و WET در کدنویسی بهینه](thing_91/README.md) +1. [زمانی که برنامه نویسان و تسترها با هم همکاری کنند!](thing_92/README.md) +1. [طوری کد بنویسید که انگار باید تا آخر عمر برای آن پشتیبانی بدهید](thing_93/README.md) +1. [تا حد ممکن فانکشن‌های کوچک بنویسید](thing_94/README.md) +1. [برای دولوپرها تست بنویسید نه برای ماشین‌ها!](thing_95/README.md) +1. [مراقب سورس‌ کد باشید!](thing_96/README.md) +1. [منظور مشتریان شما چیزی نیست که می گویند!](thing_97/README.md) diff --git a/fa/thing_01/README.md b/fa/thing_01/README.md new file mode 100644 index 00000000..0c45026a --- /dev/null +++ b/fa/thing_01/README.md @@ -0,0 +1,7 @@ +# بدهی فنی (Technical Debt) + +پیش می‌آید که می بایست مابین «انجام اصولی یک پروژه» و «انجام سریع یک پروژه» یکی را انتخاب کنیم و در ابتدای کار سرعت بخشیدن به فرایند طراحی یک پروژه جذاب‌تر به نظر می‌رسد با این استدلال که بعداً هم می‌شود مجدد به کدها سر زد و اگر مشکلی داشت آن ها را از بین برد! اما تجربه نشان داده است زمانی که در بر گیرنده واژه ی بعداً است، خود حاوی بسیاری باگ ها و مشکلات خواهد بود که برنامه نویس مجبور است بیشتر تمرکز خود را روی آن‌ها بگذارد و از توجه به مشکلات -هرچند جزئی- گذشته باز می ماند. + +چنین سیاستی در برنامه نویسی اصطلاحاً Technical Debt گفته می‌شود که به صورت تحت الفظی می‌توان آن را به «بدهی فنی» ترجمه کرد (توجه داشته باشید که در واژه انگلیسی Debt حرف b تلفظ نمی شود!) این بدهی فنی اصلاً چیز خوبی نیست و گاهی اوقات منجر به بوجود آمدن فجایعی در تولید نرم افزار می شود. برای روشن شدن این مسأله مثالی می زنیم. بدهی فنی همچون وام گرفتن است که در کوتاه مدت کار ما را راه می‌اندازد اما غافل از این که در آینده می بایست با بهره ای که روی آن می‌آید -مثلا 30 درصد بیشتر- قرض خود را پرداخت کنیم (راستی می گن در برخی کشورهایی که مسلمان نیستند بهره بانکی چیزی در حدود یکی دو درصد است در حالی که در ایران اسلامی ما گاها تا پنجاه درصد می رسد. آن‌ها مسلمانند یا ما. بگذریم!) + +در برنامه نویسی هم قضیه دقیقاً به همین صورت است. اگرچه گاهی اوقات می‌توان از راه کارهایی استفاده کرد که به کدنویسی ما سرعت بخشند اما این در حالی است که در آینده اضافه کردن ویژگی‌های جدیدی به پروژه را دشوار می‌سازد و به اصطلاح نمی‌توان به سادگی کدهای خود را Refactor کرد. جالب اینجا است که هرچه از زمان ایجاد این دست مشکلات بیشتر می گذرد، یافتن راه‌کار هم برای آن‌ها دشوارتر خواهد شد. اما اگر ما از زمان بندی پروژه عقب باشیم و مجبور باشیم سرعت عمل را بر کیفیت ترجیح دهیم چطور؟ توصیه ما این است که هرگز سیاست فدا کردن کیفیت کار به خاطر سرعت بخشیدن به آن را دنبال نکنید اما اگر واقعاً مجبور هستید، پس این کار را انجام دهید اما حتماً به خاطر داشته باشید که شما با این کار یک بدهی فنی برای خود ایجاد کرده‌اید که می بایست در اولین فرصت این بدهی خود را صاف کنید. برای این منظور هم، حتماً در مستندات پروژه این قضیه را ذکر کنید تا فراموش نشود که در غیر این صورت ممکن است مجبور شوید بهای گزافی بابت آن پرداخت کنید. diff --git a/fa/thing_02/README.md b/fa/thing_02/README.md new file mode 100644 index 00000000..6534f4a3 --- /dev/null +++ b/fa/thing_02/README.md @@ -0,0 +1,5 @@ +# برنامه نویسی تابعی یا Functional Programming + +برنامه نویسی تابعی یا Functional Programming در چند سال گذشته طرفداران بسیاری پیدا کرده است. این پارادایم عبارت است از روشی که در آن منطق به کار گرفته شده در برنامه به صورت توابع ریاضیاتی در نظر گرفته می شوند. درک صحیح این نوع پارادایم به طرز قابل توجهی کمک به ارتقاء کیفیت کدی که نوشته می‌شود خواهد کرد و چنانچه شما -به عنوان یک برنامه نویس- از اصول برنامه نویسی تابعی استفاده کنید، کیفیت برنامه‌ای که می نویسید دوچندان خواهد شد که در نهایت با تعداد خطوط کدی کمتری، نتیجه ای که نیاز دارید را به دست خواهید آورد. + +زمانی که در پروژه های خود از توابع استفاده می کنیم، مسئولیت های خاصی را می‌توان به هر تابع اختصاص داد و توابع با استفاده از آرگومان هایی که می گیرند، می‌توانند خروجی های مختلفی را در اختیار سایر بخش های برنامه قرار دهند. برنامه‌هایی که در آن‌ها از توابع به درستی استفاده شده باشد، نسبت به روش‌های سنتی برنامه نویسی به سادگی قابل Debug کردن هستند. برنامه نویسی تابعی در برنامه نویسی شیئ گرایی به خوبی جواب داده است اما این در حالی است که در تمامی موقعیت ها نمی‌توان از این پارادایم استفاده کرد. diff --git a/fa/thing_03/README.md b/fa/thing_03/README.md new file mode 100644 index 00000000..1b29a3c5 --- /dev/null +++ b/fa/thing_03/README.md @@ -0,0 +1,9 @@ +# نیاز کاربر چیست؟ + +همه کسانی که برنامه نویسی می‌کنند فکر می‌کنند که کاربران برنامه یا اپلیکیشنی که توسعه می دهند مثل ایشان فکر می‌کنند و بر این باورند که همان ارتباطی که خود ایشان با برنامه شان دارند را کاربران دیگر هم خواهند داشت که این ایده بس اشتباه است. چنین باوری از دید روانشناسی اصطلاحاً False Consensus Bias نامیده می شود. جالب است بدانیم وقتی کاربران به طرزی با برنامه نوشته شده توسط ما تعامل برقرار می‌سازند که بر خلاف انتظار ما است،‌ روی ایشان برچسب «یک کاربر غیر حرفه ای» را می زنیم! اما این در صورتی است که ما یک برنامه نویس غیر حرفه ای هستیم که نیازهای جامعه ی هدف خود را به خوبی تشخیص نداده ایم! + +آنچه مسلم است این که کاربران هرگز مثل برنامه نویسان فکر نمی‌کنند چرا که ایشان برخلاف توسعه دهندگان زمان کمتری را پای کامپیوتر می نشینند،‌ با نحوه کار کردن سیستم‌ها خیلی آشنایی ندارند، فاقد مهارت های حل مسأله هستند که اکثر برنامه نویسان از آن‌ها برخوردارند، با الگوهایی که برنامه نویسان برای طراحی و کدنویسی مورد استفاده قرار می‌دهند آشنا نیستند و غیره. به عبارت دیگر، ارتباطی که یک End User با یک برنامه یا اپلیکیشن دارد همچون ارتباطی است که یک برنامه نویس با یک خودرو دارد. درست است که برنامه نویس می‌داند که چگونه سوار خودرو شود، کمربند خود را ببندد و ...، اما این آقا یا خانم برنامه نویس هرگز نمی‌داند که سازوکار سیستم این خودرو به چه شکل است. + +برای رفع این مشکل، می بایست از یک کاربر عادی بخواهیم که به تعامل با برنامه، سایت یا اپلیکیشن ما بپردازد و نحوه ارتباط برقرار ساختن وی با نرم‌افزار را به دقت مورد بررسی قرار دهیم. در‌واقع می بایست ببینیم که نیازهای این کاربر چیست، کجاها به مشکل بر می خورد، در کدام بخش‌ها سردرگم می‌شود و … برای روشن شدن این مسأله مثالی می زنیم. زمانی که یک برنامه نویس به عنوان مثال سایتی را کدنویسی می کند، زمانی که در ناحیه کاربری به مشکلی برخورد می‌کند به طور حتم می‌داند که از چه طریق می بایست آن مشکل را رفع کرد اما این مسأله در مورد کابران عادی صدق نمی‌کند و ایشان ممکن است به محض برخورد با کوچک‌ترین مشکل، از هدف خود دست بکشند. نکته دیگری که می بایست همواره مد نظر قرار دهیم این است که در اکثر مواقع مابین آنچه کاربران واقعاً به آن نیاز دارند و آنچه بیان می‌کنند یک شکاف وجود دارد. به عبارت دیگر و به قول مرحوم استیو جابز، این کاربران نیستند که می‌گویند چه می‌خواهند بلکه این شما به عنوان یک طراح هستید که می بایست به نیاز کاربران پی برده و نیاز ایشان را به بهترین شکل به ایشان عرضه کنید. + +برای رفع این مشکل، به جای گوش کردن به صحبت‌های کاربران، می بایست به تعامل ایشان با سایت، نرم‌افزار یا اپلیکیشن نگاه کرده و از روی رفتار ایشان با برنامهٔ‌مان، وی را نیاز سنجی کنیم. در یک کلام، اگر چند دقیقه به رفتار یک کاربر با برنامه خود نگاه کنیم، به مراتب مثمرالثمر تر از انجام یک مصاحبه چند ساعتی با چندین مخاطب بالقوه در مورد نیازهای ایشان خواهد بود. diff --git a/fa/thing_04/README.md b/fa/thing_04/README.md new file mode 100644 index 00000000..9586e719 --- /dev/null +++ b/fa/thing_04/README.md @@ -0,0 +1,38 @@ +# استاندارهای کدنویسی + +استاندارهای کدنویسی یا Coding Standards یکی از چیزهایی است که هر برنامه نویسی که قصد دارد لیبل حرفه‌ای رویش بخورد می بایست دنبال کند. پیروی از استانداردهای کدنویسی کار خیلی آسانی هم نیست و گاهی اوقات خیلی خسته‌کننده می‌شود اما واقعیت امر این است که در پروژه های نسبتاً بزرگ اعضای تیم نیاز دارند تا از یکسری قوانین تبعیت کنند. + +توجه داشته باشیم زمانی که یک سری قوانین کدنویسی -مثلا تعداد اسپیس هایی که می بایست در کدها استفاده کرد- را وضع می کنیم، تمامی اعضای تیم می بایست قبول کنند که از آن قوانین تبعیت کنند که در غیر این صورت، یک برنامه نویس خاطی می‌تواند هر چه سایر برنامه نویسان رشته کرده‌اند را پنبه کند! برای اعمال استانداردهای کدنویسی می‌توان از یکسری ابزارها هم استفاده کرد که فرایند استاندارد سازی را تا حد قابل توجهی برای برنامه نویس سهل و آسان می سازند که این ابزارها بسته به IDEیی که استفاده می کنیم می توانند از خصوصیات مختلفی برخوردار باشند. + +به عنوان نمونه، می‌توان زبان برنامه نویسی پی اچ پی را مثال زد. سایتی تحت عنوان php-fig.org استانداردی تحت عنوان PSR که مخفف واژگان PHP Standard Recommendation است را برای برنامه نویسان پی اچ پی طراحی کرده که علاقمندان با استفاده از این استانداردها می توانند از کدهایی برخوردار شوند که سایر برنامه نویسان پی اچ پی با نگاه کردن به کدهای ایشان کمتر دچار سردرگمی شوند. + +به طور مثال، کدی که در زیر مشاهده می کنید بر اساس استاندارد PSR نوشته شده است: + +```php + $b) { + $foo->bar($arg1); + } else { + BazClass::bar($arg2, $arg3); + } + } + + final public static function bar() + { + // method body + } +} +``` +در واقع، در کد بالا پس از namespace و دستورات use یک اینتر قرار گرفته است و یا این که علامت } مرتبط با کلاس Foo در خط بعد نوشته شده است. به عنوان مثالی دیگر، آرگومان های متد sampleFunction با یک کاما و اسپیس از یکدیگر مجزا شده اند و این در حالی است که کاما به آرگومان اول چسبیده، سپس یک فاصله قرار گرفته و در نهایت آرگومان دوم نوشته شده است. diff --git a/fa/thing_05/README.md b/fa/thing_05/README.md new file mode 100644 index 00000000..8efc1d0e --- /dev/null +++ b/fa/thing_05/README.md @@ -0,0 +1,7 @@ +# ساده زیباست + +جمله‌ای از افلاطون وجود دارد با این مضمون که «هارمونی، زیبایی ظاهری، ظرافت و موزون بودن همه و همه به سادگی بستگی دارند.» و این جمله اگر توسط برنامه نویسان به کار گرفته شود، مزایای بسیار زیادی برای ایشان در بر خواهد داشت که از آن جمله می‌توان به خوانایی بیشتر کدها، نگهداری راحت‌تر اسکریپت ها، افزایش سرعت کدنویسی و در نهایت کیفیت بالاتر کدهای نوشته شده اشاره کرد و تمامی این موارد -و حتی موارد بیشتر- جز با به کارگیری این دیدگاه افلاطون یعنی همان سادگی امکان‌پذیر نیست. + +حال می بایست به این سؤال پاسخ دهیم که به چه نوع کدی صفت زیبا اطلاق می گردد. این سؤال بسیار انتزاعی است چرا که مفهوم زیبایی چیزی کاملاً نسبی است. درکی که هنرمندان از زیبایی دارند به مراتب متفاوت تر از مهندسان یا برنامه نویسان است. لذا نیاز است تا مسئله ی زیبایی در برنامه نویسی را کمی بشکافیم! + +برای درک بهتر این موضوع، بهتر است سری به گیت هاب زده و برخی اسکریپت های نوشته شده توسط برنامه نویسان از نقاط مختلف جهان را مشاهده کنید. با مقایسه کدهای مختلف متوجه خواهید شد که برخی برنامه نویسان هستند که یکسری قوانین را به خوبی رعایت می‌کنند و همین مسأله منجر می‌گردد تا کدهای نوشته شده توسط ایشان زیبا‌تر به نظر برسد. جالب است بدانیم که هرچه کدی ساده‌تر باشد، در عین حال زیبا‌تر هم به نظر می رسد. اگرچه برخی برنامه‌ها هستند که بسیار پیچیده هستند و کارهای عجیب و غریبی انجام می‌دهند که آدمی را به شگفتی وا می دارند، اما اگر همین برنامه‌ها را به بخش‌های کوچک‌تری تقسیم‌بندی کنیم، خواهیم دید که اگر برنامه نویس آن برنامه مد نظر حرفه‌ای بوده باشد و به سادگی در کدنویسی ایمان داشته باشد، بخش‌های کوچک برنامه کاملاً ساده و قابل درک هستند، هر ماژول وظیفه ی مشخصی دارد، بخش‌های مختلف مثل کلاس ها، متدها و متغیرها به خوبی نامگذاری شده‌اند به طوری که اگر سایر برنامه نویسان هم به سورس کد نگاه کنند، به راحتی متوجه وظیفه هر بخش از کد خواهند شد. به طور خلاصه، کد زیبا کدی است که ساده باشد. بخش‌های مختلف نرم‌افزار می بایست دارای روابط ساده‌ای با سایر بخش‌ها بوده و به سادگی قابل درک باشند. diff --git a/fa/thing_06/README.md b/fa/thing_06/README.md new file mode 100644 index 00000000..f5d756ab --- /dev/null +++ b/fa/thing_06/README.md @@ -0,0 +1,15 @@ +# آشنایی با مفهوم ریفکتورینگ در کدنویسی + +یکی از چیزهایی که اکثر برنامه نویسان با آن رو به رو می‌شوند مفهومی است تحت عنوان Refactor که به معنی بازنویسی کدهایی است که پیش از این نوشته شده اند. نیاز به توضیح نیست تجربیاتی که یک برنامه نویس پس از چند سال کدنویسی کسب می‌کند قابل مقایسه با زمانی نیست که وی تازه شروع به کار کرده و مسلماً پس از چند صباحی که به کدهای خود نگاه کند، حالش از سبک کدنویسی خود به هم خواهد خورد و تصمیم می‌گیرد تا کدهای نوشته شده ی خود را اصطلاحاً Refactor کند. در این قسمت از آموزش، قصد داریم ببینیم که زمان مناسب برای بازنویسی کدهای پیشین چه موقع است و این در حالی است که اگر بدانیم چرا و چگونه این کار را انجام دهیم، در زمان ما به طرز قابل توجهی صرفه جویی خواهد شد. + +پیش از آن که اقدام به بازنویسی کدهای خود کنید، حتماً موارد زیر را مد نظر قرار دهید: همواره یکی از بهترین رویکردها نسبت به این که کدهای خود را بازنویسی کنیم یا نکنیم این است که کدها را با استفاده از تست هایی که برای آن‌ها می نویسیم تست کنیم چرا که با این کار به نقاط ضعف و قوت برنامه خود به خوبی پی برده و زمانی که بخواهیم کدها را Refactor کنیم، بخش‌هایی از کد که دارند به خوبی کار می‌کنند را دست کاری نخواهیم کرد اما در عین حال نقاط ضعف را برطرف خواهیم نمود. برنامه نویس ها همواره فکر می‌کنند که می‌توانند کدی بنویسند که بهتر از کد فعلی کار کند و این همان اشتباهی است که می بایست تا حد ممکن از آن اجتناب کرد. + +هشدار علاوه بر این، حتماً بایستی مقابل وسوسه بازنویسی هر سورس کدی ایستادگی کرد. همواره به خاطر داشته باشیم که بایستی تا حد ممکن از کدهای قبلی استفاده کنیم حتی اگر کدها تمیز نوشته نشده اند! زمانی که کدهای قبلی را پاک می کنیم، این بدان معنا است که ما ماه ها و یا سال‌ها تلاش و کدنویسی را هدر می دهیم. + +در فرایند بازنویسی کد، اعمال چندین تغییر ساختاری کوچک به مراتب بهتر از یک تغییر عمده است. به عبارت دیگر، تغییرات کوچک این امکان را به شما می‌دهند تا تأثیر آن تغییرات را روی برنامه خود راحت‌تر تست کرده و بازخورد آن‌ها را مشاهده نمایید. + +پس از تکمیل هر ماژول -یا بهتر بگوییم هر بخش از برنامه- سورس کد ما حتماً بایستی از سد چندین تست عبور کند. به محض این که یک تغییر جدید در کد خود ایجاد می کنید، حتماً تست آن تغییرات را هم بنویسید. در‌ واقع این تست ها عملکردی همچون End User دارند که گویی دارد با برنامه ما کار می‌کند و این اطمینان را حاصل می‌کنند نرم افزاری که به دست مشتری خواهد رسید بدون باگ است. در ضمن، هرگز تست های نرم افزاری قدیمی را پاک نکنید چرا که ممکن است در ماه های گذشته ایده خاصی مد نظر شما بوده که برای تست کردن آن یک Unit Test نوشته‌اید اما اکنون که دارید به بازنویسی کدها می پردازید، فکر شما اصلاً به سمت و سوی آن ایده خاص نرفته است. + +سعی کنید تا حد ممکن سلایق شخصی را وارد کدنویسی نکنید. اگر بخشی از کد دارد به درستی کار می کند، اصلاً نیازی به بازنویسی آن نیست. اگر کدهایی که نوشته‌اید تمیز نیستند، این اصلاً دلیل خوبی برای بازنویسی آن‌ها نیست. اگر هم کدهای پیش روی شما از برنامه نویس دیگری به شما به ارث رسیده، احتمال این که فکر کنید کدهای شما به مراتب بهتر از برنامه نویسی قبلی خواهد بود زیاد است که این هم اصلاً دلیل موجهی نیست! + +استفاده از فناوری های جدید هم اصلاً دلیل مناسبی برای Refactoring نیست. یکی از بدترین دلایلی که یک برنامه نویس برای بازنویسی کدها می‌تواند بیاورد این است که کدهای برنامه مربوط به فناوری های چندین سال پیش هستند و در حال حاضر نسخه نرم‌افزارها و زبان‌های برنامه نویسی استفاده شده در آن برنامه ی به‌ خصوص خیلی ارتقاء یافته اند. در چنین مواقعی حتماً می بایست به بررسی دقیق فریم ورک یا زبان برنامه نویسی مد نظر پرداخته تا ببینیم که آیا نسخه های جدید آن واقعاً بهبود یافته‌اند یا خیر. اگر واقعاً کمکی به بهبود عملکرد، نگهداری و راندمان نرم‌افزار می‌کردند که بایستی به بازنویسی کدها پرداخت و در غیر این صورت می بایست کدها را همان‌طور که هستند رها کرد. در پایان هم همواره به خاطر داشته باشید که آدم‌ها همیشه در معرض ارتکاب خطا هستند. بازنویسی کدها اصلاً بدان معنا نیست که کدهای جدید بهتر از کدهای قبلی یا به همان خوبی کدهای قبلی کار خواهند کرد! diff --git a/fa/thing_07/README.md b/fa/thing_07/README.md new file mode 100644 index 00000000..406bce18 --- /dev/null +++ b/fa/thing_07/README.md @@ -0,0 +1,9 @@ +# نظافت را رعایت کنید! + +برخی از آدم‌های متشخص هستند که وقتی زباله ای را روی زمین مشاهده می کنند، بدون توجه به این که چه کسی آن را روی زمین انداخته، زباله را برداشته و در جایگاه مخصوص به آن می اندازند (البته این قضیه بیشتر در کشورهای جهان اول مشاهده می گردد!) به عبارت دیگر، چنین افراد خیر خواهی، فضایی تمیز برای سایر افرادی که در آن محیط حضور خواهند داشت آماده می سازند. جمله‌ای وجود دارد با این مضمون که «دنیا را برای نسل ها آتی به مکان بهتری نسبت به آنچه تحویل شما داده شده مبدل سازید.» + +یک برنامه نویس خوب کسی است که وقتی کدهای یک برنامه نویس دیگر را تحویل می‌گیرد -فارغ از این که برنامه نویس قبلی چه کسی بوده- تمام تلاش خود را به کار خواهد بست تا کدها را بهبود بخشد و این در حالی است که این بهبود کار می‌تواند هم در زمینه بهبود راندمان کدها بوده و یا حتی در زمینه کامنت گذاری باشد. به نظر شما در چنین شرایطی نتیجه نهایی چه خواهد شد؟ + +به نظر می‌رسد که اگر برنامه نویسان دنباله روی چنین رویکردی باشند، روز به روز کیفیت کدهایی که نوشته می‌شوند بیشتر خواهد شد تا جایی که وجود باگ در کدها به یک امر انتزاعی مبدل خواهد شد. حال ممکن است این سؤال برای شما پیش بیاید که اگر برنامه نویس قبلی به جای کدنویس، … بود چه؟ در پاسخ به چنین سؤالی بایستی گفت که اصلاً نیاز نیست تا شما تمامی بخش‌های کد را بهبود ببخشید بلکه صرفاً نیاز است تا هر آنچه که از دست شما بر می‌آید را انجام دهید و یا حداقل کدهایی که به ماژول قبلی می افزایید را سعی کنید تمیز و مرتب بنویسید. این تمیز نویسی کدها می‌تواند به نام گذاری صحیح توابع و متغیرها، رعایت فاصله ها و … ختم گردد. + +در تیم های برنامه نویسی می بایست پس از اتخاذ رویکردی همچون آنچه در بالا به آن اشاره شد، فضایی ایجاد گردد که حتی اگر یکی از اعضای تیم خواست تا کدنویسی نامرتبی انجام دهد از سایر اعضای تیم خجالت کشیده و خود را اصلاح کند دقیقاً شبیه به شرایطی که در یک مهمانی مجلل اتفاق می افتد: آیا کسی رویش می‌شود که پس از خوردن خیار، پوست آن را روی پارکت پرتاب کند؟ هرگز! diff --git a/fa/thing_08/README.md b/fa/thing_08/README.md new file mode 100644 index 00000000..db4c74b3 --- /dev/null +++ b/fa/thing_08/README.md @@ -0,0 +1,5 @@ +# پیش از آن که دیگران را متهم کنید، کد خود را چک کنید! + +رفتاری رایج در میان اکثر برنامه نویسان دنیا این است که وقتی اسکریپتی می‌نویسند که کار نمی کند، پیش از هر چیز تقصیر را به گردن کامپایلر، وب سرویس و یا حتی سایر برنامه نویسان می‌اندازند که چنین رویکردی در اکثر مواقع نادرست است. اگرچه گاهی اوقات پیش می‌آید که مثلاً باگی در یک وب سرور مثل آپاچی به وجود می‌آید و همین مسأله منجر به بوجود آمدن مشکلی برای ما می‌شود، اما از آنجا که چنین نرم افزارهایی جهانی هستند و عدم وجود باگ در آن‌ها از اهمیت ویژه ای برخوردار است، توسعه دهندگان چنین نرم افزارهایی در اسرع وقت آن باگ را رفع خواهند کرد. لذا وقتی کد ما کار نمی کند، پیش از هر چیز و هر کس، می بایست انگشت اتهام را به سمت خودمان نگاه داریم … + +گاهی اوقات هم برای برنامه نویسان پیش می‌آید که با مشکلی مواجه می‌شوند و این در حالی است که ایشان از یک برنامه جدید متن باز که نسخه آن هم 0.1 است استفاده می کنند. در چنین شرایطی ایشان می‌توانند به عدم کارکرد صحیح نرم‌افزار یا سرویس مورد نظر خود شک کنند اما وقتی پای سرویس های با قدمت زیاد به میان می آید که گاها چندین میلیون کاربر در سرتاسر دنیا دارند، می بایست شکی به خود راه ندهیم که مشکل از خود ما است! diff --git a/fa/thing_09/README.md b/fa/thing_09/README.md new file mode 100644 index 00000000..89f47d45 --- /dev/null +++ b/fa/thing_09/README.md @@ -0,0 +1,30 @@ +# انتخاب ابزار مناسب + +بسیاری از نرم‌افزارها و اپلیکیشن هایی که ما امروزه می‌بینیم و به موفقیت‌های نسبتاً خوبی هم دست پیدا کرده‌اند هرگز کدنویسی آن‌ها از صفر شروع نشده است بلکه این دست نرم‌افزارها با استفاده از ابزارهای موجود -در اینجا منظور از ابزار کامپوننت ها، کتابخانه ها، فریم ورک ها و … است- ساخته شده اند. در همین راستا، زمانی که قصد شروع پروژه ای را داریم حتماً می بایست مناسب‌ترین ابزارها را برای پروژه خود انتخاب کنیم و هرچه پروژه ما بزرگ‌تر باشد، لزوم تحقیق در این زمینه نیز بیشتر خواهد شد. + +در ارتباط با دلایلی که چرا برخی از پروژه ها از صفر کدنویسی نمی‌شوند و در آن‌ها از کامپوننت ها و کتابخانه‌های موجود استفاده می شود، می‌توان موارد زیر اشاره کرد: + +1- نرم‌افزارها و اپلیکیشن ها در طول زمان رشد می کنند، پیچیده‌تر می‌شود و در نهایت نسبت به نسخه بتای خود به مراتب حرفه‌ای تر می‌شوند و این در حالی است که زمان اختصاص یافته برای توسعه این دست نرم‌افزارها و اپلیکیشن ها محدود و محدودتر می گردد. منطقی‌تر به نظر می‌رسد اگر برنامه نویسان بیشتر از آن که روی کدنویسی زیرساخت پروژه زمان صرف کنند (که در اکثر پروژه ها این زیرساخت تاحدودی مشابه است)، تمرکز خود را روی کدنویسی بخش‌های اختصاصی پروژه شان متمرکز سازند. + +2- کامپوننت ها و فریم ورک هایی که در سرتاسر دنیا مورد استفاده قرار می‌گیرند به مراتب دارای باگ های کمتری نسبت به کدهایی هستند که یک برنامه نویس فریلنسر در اتاق کارش می نویسد! + +3- بسیاری از فریم ورک های موجود در بازار به صورت رایگان در اختیار توسعه دهندگان قرار می‌گیرد و همین مسأله حاکی از آن است که هزینه‌های مرتبط با توسعه یک پروژه به مراتب کاهش خواهد یافت. + +4- توسعه زیرساخت پروژه در زمینه‌های مختلف مثل امنیت، راندمان و … کاری حساس، دقیق، زمان بر و پرهزینه است اما اگر شما از کامپوننت های متن باز و رایگان استفاده کنید، می توانید از به روزرسانی به هنگام و ساختاری پروژه خود اطمینان حاصل کنید. + +به خاطر داشته باشید +توجه داشته باشیم که شرکت فیسبوک ابتدا برای برنامه نویسی این شبکه ی اجتماعی از زبان برنامه نویسی PHP استفاده کرد اما پس از آن که این شبکه جای خود را در میان کاربران باز کرد و به درآمدزایی هنگفتی دست یافت، مدیران این شرکت تصمیم گرفتند زبان اختصاصی این شرکت تحت عنوان Hack را توسعه داده و شبکه ی اجتماعی فیسبوک را روی آن بنا کنند. + +آنچه مسلم است این که انتخاب ترکیبی از ابزارهای موجود برای توسعه اپلیکیشن خود کاری حساس بوده و نیازمند برخورداری از تجربه در این زمینه است. برای همین منظور، راه کارهایی را در ادامه برای شما آورده‌ایم که می‌تواند به شما در انتخاب ابزار مد نظرتان کمک شایانی کند: + +*- هر ابزاری در یک بستر خاص بهترین اثربخشی را خواهد داشت. منظور ما در اینجا از بستر عبارت است از ساختار دیتابیس، پروتوکل های ارتباطی، سرور،‌ وب سرویس، ای پی آی و … پس این احتمال وجود دارد ابزاری که شما انتخاب کرده‌اید با بستر توسعه نرم افزاری تان همخوانی نداشته باشد و همین مسأله منجر به پیچیده‌تر شدن پروژه شما خواهد شد. + +*- ابزارهایی که امروزه مشاهده می‌کنیم از عمر مشخصی برخوردارند و زمانی که آپدیتی برای آن‌ها به بازار عرضه می‌شود و یا نسخه جدیدی از آن‌ها در دسترس توسعه دهندگان قرار می گیرد، ممکن است -اگر نگوییم حتماً همین‌طور است- شاهد تغییرات بسیاری نسبت به نسخه قدیمی باشیم که گاهی اوقات نسخه های جدید از یک ابزار خاص -مثلا یک فریم ورک برنامه نویسی- دارای تغییرات ساختاری زیادی نسبت به نسخه قبلی است که آن ها را اصلا غیر قابل مقایسه می کند. به طور مثال، فریم ورک برنامه نویسی تحت وب لاراول، در نسخه ۵ خود کاملاً ساختار این فریم ورک را تغییر داده و این در حالی است که اگر شما از نسخه ۴ این فریم ورک استفاده می‌کرده اید و حال قصد مهاجرت به آخرین نسخه را دارید، کل پروژه شما دستخوش تغییر خواهد شد (توجه داشته باشیم که هرچه تعداد فریم ورک ها و ابزارهای استفاده شده در پروژه ما بیشتر باشد، عمق این فاجعه هم بیشتر خواهد شد!) + +*- برخی از ابزارهای موجود نیازمند کانفیگ یا تنظیم کردن هستند که مسأله تنظیم کردن آن‌ها شاید نیازمند صرف وقت و هزینه قابل توجهی باشد. + +*- برخی از ابزارهای به اصطلاح رایگان آن طور که باید و شاید Free نیستند. در ابتدا ما تصور می‌کنیم که ابزار مد نظر ما کاملاً رایگان است و شروع به استفاده از آن می‌کنیم اما وقتی پروژه به جاهای حساس خود می‌رسد و نیازمند استفاده از کامپوننت های خاصی است، کاشف به عمل خواهد آمد که می بایست بخشی از سورس کد را از توسعه‌دهنده اصلی خریداری کنیم و همین مسأله می‌تواند آینده نرم‌افزار ما را تحت الشعاع قرار دهد. + +*- برخی از ابزارها پس از توسعه نرم‌افزار با آن‌ها برای ما محدودیت ایجاد می کنند. به طور مثال، برخی از لایسنس های نرم افزاری هستند که توسعه دهندگانی که از آن‌ها استفاده می‌کنند را ملزم به انتشار نرم افزارشان به علاوه سورس کد آن به صورت کاملا باز و رایگان می‌کنند که چنین محدودیتی مسلما برای خیلی از توسعه دهندگان خوشایند نخواهد بود! + +آنچه مسلم است این که تصمیم گیرنده نهایی خود شما خواهید بود لذا می بایست تا حد ممکن کدهایی که مرتبط با زیرساخت پروژه می‌شوند را با استفاده از بهترین ابزار یا فریم ورک موجود توسعه داده و کدهای مرتبط با ماژول اختصاصی پروژه خود را شخصاً کدنویسی کنید. diff --git a/fa/thing_10/README.md b/fa/thing_10/README.md new file mode 100644 index 00000000..bcb092f2 --- /dev/null +++ b/fa/thing_10/README.md @@ -0,0 +1,13 @@ +# برنامه های خود را به زبان مشتریان بنویسید! + +به عنوان یک برنامه نویس احتمالاً صاحبان صنایع و مشاغل مختلف به شما مراجعه می کنند و به شما سفارش کار می دهند. برای انجام این سفارشات که مربوط به فرآیند های کاری مشتریان می باشند، شما می توانید با استفاده از قابلیت های زبان های برنامه نویسی مختلف، آن فرآیند ها را مدل سازی کنید. به طور مثال ممکن است صاحب یک فروشگاه به شما سفارش برنامه ای برای کنترل کالاهای موجود در انبار فروشگاه بدهد. بنابراین شما باید یک انبار را مدل سازی کنید که کالاهای خریداری و ذخیره شده در آن ثبت شوند و بتوان وضعیت آن ها را تا زمانی که در انبار موجود باشند پیگیری کرد. توصیه ای که ما به شما داریم این است که در این موارد برنامه ی خود را به زبان مشتری سفارش دهنده بنویسید. + +منظور از این که برنامه ی سفارشی خود را به زبان مشتری بنویسید این است که در کدهای برنامه از اصطلاحات کسب و کار مشتری استفاده کنید و روابط و رویه های کاری او را در برنامه پیاده سازی کنید. بگذارید با مثال هایی موضوع را شفاف تر سازیم. مثال فروشگاه را در نظر بگیرید. برای مدل سازی کالاهای خریداری شده، باید متغیری تعریف کنیم که نام کالای جدید را در آن ذخیره کنیم تا بعداً در بخش های دیگر برنامه از آن استفاده شود. می دانیم که برای تعریف هر متغیر یا Variable در برنامه نویسی، نیاز به یک اسم داریم. بهترین کار این است که به جای استفاده از یک نام بی معنی، مثلاً x، نامی را انتخاب کنیم که معرف این باشد که قرار است چه چیزی در متغیر مد نظرمان ذخیره شده و در عین حال برای مشتری هم شناخته شده باشد. به طور مثال این متغیر را new_product_name نام گذاری کنیم و با ورود هر کالای جدید آن را در این متغیر ذخیره کنیم، +``` +new_product_name = "Icecream" +// or +new_product_name = "Pen" +``` +در مورد رویه ها نیز به همین ترتیب عمل کنیم. مثلاً این طور نیست که کارکنان انبار تمام اجناس خریداری شده را در یک قسمت نگه داری کنند، بلکه متناسب با نوع محصول، آن ها را در بخش های مختلف انبار می کنند. مواد غذایی فاسد شدنی را در سردخانه، کرم ها را در بخش لوازم بهداشتی، پارچه ها را در بخش منسوجات و . . . وقتی نوبت به شما می رسد تا این رویه را مدل سازی کنید، شاید با خود فکر کنید در این مدل مجازی کنار هم قرار دادن کالاهایی مثل مواد غذایی، لوازم بهداشتی، و غیره تأثیری روی آن ها نمی گذارد. بنابراین به جای آن که با صرف زمان بیش تر و نوشتن کدهای بیش تر، نام این محصولات را در جداول جداگانه ای در دیتابیس قرار دهید، تصمیم می گیرید تمام آن ها را در یک جدول قرار داده تا در زمانی که بخواهید وضعیت یک محصول را بررسی کنید، کدهای برنامه به جای چند جدول دیتابیس، یک جدول را بیش تر در دیتابیس نگردند. شاید این کار برای شما راحت باشد، اما این نکته را در نظر داشته باشید که این برنامه برای صاحب فروشگاه است، نه شما! + +بهتر است که کدهای شما صریحاً رویه های ذخیره سازی در انبار را شبیه سازی کنند. مزیت این نوع کدنویسی صریح و مطابق با روال های کاری مشتری آن است که اولاً، تصحیح خطاها و تغییرات مورد نیاز در برنامه را برای شما راحت تر می کند (حتی اگر فراموش کنید هر قطعه از کد شما چه طور و برای چه منظوری کار می کند، می توانید به رویه های کاری مشتری رجوع کنید و الگوریتم آن را رمز گشایی کنید) ثانیاً، اگر برنامه نویس دیگری جایگزین شما شود تا سیستم موجود را به روز رسانی کند، از طریق آشنایی با این رویه های کاری، منظور کدهای شما را به راحتی درک می کند و نیازی نیست که به شما مراجعه کند تا آن ها را تفسیر کنید یا این که بخواهد برنامه ی جدیدی که برای خودش قابل فهم باشد را بازنویسی کند! diff --git a/fa/thing_11/README.md b/fa/thing_11/README.md new file mode 100644 index 00000000..58f2950c --- /dev/null +++ b/fa/thing_11/README.md @@ -0,0 +1,13 @@ +# طرح‌های خود را بی‌نقص کنید + +در این مطلب قصد داریم در مورد یکی از بحران های کنونی در دنیای برنامه نویسی و طراحی نرم افزار صحبت کنیم. با پیشرفت تکنولوژی و افزایش وابستگی افراد و صنایع به کامپیوترها، جامعه ی برنامه نویسان با تقاضای فزاینده ای برای طراحی نرم افزارهای کاربردی مواجه شده اند. به طور طبیعی برنامه نویسی که بتواند کدهای خود را سریع تر بنویسند و نیازهای مشتریان بیش تری را پاسخگو باشد، بهره ی بیش تری از این بازار خواهد برد؛ اما همین موضوع سرعت انجام کارها مسئله ساز شده است و باید ببینیم این افزایش سرعت به چه قیمتی است. + +به خاطر داشته باشید که کدنویسی یک کار خلاقانه است و برنامه نویس در هر پروژه، طرحی نو خلق می کند. بنابراین برای خلق یک طرح باکیفیت و معتبر باید از قبل برنامه ریزی انجام شود، تمام جنبه های طرح به دقت بررسی شود، بهترین ابزارهایی که می توان برای اجرای طرح از آن ها استفاده کرد فراهم شوند، و در نهایت به دقت از تمام قابلیت ها و امکانات استفاده شود و پس از اتمام کار، نرم افزار طراحی شده را از جنبه های مختلف آزمود تا تمام باگ ها و نقص های آن برطرف شود. اما بحرانی که دنیای طراحی نرم افزارها با آن مواجه است این است که بسیاری از برنامه نویسان به دلیلی که در بالا به آن اشاره شد برای افزایش سرعت، این رویه ها را نادیده می گیرند. + +برخی از برنامه نویسان پس از قبول هر پروژه بلافاصله شروع به کدنویسی می کنند، بدون آن که طرح خاصی را در ذهن داشته باشند. در نوشتن هر قطعه از برنامه در لحظه به آن فکر می کنند که کدام دستور می تواند کار را پیش ببرد. بدون توجه به این که آیا کدهای نوشته شده از کیفیت و زیبایی لازم برخوردارند، و در صورتی که بتوانند تا حدودی به خواسته ی مد نظر مشتری دست یابند، کار را ادامه می دهند و تنها وقتی که به مشکلی برخورد کنند به تغییر کدها فکر می کنند. + +در واقع در این موارد برنامه نویس از قابل دسترس ترین امکانات زبان برنامه نویسی مد نظر خود استفاده می کند تا کارش را سرهم بندی کند و به سرعت تحویل مشتری دهد. مشتری ها هم که غالباً چیزی از طراحی نرم افزار نمی دانند تنها به سرعت کار توجه می کنند، و در انتهای کار ناگزیر متحمل نتایجی ناقص و ناکامل می شوند! + +شاید این نوع فعالیت ها در کوتاه مدت بتوانند بهره ای برای برنامه نویسان داشته باشند، اما باید بدانید که در بلند مدت برنامه نویسان حرفه ای را از برنامه نویسان غیر حرفه ای متمایز می سازند. بنابراین سعی کنید طرح های ماندگار و بااعتباری خلق کنید. ممکن است مشتری شما تا مدتی بعضی از قابلیت های نرم افزار را به کار نگیرد و درنتیجه متوجه نقایص احتمالی آن نشود، اما این وظیفه ی شما است که نرم افزار خود را به دقت بررسی کنید. + +باید بدانید که طراحی یک نرم افزار کامل نمی شود مگر آن که از جنبه های مختلف کیفیت آن را تست کنید و کارایی آن را زمانی که منتشر می شود کنترل کنید. زبان ها و تکنیک های پیشرفته ی طراحی کمک بزرگی به شما می کنند تا طرح های کامل و بدون نقصی خلق کنید و این حقیقت را بدانید که صرف نظر از کدها، طرح های بزرگ و عالی توسط برنامه نویسان بزرگی ایجاد می شوند که خود را وقف خبرگی در حرفه ی خود کرده اند! diff --git a/fa/thing_12/README.md b/fa/thing_12/README.md new file mode 100644 index 00000000..704208ff --- /dev/null +++ b/fa/thing_12/README.md @@ -0,0 +1,16 @@ +# به چیدمان کدها توجه کنید! + +اگر تجربه ی کدنویسی برنامه های نسبتاً بزرگ را داشته باشید حتماً متوجه شده اید که بیش تر وقت خود را به جای نوشتن کدهای جدید صرف مرور کدهای قبلی کرده اید تا تغییراتی را که لازم است در آن ها اعمال کنید و اشکالات آن ها را رفع نمایید. یکی از فاکتورهای مهمی که سرعت و کارایی شما را در مرور کدها تعیین می کند چیدمان کدها (Code Layout) است. یک چیدمان خوب با تورفتگی های صحیح و قرار دادن میزان فضای سفید مناسب، تفاوت چشمگیری را در مدت زمانی که طول می کشد تا دستورات یک کد را بررسی کنید و منظور آن ها را بفهمید ایجاد می کند. در این آموزش قصد داریم راه کارهایی را برای بهینه سازی نحوه ی چیدمان و آرایش کدها مطرح کنیم. + +پویش کدها را ساده تر کنید: +فرض کنید تیم شما برنامه ای نوشته است که چندین کلاس مختلف دارد. در هنگام اجرای کلاس های برنامه، برای کامپایلر تفاوتی ندارد که در بدنه ی کلاس ابتدا عناصر public تعریف شده اند یا عناصر private، یا این که ابتدا ثابت ها تعریف شوند یا فیلدها و یا متد ها؛ به عبارت دیگر، ترتیب قرار گرفتن اجزای یک کلاس برای کامپایلر تفاوتی ندارد، اما برای شما چه طور؟ + +باید بدانید که افراد غالباً در تطبیق الگوهای بصری خوب هستند، بنابراین یکی از رویکردهایی که می توانید با دنبال کردن آن، مرور کدهای خود را آسان تر کنید این است که الگویی برای قرار دادن عناصر برنامه در کدهای خود تعریف کنید و تمام اعضای تیم در زمان کدنویسی بخش های مختلف برنامه از آن الگو پیروی کنند. به عنوان نمونه، می‌توان زبان برنامه نویسی پی اچ پی را مثال زد. سایتی تحت عنوان php-fig.org استانداردی تحت عنوان PSR که مخفف واژگان PHP Standard Recommendation است را برای برنامه نویسان پی اچ پی طراحی کرده که علاقمندان با استفاده از این استانداردها می توانند از کدهایی برخوردار شوند که سایر برنامه نویسان پی اچ پی با نگاه کردن به کدهای ایشان کمتر دچار سردرگمی شوند + +برای روشن تر شدن این مسئله، از سایر زبان های برنامه نویسی هم چند مثال می زنیم. اکثر برنامه نویسان ++C ابتدا تعریف متدهای public را در بدنه ی کدهای خود قرار می دهند و در زیر آن ها متدهای private را، در حالی که این رویه در کدنویسی به زبان #C کاملاً برعکس است. البته توجه کنید که ما این الگوها را به طور تجربی در زمان یادگیری هر زبان از منابع آموزش دهنده دریافت کرده و ناخواسته از آن ها تبعیت می کنیم و پیروی از آن ها باعث می شود سایر برنامه نویسان هم به راحتی کدهای ما را بخوانند، با این حال شما می توانید استاندارد مخصوصی برای خود تعریف کنید تا تمام اعضای تیم از آن تبعیت کنند. + +چیدمان کدها را طوری تنظیم کنید که منظور کدها را برساند: +یکی از توصیه هایی که همیشه به برنامه نویسان می شود این است که در زمان نام گذاری کلاس ها، متغیرها، متدها، و سایر عناصر برنامه از اسامی با معنا استفاده کنند که تا حد ممکن نشان دهد که هر عنصر برنامه چه کاری انجام می دهد. باید بدانید که چیدمان کدها نیز باید به گونه ای باشد که تا جای ممکن منظور کدها را به روشنی مشخص کند. اگر شما کدهای خود را در یک ویرایش گر ساده ی متن بنویسید زحمت تنظیم چیدمان آن بر عهده ی خودتان است، اما امروزه بیش تر برنامه نویسان از محیط های توسعه ی یکپارچه (IDE) مثل اکلیپس استفاده می کنند که می توانند به صورت خودکار چیدمان کدها را تعیین می کنند. با این وجود توصیه ای که به شما داریم این است که همیشه در نظر داشته باشید که این ابزارها نمی توانند منظور شما را از کدهایی که نوشته اید بفهمند، بنابراین گاهی لازم است به صورت دستی تغییراتی را در چیدمان کدها ایجاد کنید تا منظور خود را شفاف سازید. + +چیدمان خود را تا جای ممکن فشرده سازید: +اکثر برنامه نویسان زمانی که در یک محیط توسعه کد می زنند هر کامند یا دستوری را در یک خط جداگانه وارد می کنند، تا جایی که می بینیم بیش تر دستورات حتی تا پایان خط هم ادامه پیدا نمی کنند، بنابراین در پایان کار برنامه ای با خطوط زیادی کد و فضاهای خالی بی شمار دارند. با این حال باید بدانید که بهترین رویکرد این است که چیدمان خود را -تا جایی که به خوانایی کدها لطمه ای نزند- فشرده سازید. مزیت این کار آن است که حرکت میان کدها راحت تر و سریع تر می شود (به خصوص در برنامه های بزرگ)، یا به طور مثال در برنامه های تحت وب حجم داده هایی که از سمت سرور به کلاینت ها ارسال می شود و یا زمان لود شدن صفحات را کاهش می دهد. diff --git a/fa/thing_13/README.md b/fa/thing_13/README.md new file mode 100644 index 00000000..d6877227 --- /dev/null +++ b/fa/thing_13/README.md @@ -0,0 +1,29 @@ +# نقد و بررسی کدها + +یکی از توصیه های مهمی که همواره به تیم های برنامه نویسی می شود برگزاری جلسات نقد و بررسی کدها است. بسیاری از سازمان ها و شرکت های نرم افزاری روی این موضوع تأکید ویژه ای دارند و برگزاری جلساتی از این دست در آیین نامه های فرآیند توسعه ی نرم افزاری آن ها آمده است و تبدیل به یک فرآیند رسمی اداری شده است، که تیم برنامه نویسی آن ها را ملزم به انجام این کار می کند. چنین تأکیدی دلالت بر اهمیت و کارایی این جلسات دارد. با این وجود، بیش تر تیم های برنامه نویسی به دلیل برخی مسائل تمایل زیادی به شرکت در این جلسات ندارند. در این آموزش قصد داریم به بررسی این مشکلات بپردازیم و راه کارهایی را برای برگزاری بهتر این جلسات ارائه دهیم. برنامه نویسانی که تجربه ی قبلی بدی در این زمینه داشته اند غالباً مسائلی از این دست را مطرح می کنند که: + +1- برخی انتقادات و نظرات در مورد کدها این احساس را در برنامه نویس ایجاد می کند که منتقد تنها قصد خراب کردن وجهه ی او را دارد و فرصتی را پیدا کرده است تا به شخصیت او حمله کند و کار او را به باد انتقاد بگیرد. + +2- برخی منتقدان به جای بررسی مسائل مهم و اساسی تنها روی ساختار و چیدمان کدها مثل نحوه ی تورفتگی ها تأکید می کنند. + +3- در بسیاری از مواقع منتقدان قبلاً کدها را مرور نکرده اند و بدون آمادگی قبلی وارد جلسه می شوند. + +4- گاهی تنها یک بخش نمونه از کدها بررسی شده و سایر بخش های مهم نادیده گرفته می شود. + +5- در برخی مواقع، تیم بررسی کدها را تا زمانی که بخش اصلی کدها کامل شود به تأخیر می اندازد و پس از آن به دلیل حجم زیاد اطلاعات، مرور کدها دیگر نه امکان پذیر است و نه اثربخش خواهد بود. + +6- در بعضی موارد چون اعضا با این دید وارد جلسه می شوند که قرار است تنها یک وظیفه ی اداری را به دستور مدیر انجام دهند، توجه چندانی به جریان جلسه ندارند و انرژی کافی را صرف پیش برد آن نمی کنند. + +7- در برخی جلسات هم افرادی به جلسه دعوت می شوند که هیچ ارتباطی با پروژه ندارند و این موضوع کمی برای توسعه دهندگان نگران کننده است چرا که ممکن است نظرات خامی به زبان آورند! + +مسائلی از این دست به علاوه خیلی موارد دیگر، موجب عدم تمایل توسعه دهندگان برای شرکت در این جلسات می شود. بنابراین تیم های برنامه نویسی باید به دنبال راه کارهایی برای برطرف کردن این مشکلات باشند تا بتوانند از مزایای آن بهره ببرند. + +اولین نکته ای که در مورد جلسات نقد و بررسی باید مورد توجه قرار گیرد این است که هدف چنین جلساتی صرفاً پیدا کردن خطاهای موجود در کدها نیست، بلکه این جلسات باید با هدف به اشتراک گذاری دانش و آگاهی در میان اعضای تیم و برقراری راهبردهای مشترک کدنویسی برگزار شوند. به اشتراک گذاری کدها با سایر برنامه نویسان احساس مالکیت مشترک کدها را در افراد به وجود می آورد. به این ترتیب، هر کسی تلاش می کند در کنار سایرین روی کدها کار کند و به جای آن که صرفاً به دنبال خطاها و غلط گیری باشد سعی کند کدها را بفهمد و منظور و هدف آن ها را دریابد و در پیش برد و بهبود آن ها همکاری کند. + +در طی جلسه نقد و بررسی سعی کنید آرام باشید و نظرات خود را با ملایمت بیان کنید و احترام سایرین را حفظ کنید. مطمئن شوید که نقدهای شما سازنده باشد، نه این که با زبان تلخ و صرفاً برای کنایه زدن به دیگران بیان شوند. نقش های متفاوت را در جلسه ی بازنگری بشناسید تا به این ترتیب اجازه ندهید مثلاً نظر مدیر گروه صرفاً به این دلیل که جایگاه سازمانی بالاتری نسبت به سایرین دارد نظرات دیگران را تحت تأثیر قرار دهد یا مانع بیان حقیقت شود. برای مثال یک نوع از تقسیم نقش ها می تواند به این صورت باشد که یکی از اعضا روی مستند سازی، دیگری روی استثنائات، و نفر سوم روی کارکردها و قابلیت استفاده ی کدها متمرکز شود. این شیوه کمک می کند تا مسئولیت نقد و بررسی بر عهده ی همه ی اعضای گروه باشد و همه ی شرکت کنندگان جلسه فعال باشند. + +بازنگری کدها را به صورت مرتب در هر هفته انجام دهید. چند ساعت از وقت خود را صرف شرکت در این جلسات کنید. به صورت گردشی منتقدان را انتخاب کنید. به اعضای تازه وارد تیم هم اجازه دهید در این جلسات حضور فعال داشته باشند. شاید تجربه ی کاری آن ها کم باشد، با این حال چون این افراد غالباً به تازگی از دانشگاه فارغ التحصیل شده اند و دانش و آگاهی جدیدی دارند می توانند زاویه ی دید متفاوتی را در گروه ایجاد کنند. البته حضور اعضای حرفه ای و متخصص هم امری ضروری است تا از این طریق بتوانند دانش و تجربه منحصر به فرد خود را به سایرین منتقل کنند. چنین افرادی می توانند کدهای مستعد خطا را با سرعت و دقت بیش تری نسبت به سایرین پیدا کنند. + +اگر همه ی کدهای نوشته شده توسط تیم برنامه نویسی از قراردادها و استانداردهای تعریف شده ای پیروی کنند که بتوان آن ها را با ابزارهای خاصی کنترل کرد، جریان بازنگری و مرور کدها راحت تر و سریع تر پیش می رود و از این طریق، تیم در جلسه ی بررسی وقت خود را برای شکل دهی و فرمت بندی کدها تلف نمی کند. + +شاید مهم ترین چیزی که به تیم ها کمک می کند تا از مزایای چنین جلساتی بهره مند شوند تبدیل کردن یک جلسه ی خسته کننده و کسالت آور به یک جلسه ی پر نشاط و مفرح باشد. اگر اعضای جلسه احساس کنند که موقعیت آن ها تهدید می شود، به سختی می توان انگیزه ی شرکت در جلسات بعدی را در آن ها ایجاد کرد. جلسات بررسی کدها باید به صورت غیر رسمی و با هدف اصلی انتقال دانش و اطلاعات در میان اعضا برگزار شوند. هرکس باید سعی کند به جای اظهار نظر طعنه آمیز و تحریک کننده، جوی صمیمی و به دور از استرس را ایجاد کند. مطمئن باشید برگزاری جلسات در چنین فضایی کیفیت کدها را بهبود می بخشد، رعایت استانداردها را تضمین می کند، و به عنوان یک ابزار آموزشی ارزشمند دانش و تجربه ی توسعه دهندگان را بالاتر می برد. diff --git a/fa/thing_14/README.md b/fa/thing_14/README.md new file mode 100644 index 00000000..8ec24321 --- /dev/null +++ b/fa/thing_14/README.md @@ -0,0 +1,16 @@ +# کامنت‌گذاری را فراموش نکنید + +یک برنامه ی کامپیوتری که به خوبی کدنویسی شده است باید این قابلیت را داشته باشد که خودش را به طور شفاف توضیح دهد که هر بخش اش چه کار می کند و رابطه ماژول های مختلف برنامه با یکدیگر به چه شکل است. به طور مثال، برنامه نویس می تواند با انتخاب اسامی مناسب و با معنا برای متغیرها، توابع، کلاس ها، و ...، و همچنین برای برقرار ساختن یک جریان منطقی در دستورات نوشته شده این امکان را فراهم سازد تا کدهای او برای سایر برنامه نویسان خوانا باشد. با این حال اگر مدتی از نوشتن کدها گذشته باشد خود برنامه نویس هم نمی تواند به راحتی و بلافاصله تنها با خواندن کدهایش هدف آن ها و این موضوع که کدها چه کاری انجام می دهند را بفهمد؛ بنابراین سایر برنامه نویسان هم حتماً در بررسی کدهای ایشان به منظور توسعه یا رفع باگ ها به مشکل بر خواهند خورند. این جا است که نقش توضیحاتی که در بدنه ی کدها قرار می گیرند یا همان Comment ها پر رنگ می شود و اضافه کردن آن ها در میان خطوط کدهای برنامه اهمیت ویژه ای برای برنامه نویسان پیدا می کند. + +بیش تر زبان های برنامه نویسی جدید سطح بالا، ابزارهایی در خود دارند که به خوبی می توانند یک برنامه را مستند سازی کنند. اگرچه استفاده از آن ها یک شروع خوب برای شفاف کردن هدف برنامه است با این وجود قطعاً تمام نیازهای برنامه نویس را رفع نخواهند کرد. مستندسازی باید در سراسر خطوط نوشته شده انجام گیرد تا به وضوح نشان دهد هر قطعه کد چه کاری را انجام خواهد داد. برای آن که بتوانیم توضیحات مناسب را در برنامه ی خود بگنجانیم، باید با شیوه های استاندارد درج کامنت که مشخص می کنند آن ها باید در کدام قسمت از بدنه ی کدها قرار داده شوند و چه اطلاعاتی را در بر داشته باشند آشنا باشیم که در این جا به بعضی از این استایل های استاندارد اشاره می کنیم: + +توضیحات سرآمد یا Header Comments: +هر برنامه باید با یک توضیح آغازین همراه باشد که به آن "توضیحات سرآمد" می گوییم. این توضیحات باید حاوی اطلاعاتی از این قبیل باشند: نام برنامه نویس، تاریخ، نام فایلی که برنامه در آن ذخیره می شود، توضیحی در مورد برنامه و نحوه ی اجرا و استفاده از آن. یکی از بهترین استراتژی ها برای نوشتن برنامه های بزرگ و پیچیده تقسیم کردن کدهای آن در مجموعه فایل های جداگانه ای به نام ماژول است که این کار بررسی و توسعه ی کدها را راحت تر می کند (به طور مثال، یک وبسایت میتواند از ماژول های Application, Tutorial, Blog, Wiki, Jobs, Forum و ... تشکیل شده باشد.) در این صورت هر فایل نیاز به توضیحات سرآمد دارد که شامل این اطلاعات می شود: نام برنامه نویس، تاریخ، نام فایلی که کدها در آن ذخیره می شوند. هم چنین در این توضیحات باید نام فایل های دیگری که کدهای ماژول کنونی به آن ها وابسته هستند، مثلاً کلاسی را از فایل دیگری به ارث می برند را هم بیاورید. + +توضیحات مربوط به توابع: +هر کلاس پیچیده به بخش های کوچک تری تقسیم می شود که به آن ها توابع می گویند و هر تابع مسئول انجام یک وظیفه ی خاص در برنامه است. پیش از معرفی هر تابع، توضیحاتی مربوط به آن نوشته می شود که اطلاعاتی از این قبیل را شامل می شود: تابع قرار است چه کاری را در برنامه انجام دهد، چه ورودی هایی لازم است که به تابع داده شود تا عملیات خود را اجرا کند، و این که تابع در نهایت چه تغییراتی را ایجاد می کند و خروجی آن چه خواهد بود یا اصطلاحاً این تابع چه چیزی را return می کند یا برمی گرداند. + +توضیحات بین خطوط یا Inline Comments: +به غیر از توضیحات سرآمد، لازم است که کامنت هایی را هم در بدنه ی کدهای خود وارد کنید تا به توسعه دهندگان دیگر امکان تصحیح خطاها یا توسعه ی کدها را در آینده بدهند. این گونه توضیحات به دو گروه تقسیم می شوند: توضیحات خطی که در کنار یک خط از سورس کد می آیند و توضیحاتی در مورد آن خط از کد می دهند -مثلاً در یک خط متغیری از جنس عددی تعریف می شود و در توضیح آن، دامنه ای که می تواند اختیار کند را می آوریم- و یا کامنت های بلوکی که شبیه به توضیحات سرآمد، به طور کامل کاری را که یک بخش یا بلوک از کدهای برنامه انجام می دهد را توضیح می دهند. + +هشدار توجه داشته باشید که دقت کنید توضیحات شما تنها منظور کدهایتان را روشن کنند نه این که آن ها را تحت الشعاع قرار دهند. بسیاری از برنامه نویسان تازه کار حتی برای واضح ترین و ابتدایی ترین کدها هم کامنت می نویسند که این کاری بس اشتباه است! نوشتن توضیحات زیاد و مفصل می تواند به مانعی برای خوانایی کدهای شما در آینده تبدیل شود. diff --git a/fa/thing_15/README.md b/fa/thing_15/README.md new file mode 100644 index 00000000..262fb356 --- /dev/null +++ b/fa/thing_15/README.md @@ -0,0 +1,11 @@ +# تنها توضیحاتی را بنویسید که کدهایتان قادر به شرح آنها نباشند! + +پیش از این در مورد "کامنت‌ گذاری را فراموش نکنید" در مورد لزوم افزودن کامنت به سورس کد برنامه ها و مستندسازی آن ها و برخی شیوه های استاندارد برای درج کامنت ها در برنامه ها صحبت کردیم. موضوع مهمی که در این میان وجود دارد توجه به این نکته است که با وجود تمام مزایایی که درج کامنت برای برنامه نویسان ایجاد می کند، گاهی استفاده ی نادرست از آن ها می تواند منجر به ناخوانایی کدها و حتی بروز برخی مشکلات شود. بنابراین آشنایی با نحوه ی کامنت گذاری صحیح اهمیت زیادی دارد و برنامه نویسان باید در کنار سایر مهارت های برنامه نویسی، مهارت نوشتن کامنت مناسب را هم کسب کنند. شاید بتوان گفت بخش عمده ای از این مهارت، آگاهی از این موضوع است که در کجا نباید از کامنت ها استفاده شود. + +اگر در ساختار کدها ایرادات و خطاهایی وجود داشته باشد، کامپایلرها، مفسرها و ابزارهایی از این قبیل آن ها را پیدا خواهند کرد. باگ های نرم افزاری هم توسط بازبین ها، تست کننده های نرم افزار، تحلیل گران -و حتی گاهی هم در زمان استفاده توسط کاربران- شناسایی شده و رفع می شوند. بنابراین اغلب نگرانی چندانی در مورد کدهایی که اجرا می شوند وجود ندارد، اما در مورد کامنت ها چنین نیست و از آن جا که این موارد در زمان اجرا نادیده گرفته می شوند، ممکن است وجود یک کامنت اشتباه در میان کدها که می تواند منجر به حواس پرتی و یا حتی ارائه ی اطلاعات غلط به برنامه نویس شود هرگز تشخیص داده نشود. + +بعضی از کامنت ها از نظر فنی مشکلی ندارند با این حال هیچ ارزشی برای برنامه نویس ایجاد نمی کنند. مثلاً کامنت هایی که دقیقاً اطلاعاتی را که از خود کد می توان به دست آورد را تکرار می کنند و تنها باعث شلوغی برنامه می شوند. یکی از کاربردهای کامنت قرار دادن در سورس کد این است که اگر بخواهیم قطعه کد خاصی در برنامه اجرا نشود آن را تبدیل به کامنت می کنیم تا در زمان اجرا نادیده گرفته شود. وجود چنین کدهایی نیز برنامه را شلوغ می کند و هیچ ارزشی برای برنامه نویس نخواهد داشت. به این موارد، باید کامنت های مربوط به نسخه و تاریخچه ی نرم افزار را هم افزود، چرا که این موارد به صورت دقیق تر توسط ابزارهای کنترل نسخه مشخص می شوند. + +یکی از معایبی که وجود بیش از حد کامنت اشتباه یا بی ارزش دارد این است که باعث می شود برنامه نویس ترجیح دهد تمام کامنت ها را نادیده بگیرد و با استفاده از ابزارها و امکانات مختلف آن ها را بپوشاند یا از میان کدهای برنامه حذف کند تا درگیر خواندن توضیحات بی ارزش نشود. واضح است که این کار باعث از دست رفتن کامنت های ضروری و ارزشمند نیز می شود، بنابراین بهترین کار این است که در زمان درج کامنت، دقت کنیم که با آن ها مثل کدهای خود رفتار کنیم. تنها کامنت هایی را درج کنیم که ارزشی برای خواننده ی کدها داشته باشند و در غیر این صورت آن ها را حذف یا مجدداً اصلاح کنیم. + +وقتی صحبت از کامنت ارزشمند می کنیم، باید بدانیم چه چیزی ارزش آفرین است. مفهوم کامنت ارزشمند -در کدنویسی- به چیزی اطلاق می شود که بیان کننده ی مواردی است که کدها قادر به بیان آن نباشند. درج توضیحات می تواند انگیزه ای باشد برای تغییر ساختار کد و قراردادهای کدگذاری به طوری که کدها بتوانند نحوه ی کار خودشان را تشریح کنند. به طور مثال، شاید خواندن توضیحات مربوط به عملکرد یک کلاس یا تابع باعث شود نام مناسب تری برای آن انتخاب کنید که این نام گویای تمام توضیحات باشد. یا به جای توضیح در مورد بخش های مختلف یک تابع تلاش کنید آن را به توابع کوچکتری تقسیم کنید که نام هر یک از این توابع تمام توضیحات بخش های قبلی را بیان کند. در نهایت این که باید تلاش کنیم در کامنت های خود تنها نکات لازمی را بگنجانیم که کدها نمی توانند آن ها را بیان کنند، نه نکاتی را که کدها آن ها را بیان نکرده اند، و تا حد ممکن باید از ظرفیت کدها استفاده شود، آن گاه به سراغ کامنت گذاری برویم. diff --git a/fa/thing_16/README.md b/fa/thing_16/README.md new file mode 100644 index 00000000..44eb49b8 --- /dev/null +++ b/fa/thing_16/README.md @@ -0,0 +1,23 @@ +# از کدهای قبلی خود در شرایط مناسب مجدداً استفاده کنید + +بسیاری از توسعه دهندگان حرفه ای نرم افزارها عادت دارند کدهایی بنویسند که اصطلاحاً Reusable یا دارای قابلیت استفاده ی مجدد باشند. وجود قابلیت استفاده ی مجدد در یک قطعه کد باعث می شود که بتوانیم در کدنویسی چندین برنامه ی مختلف از آن استفاده کنیم. وقتی می گوییم برنامه نویسان حرفه ای چنین قابلیتی را در کدهای خود وارد می کنند به نحوی مثبت بودن چنین چیزی را عنوان می کنیم، با این حال باید این موضوع به دقت بررسی شود و ببینیم که آیا این کاری تحت هر شرایطی درست است یا خیر؟ + +آیا استفاده ی مجدد از کدها همواره و تحت هر شرایطی مورد تأیید است؟ برای پاسخ به این سؤال باید از مزایا و معایب چنین کاری اطلاع پیدا کنیم و آن گاه با سبک و سنگین کردن شرایط، بین استفاده مجدد از کدهای از قبل نوشته شده و نوشتن کدهای جدید یکی را انتخاب کنیم. از این رو در این آموزش قصد داریم در مورد مزایا و معایب استفاده ی مجدد از کدها صحبت کنیم. + +مزایا +استفاده ی مجدد از کدها زمان کدنویسی را کاهش می دهد، که این امر موجب کاهش هزینه های یک پروژه ی برنامه نویسی خواهد شد. فرض کنید پیش از این خود شما یا تیم برنامه نویسی دیگری روی یک مسئله کار کرده و پاسخ بهینه ای برای آن یافته اید و اکنون این پاسخ در دسترس شما است. بنابراین دلیلی وجود ندارد که شما بخواهید مجدداً به دنبال جواب برای یک مسئله ی حل شده باشید. + +استفاده ی مجدد از کدهایی که قبلاً نوشته و امتحان شده اند باعث می شود میزان باگ های احتمالی برنامه تا حد زیادی کاهش پیدا کند. به طور کلی هر چه در یک برنامه خطوط کد بیش تری نوشته شود، احتمال وجود خطا در میان آن کدها بیش تر می شود. وقتی از یک قطعه کد در چندین برنامه ی مختلف استفاده می شود به نوعی بارها و بارها آن بخش مشترک در تمام برنامه ها تست می شود و به مراتب احتمال وجود خطا در آن کاهش پیدا می کند. + +معمولاً کدهایی که قابلیت استفاده ی مجدد دارند در قالب کتابخانه های نرم افزاری جداگانه تقسیم بندی می شوند، به نحوی که هر برنامه نویس می تواند بر اساس نیاز خود از این کتابخانه های آماده استفاده کند. مزیت این کار در آن است که هر برنامه نویس می تواند با توجه به نقاط قوت خود در یک زمینه ی خاص به صورت تخصصی کدنویسی کند. به طور مثال متخصصین بخش امنیت می توانند روی کدهای مربوط به این حوزه کار کنند و با تولید کتابخانه های قدرتمند نرم افزاری در زمینه ی امنیت آن ها را با دیگر برنامه نویسان به اشتراک بگذارند، این در حالی است که مثلاً متخصصان UI روی مسائل مربوط به طراحی و بهینه سازی واسط های کاربری متمرکز می شوند. استفاده ی مجدد از کدها به طور مناسب و کارآمد می تواند به جلوگیری از تکرارهای غیر ضروری و دستورات زائد کمک کند. + +معایب +با وجود تمام مزیت هایی که استفاده ی مجدد از کدها برای ما دارد بسته به شرایط مختلف امکان دارد این کار نه تنها فایده ای برای ما نداشته باشد، بلکه ضررهایی را هم به برنامه وارد کند. + +فرض کنید از یک کتابخانه از کدها در چند بخش مختلف از برنامه استفاده کنیم. این کار باعث می شود که وابستگی کدهای این بخش ها به هم زیاد شوند. اگر بخواهیم کدهای مشترک بعضی از این قسمت ها را تغییر دهیم یا اصلاح کنیم باید مراقب باشیم که این کار چه تأثیری روی سایر بخش ها می گذارد. + +این احتمال وجود دارد که کتابخانه یا فریم ورکی که می خواهید از آن در برنامه ی خود مجدداً استفاده کنید سرعتی پایین تر از حد انتظار داشته باشد و این بستگی به زبان برنامه نویسی یا پلتفرمی دارد که شما روی آن کار می کنید. + +اگر شما از کدهایی استفاده کنید که قبلاً توسط برنامه نویسان دیگر نوشته شده باشند مسائل مربوط به امنیت و میزان قابل اعتماد بودن آن ها و مسائل مربوط به مجوزهای استفاده مطرح می شود. به علاوه ارزیابی این کدها معمولاً زمان بر است و این امکان وجود دارد که شما بعد از گذشت یک زمان طولانی متوجه ضعف در طراحی و باگ های آن کدها شوید. + +مدیریت کدهایی که بین برنامه های مختلف به اشتراک گذاشته می شوند می تواند هزینه ی اضافی برای برنامه ایجاد کند. علاوه بر این، گاهی اوقات پیاده سازی و همگام سازی این کدها با کدهای خودتان بیش از حد زمان بر است و کار زیادی را طلب می کند. به هر حال شما به عنوان یک برنامه نویس باید این مهارت را پیدا کنید که با در نظر گرفتن تمام جوانب انتخاب کنید که آیا می خواهید چرخ را دوباره اختراع کنید، یا با کمی اصلاح و تطبیق آن با سورس کد خود، مجدداً از آن استفاده کنید. diff --git a/fa/thing_17/README.md b/fa/thing_17/README.md new file mode 100644 index 00000000..76141192 --- /dev/null +++ b/fa/thing_17/README.md @@ -0,0 +1,38 @@ +# همواره در حال یادگیری موضوعات جدید باشید + +زندگی ما در عصر تکنولوژی بسیار هیجان انگیز و جالب است. فناوری ها به سرعت در حال رشد هستند و هر روز اخباری از ابتکارات و دستاوردهای جدید در عرصه ی علم و تکنولوژی منتشر می شود. از سوی دیگر، شاهد آن هستیم که رشد تکنولوژی تأثیر زیادی هم در فرآیندهای یادگیری داشته است؛ به طور مثال اینترنت بستری را فراهم کرده است که کاربران را قادر می سازد به شبکه ی عظیمی از اطلاعات دسترسی پیدا کنند و با نوآوری های جدید آشنا شوند. + +این سرعت بالای رشد علمی و دسترسی آسان تر به منابع علمی سبب افزایش تعداد رقبای شغلی به ویژه در میان برنامه نویسان شده است. آن چه بیش از هر چیز دیگر اهمیت دارد آن است که ما متوجه این تغییرات و پیشرفت ها باشیم و بدانیم برای ادامه ی کار و رقابت با دیگر برنامه نویسانی که در بازار برنامه نویسی مشغول به فعالیت هستند، لازم است که دانسته های خود را دائماً به روز کنیم که در غیر این صورت روزی دانش ما آن قدر قدیمی می شود که عملاً در هیچ جا کاربرد نخواهد داشت. + +اگر به این باور رسیدیم که امروز هر اندازه هم که ما در کار خود حرفه ای باشیم در آینده ای نزدیک این سطح از اطلاعات و مهارت بسیار اندک خواهد بود و نسبت به سایر برنامه نویسان برای ما مزیت رقابتی ایجاد نخواهد کرد، باید به دنبال راه کارهایی برای افزایش دانش و مهارت خود باشیم. خوشبختانه برخی از کارفرمایان برای حمایت از منابع انسانی و کمک به کسب و کار خود با صرف هزینه و زمان اقدام به برگزاری دوره های آموزشی و بالا بردن سطح علمی و مهارتی نیروهای کار خود می کنند. با این حال شاید شما شانس کار با چنین تیم هایی را نداشته باشید و مجبور باشید خود به دنبال راه کاری برای یادگیری موضوعات جدید باشید. + +در این جا قصد داریم بعضی از روش های کاربردی و منابع مفید را به شما معرفی کنیم تا بتوانید با استفاده از آن ها سطح دانش و مهارت خود را به عنوان یک برنامه نویس افزایش دهید. لیست این پیشنهادات به قرار زیر است: + +1- کتاب و مجله بخوانید، از پست های وبلاگی، سایت ها، و فیدهای توئیتر که اخبار و موضوعات جدید حوزه ی نرم افزار و آی تی را بررسی می کنند بازدید کنید. سعی کنید پیوسته با جامعه ای از برنامه نویسان در ارتباط باشید. +2- اگر واقعاً می خواهید با یک تکنولوژی جدید آشنا شوید، دست خود را به آن آلوده کنید! شروع به کدنویسی کنید. تلاش کنید با امتحان کردن نرم افزارهای جدید به آن ها مسلط شوید. + +3- سعی کنید همیشه با کسانی کار کنید که چیزی بیش تر از شما بدانند، چون کار کردن در کنار افراد با هوش تر و با تجربه تر و نظارت آن ها بر کار شما هم انگیزه ی یادگیری را در شما ایجاد می کند و هم در تعامل با آن ها می توانید درس های زیادی بیاموزید و اطلاعات مفیدی به دست آورید. وقتی شما تنها در کنار افرادی باشید که سطحی پایین تر از شما دارند، هم انگیزه ی رقابتی خود را برای یادگیری از دست می دهید و هم این که احتمالاً تمام وقت خود را باید صرف آموزش به آن ها کنید که به نوعی مانع یادگیری موضوعات جدید خواهد بود. + +4- از کمک منتورهای مجازی استفاده کنید. افراد شناخته شده ای در فضای وب فعالیت می کنند که نویسندگان و توسعه دهندگان بزرگی هستند. فعالیت ها و نوشته های آن ها را در وب سایت ها و وبلاگ های ایشان دنبال کنید. بسیاری از این افراد به سؤالات دیگران پاسخ می دهند و شما می توانید از راهنمایی چنین کسانی که شاید حتی در قاره ای دیگر زندگی کنند به صورت مجازی استفاده کنید. + +5- شروع به یادگیری دقیق فریم ورک ها و کتابخانه هایی که از آن ها استفاده می کنید نمایید. آگاهی از روش دقیق کار یک چیز باعث می شود بفهمید که چگونه می توانید استفاده ی بهتری از آن داشته باشید. اگر آن ها متن باز باشند که بخت با شما یار است. به جستجو در سورس کد آن ها بپردازید، چون به هر حال توسط افرادی با هوش و با تجربه نوشته شده اند و خواندن آن ها دید بهتری به شما خواهد داد و الهام بخش ایده های جدیدی در ذهن شما خواهد بود. سعی کنید سورس کد سایت هایی را که طراحی خوبی دارند مشاهده کنید تا با نحوه ی طراحی آن ها نیز آشنا شوید. + +6- زمانی که اشتباهی انجام می دهید، به باگی در میان کدهای خود برخورد می کنید، یا با مشکلی در کدنویسی برنامه ی خود مواجه می شوید سعی کنید بفهیمد واقعاً چه اتفاقی افتاده است. ممکن است قبل از شما کسی با چنین مشکلی رو به رو شده باشد و بعد از یافتن راه حل، آن را روی فضای اینترنت به اشتراک گذاشته باشد. در این موارد جستجو در گوگل -و همچنین جستجو در سایت Stack Overflow- به شما کمک زیادی خواهد کرد. به علاوه سعی کنید شما هم یافته های خود را در اختیار دیگران قرار دهید. + +7- به گفته ی یک طنزپردازی: "کسانی که بر موضوعی تسلط کامل دارند از آن استفاده می کنند و با آن کار می کنند و کسانی که چیزی از آن نمی دانند همان موضوع را درس می دهند!" واقعیت این است که یکی از راه های یادگیری یک موضوع تدریس آن و صحبت کردن در مورد آن موضوع است. وقتی قرار باشد عده ای مخاطب شما باشند و از شما در مورد مطلبی سؤال بپرسند، انگیزه ی زیادی را برای یادگیری در شما ایجاد خواهد کرد. سعی کنید در مورد موضوعات و تکنولوژی های جدید اطلاعات به دست آورید و این اطلاعات را در جمع دوستان و همکاران به دیگران منتقل کنید. + +8- موضوعی را که به آن علاقمند هستید انتخاب کنید و سعی کنید با گروهی از افراد به مطالعه ی جمعی آن موضوع بپردازید. مطمئن باشید بواسطه ی همکاری با دیگران و استفاده از نظرات و تجربیات آن ها تاثیر این یادگیری جمعی به مراتب بیش تر از یادگیری انفرادی است. خوشبختانه با ظهور شبکه های گسترده ی اجتماعی می توان این فعالیت ها را در قالب تیمی و به صورت مجازی انجام داد. + +9- شرکت در کنفرانس ها هم گزینه ی مناسبی برای اطلاع از یافته ها و موضوعات علمی جدید است. حتی اگر امکان حضور فیزیکی در چنین کنفرانس ها و سمینارهایی را ندارید می توانید بسیاری از آن ها را به صورت آنلاین و بدون پرداخت هیچ هزینه ای دنبال کنید. + +10- آیا تا به حال از ابزارهای تحلیل کدهای برنامه استفاده کرده اید، یا توجهی به پیغام های اخطار محیط توسعه ای که در آن کدنویسی می کنید داشته اید؟ یک راه مناسب برای یادگیری این است که بفهمید آن ها چه می گویند و چرا چنین تحلیل هایی را روی کدهای شما دارند. + +11- به این توصیه ی برنامه نویسان حرفه ای عمل کنید که می گویند هر سال یک زبان برنامه نویسی جدید یاد بگیرید. حداقل با یک ابزار یا تکنولوژی جدید آشنا شوید و شیوه ی به کارگیری آن را بیاموزید. دانش در مورد تکنولوژی های جدید ایده های تازه ای را برای استفاده ی بهتر از تکنولوژی های کنونی به شما خواهد داد. + +12- این روزها همه می دانند که صرف یادگیری زبان های برنامه نویسی یا دانش استفاده ازتکنولوژی های جدید برای شما مزیت رقابتی ایجاد نخواهد کرد. شما باید با حوزه ای که در آن کار می کنید آشنایی کامل داشته باشید تا بتوانید نیازهای مشتریان خود را بشناسید. آگاهی از این که چه طور کارکرد مؤثرتر و نقش سازنده تری در محیط کاری داشته باشید نیز مفید خواهد بود. برای مثال این روزها بیش تر شرکت ها به دنبال برنامه نویسانی هستند که در کنار مهارت های کدنویسی با روش های Agile یا چابک نیز آشنایی داشته باشند. + +13- اگر شما هم جزء کسانی باشید که بخش زیادی از زمان خود را در رفت و آمد و ترافیک شهری از دست می دهند، می توانید با گوش کردن به فایل های صوتی و پادکست های آموزشی که به وفور روی اینترنت قابل دسترسی هستند این زمان های تلف شده را تبدیل به فرصت مناسبی برای یادگیری و کسب اطلاعات جدید نمایید. + +14- شاید بد نباشد که به ادامه ی تحصیل در دانشگاه هم فکر کنید. گرچه بسیاری از افراد عقیده دارند دانشگاه های کشور بازدهی مطلوبی ندارند و خروجی آن ها برنامه نویسانی که آماده ی ورود به بازار کار باشند نیست، با این وجود باید بدانید که اولاً کلاس های دانشگاهی قطعاً یک پایه ی علمی مستحکم برای اطلاعات شما ایجاد می کنند، ثانیاً هر کدام از ما می توانیم با انگیزه و علاقه ی خود تا حد زیادی به پویایی محیط های دانشجویی و نزدیک کردن صنعت و دانشگاه کمک کنیم. + +به هر حال تکنولوژی به سرعت در حال تغییر است و اگر بخواهیم از این قافله عقب نمانیم باید در کنار کار زمانی را هم به یادگیری دانش و اطلاعات جدید اختصاص دهیم. این زمان هر اندازه هم که کم باشد، حتی در حد چند ساعت در هفته، می تواند نتایج مفیدی را به بار آورد. diff --git a/fa/thing_18/README.md b/fa/thing_18/README.md new file mode 100644 index 00000000..5f297905 --- /dev/null +++ b/fa/thing_18/README.md @@ -0,0 +1,47 @@ +# ویژگی‌های یک API با طراحی مناسب + +امروزه بعید به نظر می رسد که کسی در دنیای برنامه نویسی دستی بر آتش داشته باشد اما اصطلاح API به گوش او نخورده باشد! اگر شما به عنوان یک برنامه نویس با ای پی آی ها کار کرده باشید از اهمیت آن ها مطلع هستید، با این حال سایر افراد ممکن است بپرسند که «اصلاً ای پی آی ها چه هستند و چرا تا این حد مورد توجه قرار می گیرند؟» در این آموزش به دنبال پاسخ دادن به این پرسش ها هستیم و می خواهیم ببینیم یک API خوش ساخت از چه ویژگی هایی برخوردار است. + +اگر بخواهیم تعریف ساده ای از API که مخفف عبارت Application Programming Interface ی «واسط برنامه نویسی اپلیکیشن»است داشته باشیم باید بگوییم که ای پی آی ها مجموعه مقرراتی هستند که مشخص می کنند چه طور یک اپلیکیشن می تواند با اپلیکیشن دیگری ارتباط برقرار کند. زمانی که از یک پی سی یا لپ تاپ استفاده می کنیم، ای پی آی ها همان چیزهایی هستند که انتقال اطلاعات را بین برنامه ها امکان پذیر می کنند، برای مثال ای پی آی های سیستمی، اجرای برنامه ای مانند آفیس ورد را روی سیستم عامل ویندوز امکان پذیر می سازند. + +همان طور که از نام API مشخص است، آن ها مانند یک رابط بین برنامه نویسان و یک اپلیکیشن هستند؛ به این صورت که اگر برنامه نویس برای پیش برد برنامه ی خود نیاز به اطلاعاتی از اپلیکیشن دیگری داشت، این واسط ها به او می گویند که می تواند برای دریافت چه اطلاعاتی درخواست دهد، چگونه درخواست خود را مطرح کند، و چگونه اطلاعات خود را دریافت کنند. در واقع API هر اپلیکیشن درخواست های مجاز را از سایر برنامه ها تحویل می گیرد، به اپلیکیشن مورد نظر می فرستد، آن گاه اطلاعات را دریافت می کند و تحویل برنامه های دیگر می دهد. +دروافع API ها در فضای وب هم برای سرویس هایی مانند گوگل مپ یا فیسبوک این امکان را فراهم می کنند تا این برنامه ها به اپلیکیشن های دیگر اجازه دهند که آن ها را اجرا کنند. برای مثال یک اپلیکیشن Yelp با استفاده از ای پی آی ها می تواند نزدیک ترین رستوران در اطراف کاربر را روی نقشه های گوگل مپ نشان دهد. یا یک اپ بازی می تواند با سرویس ابری دراپ باکس ارتباط برقرار کند تا تاریخچه ای از نتایج بازی های کاربر روی حافظه ی ابری این سرویس ذخیره شود، بدون آن که توسعه دهنده مجبور باشد یک ذخیره ساز ابری مخصوص اپلیکیشن خود طراحی کند. + +اکنون باید ببینیم که ای پی آی ها چگونه این ارتباطات را امکان پذیر می کنند. در حقیقت ای پی آی ها با استفاده از روشی محدود شده و در چارچوب قوانینی خاص با "افشای" برخی از توابع داخلی یک برنامه به محیط خارج از آن تمام این کارها را انجام می دهند. با این کار بدون آن که نیاز باشد توسعه دهنده ها تمام سورس کدهای برنامه ی خود را در اختیار دیگران قرار دهند، اپلیکیشن ها می توانند با به اشتراک گذاری بخشی از داده ها با هم ارتباط برقرار کرده و تعامل داشته باشند. + +درواقع API ها با محدود کردن دسترسی برنامه های خارجی به بخش خاصی از قابلیت های یک برنامه -که اغلب هم این سطح از دسترسی کافی است- تمام اطلاعات مورد نیاز سایر اپلیکیشن ها برای ارتباط با نرم افزار مورد نظر را فراهم می کنند. در حقیقت می توان API ها را هم چون پنجره ای به داخل یک برنامه تصور کرد. + +با توجه به تمام مثال هایی که از کاربرد API های مختلف بیان کردیم، به نظر می رسد که متوجه اهمیت آن ها در حوزه ی توسعه ی نرم افزار شده باشیم. همان طور که اعضای یک جامعه برای زندگی در کنار هم به یکدیگر نیاز دارند و باید با هم در تعامل باشند، هر چند که در بسیاری از موارد نیازی نیست یک شناخت عمیق از هم داشته باشند -مثلاً برای خرید سبزی، شما لازم نیست که در مورد زندگی خصوصی سبزی فروش محلتان اطلاعات داشته باشید، کافی است که بدانید چه کسی سبزی فروش است و مغازه ی او کجا است- این روزها اپلیکیشن های مختلف نیز به شدت نیاز به تعامل با هم دارند و برای این کار لازم است اطلاعاتی را در مورد هم داشته باشند. ای پی آی ها که تأمین کننده ی این اطلاعات هستند، علاوه بر حفظ امنیت اپلیکیشن ها، با فراهم کردن اطلاعات لازم و حذف داده های غیر ضروری، دقت و سرعت توسعه ی نرم افزارها را بالا می برند. حال باید ببینیم خصوصیات یک API خوب کدامند؟ می توان گفت که یک ای پی آی خوب، ای پی آی یی است که: + + - یادگیری آن آسان باشد؛ +- کاربرد آن حتی بدون استفاده از اسناد، باز هم آسان باشد؛ +- امکان استفاده ی نادرست از آن کم باشد؛ +- خوانایی و امکان نگهداری و پشتیبانی از کدهایی که از آن استفاده می کنند بالا باشد؛ +- برای رفع نیازهای ارتباطی نرم افزارهای دیگر با آن به اندازه ی کافی قدرتمند باشد؛ +- توسعه و گسترش آن ساده باشد؛ + +برای این که چنین خصوصیاتی را در یک ای پی آی ایجاد کنیم لازم است در زمان طراحی آن قواعدی را رعایت کنیم. از جمله این قواعد می توان به موارد زیر اشاره کرد: + +1- هر API یک وظیفه دارد و باید آن را به بهترین نحو ممکن انجام دهد. کارکرد یک API باید به گونه ای باشد که بتوان آن را به ساده ترین صورت ممکن بیان کرد. به طور مثال می گوییم وظیفه ی یک ای پی آی این است که امکان استفاده از شبکه ی اجتماعی یوتیوب را در داخل اپلیکیشن ها فراهم می کند. اگر نتوانید وظیفه ی یک API را به راحتی شرح دهید به این معنا است که مشکلی وجود دارد، و برای رفع آن می توانید طراحی ای پی آی را در قالب ماژول های کوچک تر پیاده سازی کنید، که هر کدام وظیفه ی خاصی داشته باشند. + +2- باید API تا حد ممکن کوچک باشند؛ هر چه اطلاعات کمتری افشا شود بهتر است. با این حال باید دقت داشته باشیم که ای پی آی طراحی شده حاوی تمام اطلاعات ضروری باشد. تنها به خاطر داشته باشید که همیشه امکان اضافه کردن اطلاعات وجود دارد، اما حذف اطلاعات افشا شده غیر ممکن است! + +3- این API ها نباید از پیاده سازی های مختلف تأثیر بگیرند. به عبارت دیگر، روش استفاده ی واحدی از آن API وجود داشته باشد. + +4- دسترسی ها به هر چیز را در پایین ترین سطح ممکن قرار دهید. کلاس ها و آبجکت ها را تا جای ممکن private کنید. کلاس های public نباید فیلدهای public داشته باشند (به استثنای ثابت ها). + +5- در زمان طراحی و ساخت API سعی کنید که از کاربران نهایی خود فیدبک بگیرید تا مطمئن شوید محصول نهایی شما تمام نیازهای معقول آن ها را برآورده می کند. به علاوه، باید بدانید که طراحی ای پی آی ها نیاز به یک کار تیمی دارد و به شدت پیشنهاد می شود که تمام اعضای تیم طراحی نرم افزار روی طراحی ای پی آی هم کار کنند. + +6- در طراحی API از تکرارهای بیش از حد اجتناب کنید. برای مثال اگر دو متد یک کار را انجام می دهند، نباید از هر دوی آن ها استفاده کنیم. این کار باعث سردرگمی کاربران می شود. + +7- از پروتکل امن SSL استفاده کنید. بیش تر کاربران از نقاط دسترسی غیر رمز گذاری شده برای دسترسی به اینترنت استفاده می کنند که امکان هک شدن آن ها را به راحتی فراهم می کند. + +نکته SSL مخفف واژگان Secure Sockets Layer به معنی «لایه ی سوکت های ایمن» یکی از پروتوکل های رمزنگاری استاندارد است که به منظور تأمین امنیت ارتباطات اینترنتی توسط شرکت Netscape به منظور انتقال داده‌های خصوصی از طریق اینترنت توسعه داده شد. این پروتوکل امنیت انتقال داده‌ها را در اینترنت برای مقاصدی همچون درگاه های بانک، تصدیق اطلاعات کاربری، انتقال اطلاعات هویتی و دیگر داده‌های حساس امکان پذیر می سازد. به طور خلاصه، کارکرد پروتوکل اس اس ال به این شکل است که مابین کاربر و سایت -که به طور معمول نماینده ی کاربر مرورگری است همچون فایرفاکس یا گوگل کروم و نماینده ی سایت هم وب سرور است- یک لینک رمزنگاری شده ایجاد می‌گردد. در شرایط عادی، اطلاعاتی از این دست به صورت Plain Text یا «متن ساده» مابین مرورگرها و وب سرورها رد و بدل می‌شوند که بسیار آسیب‌پذیر است اما در اس اس ال، کلیه ی داده های رمزنگاری می شوند و به طور کلی، یو آر ال هایی که نیاز به ارتباط اس اس ال دارند، به جای http، با https شروع می شوند. + +-از نوشتن مستندات غفلت نکنید. این موضوعی است که بسیاری از برنامه نویسان آن را نادیده می گیرند یا به درستی انجام نمی دهند. مستندات خود را به صورت دقیق و ساده تهیه کنید. بهترین تاکتیک برای این کار این است که فکر کنید می خواهید موضوع را برای یک کودک 10 ساله شرح دهید. از نوشتن در مورد هیچ مرحله ای اجتناب نکنید و هرگز این پیش فرض را نداشته باشید که چون موضوعی برای شما بدیهی است دیگران هم باید آن را بدانند. مستندسازی مناسب به ویژه در شرایطی که فرآیندها پیچیده اند کمک بزرگی به کاربران خواهد کرد. + +-واقع گرا باشید. به هر حال با وجود رعایت تمامی قواعد و مشورت اعضای تیم با یکدیگر باز هم امکان اشتباه و نادیده گرفتن یک سری مسائل وجود دارد. اما آن چه باید بدانید این است که در نهایت شما نمی توانید رضایت همه ی افراد را به دست آورید. + +در انتها باید این نکته را به شما یادآوری کنیم که هر چند API ها ابزارهایی سودمند در دست برنامه نویسان هستند اما استفاده از آن ها با چالش هایی همراه است. باید بدانید که اگر یک API امروز در دسترس کاربران قرار دارد دلیلی ندارد که این دسترسی برای همیشه وجود داشته باشد. برای مثال چند سال پیش شرکت توئیتر دسترسی کاربران را به ای پی آی های خود محدود کرد. + +علاوه بر این، کمپانی هایی که API های خود را در دسترس کاربران قرار می دهند ممکن است بعد از مدتی به ارائه ی خدمات خود پایان دهند. در این صورت اگر اپلیکیشن شما وابسته به API های این شرکت ها باشند با مشکل مواجه خواهند شد. برای مثال فرض کنید شرکت گوگل تصمیم بگیرد ارائه ی خدمات سرویس گوگل مپ را متوقف کند، در این صورت کار اپلیکیشن Yelp نیز متوقف خواهد شد. به هر حال با وجود تمام چالش هایی از این دست، توسعه دهندگان علاقه ی زیادی به استفاده از API ها دارند و هر روز شاهد گسترش ای پی آی های مختلف هستیم. diff --git a/fa/thing_19/README.md b/fa/thing_19/README.md new file mode 100644 index 00000000..917baafb --- /dev/null +++ b/fa/thing_19/README.md @@ -0,0 +1,32 @@ +# از ابتدای کار توسعهٔ اپلیکیشن خود روی فرآیند نصب و دیپلوی آن به طور پیوسته کار کنید + +استقرار نرم افزار یا Software Deployment فرآیند آماده سازی یک برنامه برای نصب و پیکربندی آن روی سیستم های مشتریان است. یک اپلیکیشن جدید ممکن است روی سیستم شما که توسعه دهنده ی آن هستید به خوبی کار کند، اما این به معنای آن نیست که واقعا برای کار روی سایر سیستم ها آماده شده باشد. بسیاری از قابلیت ها وجود دارند که ممکن است شما اصلاً به آن ها احتیاج پیدا نکرده باید، با این حال سایر کاربران به آن ها نیاز دارند و شما مسئول ایجاد این قابلیت ها در نرم افزار خود هستید تا به نیاز مشتریانتان به خوبی پاسخ دهید. وجود این قابلیت ها از این نظر مهم است که نرم افزار شما را اصطلاحاً کاربر پسندتر می کند و به شما کمک خواهد کرد تا از سرقت نرم افزار خود جلوگیری کنید. در این آموزش به معرفی گام های فرآیند استقرار نرم افزار و برخی الزامات آن می پردازیم. + +گفتیم فرآیند استقرار نرم افزار به تمام اقدامات لازمی اطلاق می شود که با انجام آن ها، کاربران می توانند به راحتی از یک نرم افزار استفاده کنند. از آن جا که هر سیستم نرم افزاری قابلیت های منحصر به فرد خود را دارا است، نمی توان در مورد پروسه ی دقیق هر فعالیت چیزی گفت. از این رو می توانیم دیپلویمنت نرم افزار را یک فرآیند کلی در نظر بگیریم که باید بر اساس خصوصیات و الزامات خاص هر سیستمی شخصی سازی شود. با این وجود می توانیم به طور خلاصه توضیحاتی کلی در مورد برخی از اقدامات این فرآیند به شرح زیر داشته باشیم: + +توزیع یا Release:این فعالیت در حقیقت واسطی بین فرآیند توسعه و فرآیند دیپلویمنت نرم افزار است که شامل تمام عملیات مورد نیاز برای آماده سازی یک نرم افزار به منظور یکپارچه سازی و انتقال آن به سیستم کاربران می شود. بنابراین توزیع یک سیستم نرم افزاری باید تمام منابع لازم را به همراه داشته باشد تا نرم افزار به درستی روی سیستم کاربران اجرا شود. به طور کلی توزیع یک نرم افزار شامل پکیجی از اجزای مورد نیاز برای راه اندازی سیستم، توضیحات راهنما در مورد نحوه ی نصب سیستم، و اطلاعاتی در مورد خصوصیات، موارد استفاده و جامعه ی هدف سیستم نرم افزاری است. + + نصب یا Installation: این مرحله اولین اقدام برای دیپلویمنت نرم افزار روی سیستم مشتریان است. معمولاً این مرحله پیچیده ترین مرحله ی دیپلویمنت نرم افزار است، چرا که برای این کار باید تمام منابع مورد نیاز برای استفاده از سیستم به طور مناسب گردآوری شوند. + +فعال سازی یا Activation : این فعالیت مربوط به راه اندازی اجزایی از سیستم می شود که برای اجرای نرم افزار مستقر شده ابتدا باید آن ها اجرا شوند. معمولاً فعال سازی با استفاده از پنجره های راهنما و آیکون ها و دکمه های گرافیکی طراحی شده صورت می گیرد. باید دقت داشته باشیم که در مرحله ی فعال سازی ممکن است نیاز به فعال بودن یک سری نرم افزارهای دیگر داشته باشیم. برای مثال اگر در این مرحله یک فایل فشرده ی زیپ داشته باشیم، برای باز کردن آن نیاز به یک نرم افزار نصب شده ی دیگر روی سیستم خواهیم داشت که فایل های زیپ را بخواند. + +غیر فعال سازی یا De-Activation :اقدامی درست بر خلاف فعالیت قبلی که اجرای تمام اجزای نرم افزار را متوقف می کند. این عملیات معمولاً قبل از فعالیت های دیگر فرآیند دیپلویمنت مانند به روز رسانی سیستم اتفاق می افتد. + +به روز رسانی یا Update: این فعالیت در حقیقت حالت خاصی از نصب نرم افزار است که معمولاً پیچیدگی کم تری نسبت به عملیات نصب دارد، چرا که نرم افزار قبلاً یک بار روی سیستم نصب شده است. + +پاک کردن نرم افزار نصب شده یا De-Installation: زمانی پیش می آید که یک کاربر دیگر نیازی به یک نرم افزار ندارد و می خواهد آن را از سیستم خود پاک کند. در این شرایط باید تمام اجزای نصب شده به درستی غیر فعال شده، سپس از روی سیستم پاک شوند. در این مورد باید دقت لازم صورت بگیرد که آسیبی به سایر منابع و فایل های مشترک وارد نشود. + +منسوخ شدن یا Obsolescence: در نهایت یک نرم افزار پس از مدتی منسوخ می شود و سازندگانش دیگر از آن پشتیبانی نخواهند کرد. دقیقاً مانند زمانی که نسخه ی نصب شده را غیر فعال می شود، باید مراقب باشیم که مشکلی برای سایر اجزای سیستم به وجود نیاید. یکی از الزامات این کار این است که به کاربران زمان منسوخ شدن نرم افزار از پیش اطلاع داده شده باشد. + +به منظور استقرار یک اپلیکیشن در محیط سیستم مشتریان، مراحل بالا باید به طور دقیق طراحی و آزمایش شوند. از آن جا که تمام این اقدامات پس از توسعه ی یک نرم افزار روی سیستم کاربران صورت می گیرد، معمولاً طراحی و اشکال زدایی آن ها تا مراحل پایانی توسعه نرم افزار به تعویق می افتد. مسئولیت کدنویسی بخش مربوط به نصب نرم افزار در آخرین مرحله به یک مهندس توزیع محول می شود که به واسطه ی پیچیدگی های مربوط به آن، کار خود را با نارضایتی پیش می برد. نتیجه ی این کار این است که تیم نرم افزاری هیچ تجربه ای در مورد فرآیند دیپلویمنت نرم افزار یا محیط واقعی که نرم افزار در آن استقرار می یابد پیدا نمی کند، تا زمانی که بسیار دیر می شود و عملاً نمی توان تغییری را در سیستم اِعمال کرد یا نتیجه ی اِعمال تغییرات بسیار سنگین می شود. + +از آن جا که فرآیند نصب و دیپلویمنت اولین چیزی است که مشتری با آن رو به رو می شود، هر اندازه این فرآیند ساده تر باشد، کاربر نهایی راحت تر و با خطای کم تر می تواند نرم افزار شما را روی سیستم خود به کار گیرد، در نتیجه به نرم افزار اعتماد پیدا می کند و راحت تر برای پذیرش آن قانع می شود. + +زمانی که پروژه ی نرم افزاری خود را با کار روی عملیات نصب آغاز می کنید، فرصت بیش تری برای کار روی این فرآیند دارید، در نتیجه شانس این را دارید که هم زمان با توسعه ی نرم افزار بتوانید بخشی از کدهای برنامه را به منظور تسهیل فرآیند نصب تغییر دهید. اجرا و تست فرآیند نصب در یک محیط تمیز به صورت دوره ای خیال شما را از این بابت راحت خواهد کرد که فرآیند طراحی شده به قابلیت های منحصر به سیستم شما که روی آن نرم افزار را توسعه می دهید وابستگی ندارد، و روی هر سیستمی قابل راه اندازی و اجرا است. + +به تأخیر انداختن طراحی و تست اقدامات فرآیند دیپلویمنت نرم افزار به این معنا است که در مراحل پایانی با پیچیدگی های بیش تری رو به رو خواهید بود. به این دلیل که مجموعه ای از کدهای نرم افزار عملاً قابل تغییر نیستند، یا این که گاهی کدنویسی برنامه با فرضیاتی در مورد سیستم صورت گرفته است که منحصر به سیستم خاص شما است و برای کار روی سایر سیستم ها نیازمند تغییر است. + +اگرچه فکر کردن در مورد فرآیند دیپلویمنت نرم افزار و کار روی آن در همان آغاز پروژه توجیه اقتصادی ندارد و ارجحیت با این است که توسعه دهنده بتواند اپلیکیشنی را طراحی و توسعه دهد که در محیط توسعه، روی سیستم خودش به درستی اجرا شود؛ با این حال نکته ی اساسی در این است که شما نهایتاً زمانی می توانید از پروژه ی خود سود اقتصادی ببرید که بتوانید نسخه ی قابل نصب و اجرا را در اختیار مشتریان قرار دهید و آن ها بتوانند از نرم افزار کدنویسی شده به درستی روی سیستم خود استفاده کنند، در غیر این صورت هیچ کس برای اپلیکیشنی که کدهای آن تنها در یک IDE اجرا می شوند پولی پرداخت نخواهد کرد. + +به عنوان نکته ی پایانی باید به این مورد اشاره داشته باشیم که فرآیند نصب و دیپلویمنت نرم افزار نقش مهمی در میزان بهره وری مشتریان و تیم خدمات تخصصی شما دارد، بنابراین به همان نسبت که برای تست و دیباگ کردن سورس کد نرم افزار خود وقت صرف می کنید، روی آزمایش، ارزیابی، و اشکال زدایی فرآیند نصب و دیپلویمنت نرم افزار نیز زمان بگذارید. + diff --git a/fa/thing_20/README.md b/fa/thing_20/README.md new file mode 100644 index 00000000..478ee176 --- /dev/null +++ b/fa/thing_20/README.md @@ -0,0 +1,12 @@ +# مدیریت اکسپشن ها + +یک Exception (اکسپشن یا استثناء) مشکلی است که در زمان اجرای برنامه رخ می دهد. زمانی که یک اکسپشن اتفاق می افتد جریان عادی برنامه مختل می شود و برنامه یا اپلیکیشن به طور غیر عادی پایان می یابد. + +برای جلوگیری از چنین پایان ناخواسته ای باید اکسپشن ها مدیریت یا هَندل شوند و عملیات لازم برای رفع مشکل انجام شود. از این رو در زمان رخ دادن یک اکسپشن آبجکتی تحت عنوان Exception Object ایجاد می شود که حاوی اطلاعاتی در مورد نوع و زمان ایجاد خطا در برنامه یا اپلیکیشن است، سپس این آبجکت در اختیار سیستم قرار می گیرد. از این مرحله به بعد، سیستم سعی می کند تا راهی برای رفع خطا پیدا کند. اگر سیستم قطعه کدی پیدا کند که بتواند خطای ایجاد شده را رفع کند، استفاده ی مجدد از سیستم امکان پذیر خواهد بود. پس لازم است در بخش هایی از برنامه که احتمال بروز اکسپشن وجود دارد از قبل آینده نگری شود و برای مدیریت اکسپشن ها برنامه ریزی و کدنویسی شود. رخ دادن یک اکسپشن می تواند دلایل زیادی داشته باشد که برخی از مهم ترین آن ها عبارتند از: +- کاربر داده ی نامعتبری وارد کرده است. +- برنامه برای اجرا نیاز به فایلی دارد که نمی تواند آن را پیدا کند و محتوای آن را بخواند. +- ارتباط با شبکه قطع می شود و یا حافظه ی دستگاه از دسترس خارج می شود. + +برخی از این سناریوها به دلیل خطای کاربر، برخی بواسطه ی خطای برنامه نویس و دسته ای دیگر به خاطر نبود ریسورس کافی یا بهتر بگوییم «منابع فیزیکی» اتفاق می افتند. با این حال تمام این اکسپشن ها در دسته ی "خطاهای فنی" قرار می گیرند. در کنار این خطاها گروهی دیگری از اکسپشن ها وجود دارند که به واسطه ی برآورده نشدن Business Logic اتفاق می افتند. برای مثال فرض کنیم اپلیکیشنی طراحی شده است که به کاربران امکان خرید آنلاین می دهد. حال یکی از کاربران این اپلیکیشن بخواهد خریدی انجام دهد، اما اعتبار پولی کافی در حساب خود نداشته باشد. در این صورت یک شرایط استثناء اتفاق می افتد که مربوط به جنبه های فنی برنامه نمی شود، بلکه «منطق تجاری» برنامه این اجازه را به کاربر نمی دهد که با اعتبار ناکافی تراکنش خود را انجام دهد. + +نکته ای که باید در مورد اکسپشن ها رعایت شود این است که می بایست بین انواع فنی و عملی اکسپشن ها تمایز قائل شویم. با این کار، امکان این را خواهیم داشت که از مکانیزم های عمومی مدیریت اکسپشن ها در زبان های برنامه نویسی مختلف استفاده کرده و حتی برای مدیریت اکسپشن ها از برخی فریم ورک های نرم افزاری استفاده کنیم، اما در مورد اکسپشن های عملی باید کاربر حتما از شرایط استثنایی رخ داده شده آگاه شود و آماده ی مدیریت آن باشد، که در این موارد بهتر است یک اکسپشن جداگانه یا سلسله مراتب استثناء متمایز برای مدیریت اکسپشن ها در نظر گرفته شود تا کاربر بتواند بر اساس شرایط خود، آن ها را مدیریت کند. diff --git a/fa/thing_21/README.md b/fa/thing_21/README.md new file mode 100644 index 00000000..0e6e41ce --- /dev/null +++ b/fa/thing_21/README.md @@ -0,0 +1,22 @@ +# تمرین آگاهانه، لازمهٔ حرفه‌ای شدن است! + +فرض کنید شما در یک کلاس برنامه نویسی شرکت کرده اید، یا یک دوره ی برنامه نویسی را گذرانده اید. مطمئناً در این دوره ها با مفاهیم زیادی مثل استفاده از شرط ها و حلقه ها، اصول شیء گرایی، مدیریت اکسپشن ها و بسیاری موارد پایه ای دیگر آشنا شده اید. به علاوه در هر کدام از این دوره ها با جزئیات عملی زیادی مثل این که در زبان پایتون برای بلوک بندی قطعه کدها به جای کروشه از تورفتگی استفاده می کنیم، یا این که زبان جاوا نسبت به حالت حروف حساس است آشنا شده اید. + +با وجود آشنایی با تمام این مفاهیم و جزئیات عملی ممکن است شما باز هم نتوانید یک اپلیکیشن خوب توسعه دهید. دلیل این موضوع این است که دانش مفاهیم نظری پایه ی کار برای شروع برنامه نویسی است، با این حال تنها تمرین کردن و تمرین کردن و تمرین کردن در کدنویسی و کسب مهارت است که از شما یک برنامه نویس حرفه ای می سازد. + +هیچ جایگزینی برای تمرین وجود ندارد. شما نمی توانید به خودتان بگویید که خب من یک منبع خوب برای یادگیری برنامه نویسی پیدا کردم و با مطالعه ی آن تا دو هفته ی دیگر تبدیل به یکی از خبرگان برنامه نویسی می شوم. بدون تمرین مفاهیم نظری هم به سرعت فراموش خواهند شد. با این حال همان طور که اگر برای یادگیری مفاهیم نظری استاد خوب و منابع درسی کاملی در دست داشته باشید می توانید با سرعت بیش تری مطالب را بفهمید و یاد بگیرید، در مورد یادگیری مهارت های عملی نیز راه هایی وجود دارد که می توانید با استفاده از آن ها سرعت خود را بیش تر کنید، یا اگر بخواهیم به طور دقیق تر صحبت کنیم با استفاده از این روش ها شما وقت خود را برای تمرین های بیهوده که تأثیری در مهارت آموزی شما نخواهند داشت تلف نخواهید کرد. + +Deliberate Practice یا «تمرین آگاهانه» تکنیک قدرتمندی است که به شما این اطمینان را می دهد که از زمانی که برای تمرین کردن اختصاص داده اید، بیش ترین استفاده را کرده اید. تکنیک تمرین آگاهانه بر اساس تحقیقات کی. آندرس اریکسون طراحی شده است. این تکنیک چندین اصل پایه ای برای تمرین آگاهانه دارد، اما در این جا ما روی دو مورد از آن ها تمرکز می کنیم: + +1- تمرین بر لبه ی توانایی ها و دانش کنونی: +تمرین بسیار ساده چیز تازه ای به شما یاد نمی دهد و تمرین بسیار سخت مانع پیشرفت شما خواهد شد. اولین نکته بسیار آشکار است. اگر سطح دشواری تمرین های شما بسیار پایین باشد، پیشرفت چندانی نخواهید داشت. اگر شما مدتی است که یادگیری برنامه نویسی را شروع کرده اید، نوشتن یک برنامه ی ساده ی HelloWorld هیچ کمکی به شما نخواهد کرد و چیز تازه ای به شما یاد نخواهد داد. + +بنابراین حتی در پیاده سازی برنامه های ساده نیز خلاقیت به خرج دهید. اگر روی مثال های آموزشی خود کار می کنید، سعی کنید آن ها را به نحوی تغییر دهید و با دانش قبلی خود ترکیب کنید. مثلاً اگر یاد می گیرید که فانکشنی بنویسید که یک آرگومان استرینگ می گیرد، سعی کنید خودتان فانکشن های جدیدی بنویسید که تعداد آرگومان های بیش تر، با انواع متنوع تری داشته باشد. با این حال اگر سطح دشواری تمرین های شما بیش از حد بالا باشد، شانس زیادی برای موفقیت نخواهید داشت. اگر شما روی یک برنامه ی بسیار پیشرفته کار کنید که نتوانید بفهمید هر بخش آن چطور کار می کند، در این صورت تمرین کردن بی معنی خواهد بود. اگر شما همین دیروز شروع به یادگیری برنامه نویسی کرده اید، و امروز بخواهید روی کدنویسی یک پروژه ی بزرگ کار کنید قطعاً راه به جایی نخواهید برد. + +2- بازخورد گرفتن: +کارهای خود را به دیگران ارائه کنید و از آن ها بخواهید نظر خود را در مورد نقاط ضعف و قوت برنامه هایتان اعلام کنند. +اصل دوم نیز بسیار مشهود است، با این حال بسیاری از افراد در زمان تمرین یک مهارت جدید آن را فراموش می کنند. بازخورد گرفتن به طور غیر قابل باوری اهمیت دارد، زیرا به شما این امکان را می دهد تا کار خود را تصحیح و تعدیل کنید. اگر هیچ کس به شما نگوید که چه اشتباهی کرده اید، چطور پی به خطای خود می برید و آن را اصلاح می کنید؟ + +مثلاً فرض کنید شما کدهای برنامه ی خود را روی یک برگه کاغذ بنویسید؛ این کار برای شما راحت تر خواهد بود، اما تا زمانی که آن ها را در محیط کامپیوتری کامپایل و اجرا نکرده باشید چطور مطمئن خواهید بود که برنامه ی درست و بدون باگی نوشته اید. به علاوه تمام تکنیک های کدنویسی را نمی توان تنها با اجرای کامپیوتری برنامه ها یاد گرفت. لازم است گاهی دیگران نگاهی به کار شما بیاندازند و نظر خود را در مورد آن بگویند. + +تمرین کردن کدنویسی بدون آن که کار خود را به دیگران ارائه کنید و از آن ها بازخورد بگیرید، مثل این است که در تاریکی قدم برمی دارید. ممکن است به جلو پیش روید، ممکن است تنها دور خود بچرخید، اما نمی توانید تفاوت این دو را بفهمید. diff --git a/fa/thing_22/README.md b/fa/thing_22/README.md new file mode 100644 index 00000000..df9b2a37 --- /dev/null +++ b/fa/thing_22/README.md @@ -0,0 +1,27 @@ +# پشت هر خط از کد شما می‌بایست یک منطق وجود داشته باشد! +یکسری ابزارها در اختیار برنامه نویسان هستند که این امکان را به ایشان می‌دهند تا کدهایشان را به منظور عدم وجود هرگونه باگی چک کنند اما واقعیت امر آن است که این دست ابزارها همیشه کارآمد نیستند و نتیجه ی دلخواه را بوجود نمی آورند. در همین راستا، برنامه نویسان نیاز به رویکردی دارند تا از آن طریق بتوانند از درستی کدهای خود اطمینان حاصل کنند و این همان چیزی است که در این آموزش قصد داریم مورد بررسی قرار دهیم. + +یک برنامه نویس حرفه‌ای کسی است که سورس کد پروژه ی خود را به بخش‌های کوچک تقسیم‌بندی کرده -خواه بخش‌های یک خطی مثل فراخوانی یک فانکشن، خواه بخش‌های مثلاً ده خطی- و از صحت کارکرد این بخش‌های سورس کد اطمینان حاصل کند. اگر شما بتوانید به اندازه‌ای از کارکرد سورس کد پروژه ی خود اطمینان داشته باشید که یکی از دوستان برنامه نویس شما -که نقش Devil`s Advocate را بازی می کند- نتواند به آن گیر دهد، کفایت می‌کند و شما به هدف خود دست یافته اید. + +به خاطر داشته باشید به طور کلی منظور از Devil`s Advocate یا «وکیل مدافع شیطان» کسی است که مهارت خاصی در ایراد بنی اسرائیلی گرفتن دارد و همواره نیمه ی خالی لیوان را نگاه می کند. ممکن است این تصور برای شما پیش بیاد که در شرکت های حرفه‌ای چنین افرادی اصلاً جایگاه خوبی ندارند اما این باور کاملاً اشتباه است. شرکت های تراز اول برای وکلای مدافع شیطان سر و دست می شکنند چرا که این افراد می‌توانند متضمن موفقیت یک محصول شوند. +در بررسی تک تک خطوط سورس کد، می بایست همواره این نکته را مد نظر قرار دهیم که تا حد ممکن بلوک های کد مستقل از یکدیگر باشند و اصطلاحاً Dependency (دیپندنسی یا وابستگی) کمی مابین بخش‌های مختلف کد وجود داشته باشد چرا که در این صورت، بررسی سورس کد به مراتب راحت‌تر خواهد بود. به طور کلی، یکسری نکات هستند که اگر بتوانیم از آن‌ها در کدنویسی پیروی کنیم، تا حد قابل توجهی می‌توانند متضمن یک محصول نهایت بهینه گردند که عبارتند از: + +- تا حد ممکن از فانکشن هایی که ماهیت GoTo دارند اجتناب کنید. در اینجا منظور از GoTo، فانکشن هایی است که برای انجام کاری خاص نیاز به سایر فانکشن ها دارند و همین مسأله منجر ارتباط بین فانکشنی و در نهایت پیچیدگی بیشتر سورس کد می شود. + +- تا حد ممکن از متغیرهای گلوبال که امکان تغییر مقادیر آن‌ها وجود دارد استفاده نکنید چرا که این دست متغیرها منجر به ایجاد وابستگی مابین بخش‌های مختلف کد می‌شوند (منظور از متغیرهای گلوبال، متغیرهایی است که در بدنه ی کلاس‌ها تعریف شده و به نوعی public هستند؛ یعنی از هر کجای برنامه می‌توان به آن‌ها دسترسی داشت.) + +- هر متغیر می بایست تا حد ممکن از Scope یا «حوزه ی» کوچکی برخوردار باشد. به عبارت دیگر، مثلاً به جای تعریف کردن متغیری تحت عنوان userAccountNumber که گلوبال است، بهتر است که این متغیر را داخل یک فانکشن تعریف کنیم و صرفاً داخل همان فانکشن به آن دسترسی داشته باشیم. + +- از فضاهای خالی به منظور خوانایی بیشتر کد استفاده کنید. به عبارت دیگر، بخش‌های مختلف سورس کد را با زدن اینتر مجزا کنید و در عین حال هم از Indentation های درست استفاده کنید (منظور از Indentation، اسپیس هایی است که از سمت چپ ویرایشگر کد تا ابتدای دستورات وجود دارند.) امروزه اکثر IDE ها دارای این قابلیت هستند تا به صورت خودکار، فواصل سورس کد را منظم کنند. + +- کد خود را گویا کنید. به عبارت دیگر، نام هایی برای کلاس ها، فانکشن ها، متغیرها و … استفاده کنید که نیازی به کامنت گذاری نداشته و مثلاً نام یک فانکشن به خوبی نمایانگر ماهیت و کاری که آن فانکشن انجام می‌دهد باشد. به طور مثال، اگر فانکشی قرار است اطلاعات کاربر را از دیتابیس گرفته و در اختیار ما قرار دهد، نامی همچون fetchUserInfo مناسب است چرا که هم کوتاه است اما در عین حال گویای ماهیت این فانکشن نیز هست. + +- اگر منطق برنامه ی شما به گونه‌ای است که نیازمند بخش‌های تو در تو است، بهتر آن است که هر بخش را در قالب یک فانکشن کدنویسی کنید. + +- هر فانکشن می بایست فقط و فقط یک کار را انجام دهد و از نوشتن فانکشن های «همه کاره» شدیدا خودداری کنید. گفته می‌شود که یک فانکشن خوب، فانکشنی است که در صفحه ی مانیتور، بدون نیاز به اسکرول کردن، ابتدا و انتهای آن معلوم باشد. یعنی چیزی در حدود 24 خط کد! (البته بسته به رزولوشن و اندازه ی مانتیور، این قانون برای برنامه نویسان مختلف نتایج کاملا متفاوتی دارد.) + +- تعداد پارامترهای ورودی فانکشن ها می بایست محدود باشد (مثلاً 4 پارامتر ورودی به نظر محدودیت خوبی به نظر می آید) و در صورتی هم که تعداد پارامترهای ورودی مد نظر شما زیاد است -مثلا 12 پارامتر ورودی- می‌توانید پارامترهای مرتبط با یکدیگر را در قالب یک آبجکت تعریف کرده و از آن آبجکت به عنوان یکی از پارامترها استفاده نمایید. + +علاوه بر موارد فوق الذکر، راه کارهای دیگر نیز هستند که با اعمال آن‌ها می‌توان درک بهتری از سورس کد پیدا کرد اما موارد مطروحه جزو مهم‌ترین چیزهایی هستند که به شما کمک خواهند کرد تا کدی تمیز، بدون باگ، بدون وابستگی، گویا و بهینه داشته باشید.. + + diff --git a/fa/thing_23/README.md b/fa/thing_23/README.md new file mode 100644 index 00000000..a0e0664f --- /dev/null +++ b/fa/thing_23/README.md @@ -0,0 +1,37 @@ +# مفهوم DSL چیست و چرا آشنایی با آن در حوزهٔ برنامه‌نویسی اهمیت دارد؟ + +منظور ازDSL که مخفف واژگان Domain-Specific Language به معنی «زبان اختصاصی هر حوزه ی کاری» می باشد، یکسری زبان‌های برنامه نویسی است که به صورت تخصصی برای یکسری کارهای خاص در یکسری حوزه های خاص مورد استفاده قرار می‌گیرند. برای درک بهتر دی اس ال ها، می‌توان آن‌ها را همچون زبان‌های برنامه نویسی کوچکی تلقی کرد که برای انجام یکسری کارهای خاص در یک سیستم مورد استفاده قرار می‌گیرند و از جمله حوزه های خاصی که از دی اس ال ها در آن‌ها استفاده می شود، می‌توان به صنعت بیمه، صنعت هواپیمایی، پتروشیمی و … اشاره کرد. + +یکی از دلایلی که دی اس ال ها بوجود آمدند این بود که زبان‌های رایج و همه منظوره برای یکسری ابزارها، سیستم ها، پلتفرم ها و حتی صنایع آن طور که باید و شاید اثربخش نبودند و همین شد که این گروه از زبان‌های برنامه نویسی کوچک اما در عین حال کاربری ابداع شدند. + +بر خلاف زبان‌های برنامه نویسی همه منظوره ای همچون جاوا، پایتون، پرل و غیره، حوزه ای که از دی اس ال ها می‌توان در آن استفاده کرد محدود است اما این در حالی است که در آن حوزه ی خاص، دی اس ال ها با سرعت بیشتر و عملکرد به مراتب بهتری نسبت به زبان‌های همه منظور عمل خواهند کرد. + +در ضمن، به نوعی می‌توان گفت که دی اس ال ها برای حوزه ی خاصی که طراحی می‌شوند فوق‌العاده خوب هستند اما برای حوزه هایی که خارج از ساختار از پیش تعریف شده ی دی اس ال باشند فوق‌العاده بد هستند. + +نکته توجه داشته باشیم که ما با استفاده از دی اس ال ها نخواهیم توانست یک برنامه ی کامل و جامع بنویسیم بلکه صرفاً به منظور انجام کارهای کوچکی که به سرعت می بایست انجام شوند می‌توان از این زبان‌های برنامه نویسی کوچک استفاده کرد. +از جمله دی اس ال های رایج می‌توان به CSS, Ant و SQL اشاره کرد. به یاد داشته باشید که از برخی زبان‌های General Purpose یا «چند منظوره» همچون سی شارپ، اسکالا، روبی و … می‌توان به منظور ساخت یک DSL استفاده کرد. مثلاً از زبان اسکالا -که خود این زبان برگرفته از زبان برنامه نویسی جاوا است- می‌توان برای ساخت DSL هایی برای صنایع بسیار حساس همچون صنعت نفت استفاده کرد. + +انواع DSL ها +به طور کلی، زبان‌های دی اس ال را می‌توان به دو دسته ی Internal (اینترنال یا داخلی) و External (اکسترنال یا خارجی) تقسیم‌بندی کرد. + +دی اس ال های اینترنال به گروهی از زبان‌های برنامه نویسی گفته می‌شود که بر پایه زبان‌های برنامه نویسی همه منظوره ای همچون سی شارپ، جاوا، اسکالا، روبی و … بوده و این در حالی است که بسیاری از قابلیت‌های این زبان‌های مادر در DSL هایی که بر پایه ی آن‌ها نوشته شده‌اند مشهود است که به عنوان مثال می‌توان به سینتکس -نحوه ی نوشتار- این زبان‌ها اشاره کرد. از زبان‌های دی اس ال اینترنال در جامعه ی توسعه دهندگان زبان برنامه نویسی Lisp به کرات استفاده می شود. + +در مقابل، دی اس ال های اکسترنال قرار دارند که خود توسعه‌دهنده می‌تواند تصمیم بگیرد که از چه نشانه ها، سینتکس و ساختاری برای زبان مد نظرش استفاده کند. دی اس ال های اکسترنال تا حد بسیار زیادی دست شما را باز می‌گذارند اما این در حالی است که طراحی این دست زبان‌ها به مراتب دشوارتر بوده و مستلزم صرف زمان نسبتاً زیادی برای توسعه ی آن‌ها است چرا که شما می بایست کامپایلر اختصاصی دی اس ال را به منظور اجرای سینتکسی که مد نظر شماست را نیز طراحی کنید. در توسعه ی سیستم عامل های مبتنی بر Unix از زبان‌های دی اس ال اسکترنال به کرات استفاده می شود. + +در زمان طراحی DSL ها، همواره می بایست مخاطب را مد نظر قرار داد و دید که مخاطبین این زبان برنامه نویسی جدید چه گروهی از کاربران هستند؛ آیا توسعه‌دهنده اند یا جزو مدیران و تیم اجرایی یک شرکت محسوب می شوند. پس از آن که مخاطبین زبان مشخص شدند، می بایست بر اساس نیاز و تخصص ایشان اقدام به طراحی سینتکس، سطح فنی مورد نیاز زبان، ابزارهای مورد نیاز و نحوه ی به کارگیری زبان کرد. با پنهان سازی جزئیات فنی در زبان‌های دی اس ال، می‌توان کاربران هدف را به ابزاری تجهیز کرد که بدون نیاز به کمک توسعه دهندگان، بتوانند نیازهای خود را مرتفع سازند. + +مزایای DSL ها +به طور کلی، مزایای طراحی زبان های دی اس ال را می توان به صورت زیر خلاصه کرد: +- برخلاف زبان های همه منظوره، دی اس ال ها بهترین گزینه برای نیازهای خاص هستند. +- کسانی که با برنامه نویسی هم آشنایی نداشته باشند به سادگی قادر خواهند بود تا یک دید کلی نسبت به آن ها پیدا کنند. +- این امکان وجود خواهد داشت تا با طراحی یک GUI یا «رابط گرافیکی کاربری» فرایند استفاده از دی اس ال را ساده تر نمود. +- امکان ساخت Prototype (پروتوتایپ یا نمونه ی اولیه) یک نرم افزار یا اپلیکیشن با استفاده از دی اس ال ها به مراتب راحت تر صورت می گیرد. + +یکی از بهترین نمونه های دی اس ال، CSS است که مخفف واژگان Cascading Style Sheets به معنی «الگوی های آبشاری» می باشد. به طور کلی، کدهای سی اس اس به طراحان سایت اجازه می دهند تا به عناصر تشکیل دهنده ی یک صفحه ی وب شکل و ساختار دهند. برای مثال، کدهای سی اس اس زیر رنگ بنده ی یک صفحه ی سایت را قرمز کرده، اندازه ی فونت را 16 پیکسل کرده و رنگ فونت را هم سفید می کنند: +```Css +body { + background: #F00 + font-size: 16px; + color: #FFF +} +``` diff --git a/fa/thing_24/README.md b/fa/thing_24/README.md new file mode 100644 index 00000000..386591cc --- /dev/null +++ b/fa/thing_24/README.md @@ -0,0 +1,14 @@ +# از ساختارشکنی نترسید! + +کمتر کسی را می‌توان یافت که در حوزه ی برنامه نویسی کار کرده باشد و با پروژه یی مواجه نشده باشد که ساختار کدنویسی آن مشکل داشته باشد. در چنین پروژه هایی، رفع یک باگ منجر به ایجاد ده‌ها باگ دیگر خواهد شد! در چنین شرایطی، برنامه نویس کاملاً دست به عصا کدنویسی کرده و همیشه این نگرانی را دارد که پروژه از هم بپاشد. + +دلیل مواجهه با چنین مشکلی کاملاً واضح است و این دلیل چیزی نیست جز «بیمار» بودن سیستم و این بیمار نیاز به یک پزشک دارد و در غیر این صورت، اوضاع از این هم وخیم تر خواهد شد. در‌ واقع، همان‌طور که یک عمل جراحی در ابتدا با درد همراه است و شرایط اصلاً خوشایندی را برای بیمار فراهم نمی کند اما در نهایت منجر به سلامت بیمار می شود، در این گونه پروژه ها نیز می بایست متحمل چنین دردی شویم! + +خود شما –به عنوان برنامه نویس یا یکی از برنامه نویسان چنین پروژه یی- دقیقاً می‌دانید که مشکل از کجا است و چه بخش‌هایی نیاز به ریفکتور شدن دارند اما از دست به عمل شدن هراس دارید. + +به خاطر داشته باشید به طور خلاصه، منظور از Code Refactoring (کد ریفکتورینگ) این است که ساختار فعلی سورس کد یک پروژه را تغییر دهیم -یا بهتر بگوییم بهبود بخشیم- بدون آن که تاثیری در نوع ماهیت پروژه ایجاد گردد. فرض کنیم چند سال پیش کدی را نوشته ایم، حال که چیزهای جدید فرا گرفته ایم و به کد نگاه می کنیم، می بینیم کدی که مثلا در 40 خط نوشته ایم را می توان خیلی بهینه تر کرده و به 10 خط کاهش داده و در عین حال اثربخشی آن را نیز بیشتر کرد. به چنین کاری Refactoring گفته می شود. +مادامی که شما به صورت لوکال اقدام به تغییر و تحول سورس کد خود می کنید، هرگز از دست کاری کد خود نترسید چرا که در نهایت منجر به بهبود وضعیت پروژه خواهد شد. خیلی از اوقات ما -به عنوان برنامه نویس- می‌دانیم که مشکل از کجا است اما یا حوصله ی رفع کردن آن را نداریم یا به دلیل طولانی شدن زمان کار کردن روی پروژه، ترجیح می‌دهیم مشکلات را به حال خود رها کرده و روی پروژه ی دیگری کار کنیم و یا این که از رو به رو شدن با مشکلات پروژه هراس داریم. + +متأسفانه خبر بد این که این شتری است که درب خانه ی هر برنامه نویسی می خوابد! شما چاره یی جز این ندارید که سورس کد خود را ریفکتور کنید، باگ ها را رفع کنید و وابستگی‌ها را به حداقل برسانید. اگر هم روی پروژه یی کار می‌کنید که شما مسئول مستقیم آن نیستید، سعی کنید مدیر خود را مجاب کنید که اگرچه این اصلاحات نتایج ملموس و قابل مشاهده یی ایجاد نمی کنند، اما در نهایت منجر به کاهش هزینه‌ها در دراز مدت و تجربه ی کاربری بهتری می شوند. + +به خاطر داشته باشید Dependency (دیپندنسی یا وابستگی) در توسعه ی نرم افزار به این نکته اشاره دارد که سورس کد پروژه ما برای اجرای تمام و کمال، نیاز به سایر کدها، لایبرری ها و حتی سایر نرم افزارها داشته باشد. توجه داشته باشیم که در توسعه ی نرم افزار، می بایست تمام تلاش خود را به کار بندیم تا این وابستگی ها به حداقل برسند. علاوه بر این، اصطلاحی داریم تحت عنوان Dependency Hell یا «جهنم وابستگی» که وقتی رخ می دهد که نرم افزار ثالثی که از آن در پروژه ی خود استفاده می کنیم تغییری در سورس کد اش ایجاد می کند که این تغییر منجر به عملکرد ناصحیح نرم افزار ما خواهد شد. diff --git a/fa/thing_25/README.md b/fa/thing_25/README.md new file mode 100644 index 00000000..865de090 --- /dev/null +++ b/fa/thing_25/README.md @@ -0,0 +1,11 @@ +# برای تست نرم‌افزار از دیتای واقعی استفاده کنید + +پیش از هر گونه توضیحی، سناریویی تعریف می‌کنیم تا ببینیم برای چند درصد از ما آشنایی دارد؛ نرم افزاری نوشته‌ایم -مثلا یک وب اپلیکیشن- حال نیاز است تا یکسری دیتای اولیه وارد دیتابیس کرده تا بتوانیم تست نهایی را انجام دهیم. پیش از هر چیز، چند یوزر می بایست تعریف کنیم؛ برای این کار، از نام کاربری‌هایی همچون ali1, ali2 و ali3 استفاده می کنیم. اکنون تک تک این یوزرها را می بایست به یک گروه کاربری ربط دهیم. مثلاً گروه‌های کاربری ادمین، کاربر معمولی و کاربر میهمان (در ضمن، برای ثبت نام در سایت، برای انتخاب نام کاربری حتماً می بایست هشت کاراکتر وارد کرد اما چون در مرحله ی تست است و قصد داریم برای ثبت نام و مهم‌تر از آن لاگین کردن، تعداد کاراکتر کمتری را وارد کنیم، بخشی از کد که مسئول چک کردن تعداد کاراکترهای نام کاربری است که کامنت می کنیم.) + +به علاوه این که آقا/خانم برنامه نویس برای تست یک اینپوت فرم -مثلا ناحیه یی برای وارد کردن نام خانوادگی- عبارت jfldjf'sdjfsjf یا چیزی شبیه به آن را وارد می کند! سناریو را بیش از این ادامه نمی‌دهیم اما پر واضح است که مثال‌های زیادی از این نوع رفتارهای توسعه دهندگان می‌توان زد به این صورت که از آنجا که ایشان فکر می‌کنند در مرحله ی تست هیچ‌ کس کد ایشان را نمی بیند، از دیتای غیر واقعی و … استفاده می کنند. + +وقتی ما به عنوان یک توسعه دهنده و گاهی اوقات هم تست کننده ی نرم افزار اقدام به تست می کنیم، تحت هیچ عنوان نمی بایست از نام های کاربری همانند آنچه در بالا گفته شد برای ثبت نام استفاده کنیم؛ علاوه بر این، برای تست کردن فرم ها و ... حتما می بایست دیتای واقعی وارد کنیم چرا که آدم های واقعی قرار است که این نرم افزار را مورد استفاده قرار دهند و در غیر این صورت، احتمال زیادی وجود دارد که به هدف نهایی خود که همان ارائه ی یک محصول باکیفیت و بدون باگ است نرسیم. + +خیلی از اوقات پیش می آید زمانی که برای تست نرم افزار خود بخشی از کد را کامنت می کنیم -از روی تنبلی- زمانی که می خواهیم محصول نهایی را Deploy (دیپلوی یا منتشر) کنیم، فراموش می کنیم که بخش مد نظر را از کامنت خارج کنیم و این می تواند تبعات بسیاری مخربی داشته باشد! + +خلاصه ی کلام این که تست کردن به این روش می‌تواند آینده ی اپلیکیشن را تحت الشعاع قرار دهد. همواره سعی کنید در فرایند تست محصول نهایی، از دیتای شبیه به واقعی استفاده کنید چرا که در بسیاری از مواقع، دیتای تستی -به صورت ناخواسته- منتشر شده و در اختیار End-user ها قرار می‌گیرد و نیاز به توضیح نیست که امروزه با وجود شبکه‌های اجتماعی، هر گونه «کم کاری» از طرف تیم برنامه نویسی شما می تواند در معرض دید هزاران کاربر بالقوه قرار گرفته و آبروی تیم برنامه نویسی شما را به کلی تحت تأثیر قرار دهد. diff --git a/fa/thing_26/README.md b/fa/thing_26/README.md new file mode 100644 index 00000000..3b44c46a --- /dev/null +++ b/fa/thing_26/README.md @@ -0,0 +1,26 @@ +# حتی یک ارور را هم نادیده نگیرید! + +پیش از هر چیز، ابتدا نیم نگاهی به داستانی فرضی داشته باشیم و در ادامه به بررسی ربط این داستان به ارورهای کدنویسی خواهیم پرداخت. فرض کنید که پس از فارغ التحصیلی از دانشگاه، چند سالی است که هم دانشکده یی های خود را ندیده اید و به لطف شبکه‌های اجتماعی، شما و همکلاسی هایتان همدیگر را می یابید. در یک کافه یا رستورانی قرار می‌گذارید تا یکدیگر را ملاقات کنید. زمان جلسه ساعت 5 بعد از ظهر است و اما شما تازه ساعت 4:30 از منزل بیرون رفته‌اید و از آنجا که اصلاً دوست ندارید پس از سال ها، آدم بدقولی جلوه کنید، با سرعت هرچه تمام تر به سوی محل قرار ملاقات پیش می روید. + +از این تاکسی به اون تاکسی، از این اتوبوس به آن اتوبوس، جاهایی را هم از کوچه پس کوچه‌ها می‌روید که سریع‌تر به مقصد برسید. در حال عبور کردن از مقابل مغازه یی که صاحب آن داشت جلوی مغازه اش را آبپاشی می کرد، کمی تلو تلو می‌خورید و ناگهان نقش بر زمین می شوید! + +با توجه به این که خیلی عجله دارید، اول احساس درد زیادی نمی‌کنید و به سرعت بلند شده، لباس هایتان را می تکانید و مجدد به سرعت هرچه تمام تر به راه خود ادامه می‌دهید و در نهایت تقریبا به‌موقع به قرار ملاقات خود می رسید. در حین گپ و گفتگو با دوستان، باز هم کمی احساس درد می‌کنید که با خود می‌گویید که "خب زمین خودم ام و کمرم کمی کوفتگی پیدا کرده!" در طول کل جلسه، آن طور که باید و شاید از در کنار دوستان قدیمی خود بودن لذت نمی برید تا این که جلسه به پایان می‌رسد اما از آنجا که ثانیه به ثانیه به درد کمر شما افزوده می شود، مجبور می‌شوید که فردای آن روز به درمانگاه مراجعه کنید و می‌بینید که دیسک کمر شما آسیب دیده است. + +واقعیت امر آن است که اگر به محض زمین خوردن، موضوع جدی گرفته می‌شد و به درمانگاه مراجعه می کردیم، شاید هرگز این آسیب دیدگی به دیسک های کمر کشیده نمی‌شد و صرفاً با چند روز استراحت و مراعات مشکل حل می شد! کدنویسی بسیاری از برنامه نویسان هم شبیه به داستان بالا است. چگونه؟ به این شکل که وقتی با اروری در کدهای خود مواجه می شوند، اگر آن ارور به گونه یی باشد که وی را از ادامه ی توسعه ی نرم افزارش نگاه ندارد، ارور را نادیده گرفته و به کار خود ادامه می‌دهند و همین مسأله منجر به بروز مشکلاتی گاها بسیار بزرگ در آینده ی نرم‌افزار می شوند. اگر بخواهیم به مسأله ی ارورها از این بعد نگاه کنیم، ارورهای نرم افزاری را می‌توان به دسته های زیر تقسیم‌بندی کرد: + +- دستورات return: خیلی اوقات پیش می‌آید فانکشن هایی که می نویسیم، باید چیزی را اصطلاحاً ریترن کنند اما هرگز چک نمی‌کنیم که فانکشن مد نظر دقیقاً چه چیزی را ریترن کرده است چرا که گاهی اوقات پیش می‌آید که اگر فانکشن ما چیزی را ریترن نکند، ما در مراحل ابتدایی توسعه ی نرم‌افزار اصلاً متوجه آن نخواهیم شد. + +- اکسپشن ها: مدیریت Exception ها در بسیاری از زبان‌های برنامه نویسی سطح بالا دیده می‌شود و کار برنامه نویسان را ساده کرده است چرا که در صورت بروز چنین اکسپشن هایی، مفسر زبان برنامه نویسی مد نظر به ما هشدار خواهد داد. گاهی اوقات برنامه نویسانی را می‌بینیم که مثلاً در زبان برنامه نویسی پی اچ پی به شکل زیر از ساختار مدیریت اکسپشن ها استفاده می کنند: +```C# +try { + // do something +} catch() {} // ignoring catching any errors +``` +همان طور که در بلوک کد بالا مشاهده می شود، برنامه نویس به خوبی بخش try را هندل کرده است اما اگر به هر دلیلی این قسمت به مشکل برخورد، در بخش catch هیچ کدی برای گرفتن اکسپشن ها نوشته نشده است! + +به طور خلاصه، باید بگوییم همان‌طور که بی توجه به درد کمر می‌تواند منجر به صدماتی جدی به دیسک های کمر شود، بی توجه به ارورها، هشدارها، اکسپشن ها و … در حین فرایند توسعه ی نرم‌افزار -خواه نرم‌افزار دسکتاپ باشد، خواه اپ موبایل یا وب اپلیکیشن- می‌تواند منجر به مشکلاتی جدی در مراحل تکمیلی توسعه ی نرم‌افزار گردد که از آن جمله می‌توان به موارد زیر اشاره کرد: +- دشواری در یافتن باگ ها زمانی که برنامه بزرگ‌تر می شود. +- ایجاد حفره های امنیتی در نرم‌افزار و بالا رفتن ضریب هک. +- عدم تمایل سایر توسعه دهندگان به مشارکت در توسعه ی نرم‌افزار شما + +لذا ضروری به نظر می رسد که به محض مواجهه با ارورهایی از هر نوع، فورا اقدام به رفع آن ها کرده و هرگز کار امروز را به فردا محول نکنیم. diff --git a/fa/thing_27/README.md b/fa/thing_27/README.md new file mode 100644 index 00000000..f4d87c40 --- /dev/null +++ b/fa/thing_27/README.md @@ -0,0 +1,14 @@ +# فرهنگ استفاده از یک زبان برنامه‌نویسی را در کنار سینتکس آن بیاموزید + +یش از آن که به موضوع این بخش از آموزش که «صرفاً سینتکس یک زبان برنامه نویسی را فرا نگیرید، بلکه فرهنگ استفاده از آن زبان را نیز بیاموزید» است بپردازیم، نیاز است تا مثالی از دنیای واقعی و آموزش یک زبان زنده بزنیم. + +در فرایند آموزش زبان‌های خارجی به‌خصوص زبان انگلیسی، بسیاری از مدرسین زبان را می‌بینیم که می‌گویند "برای یادگیری زبان انگلیسی، شما نیاز به فراگیری چهار مهارت Reading, Writing, Listening, Speaking دارید." این توصیه اصلاً اشتباه نیست اما ناقص است! پیش از آن که بگوییم نقص این توصیه کجا است، ابتدا مثالی می زنیم. فرض کنیم که یک نفر از ایران به کشوری انگلیسی زبان مثل کانادا مهاجرت می کند. این فرد در محفلی نشسته و همه گپ و گفتگو می کنند. آقا/خانم مهاجر پس از آن که چیزی می گوید، یکی از حضار از حرفش لذت می‌برد یک شصت به وی نشان می دهد . شصت نشان دادن در فرهنگ غربی یعنی Bravo یا «آفرین، ایول، خیلی خوب بود!» اما در فرهنگ ما چه طور؟ نیاز به توضیح نیست که در فرهنگ ایرانی این علامت معنی خیلی خوبی ندارد! + +آقا/خانم مهاجر به دلیل این که از زیرساخت های فرهنگی کشور مقصد خبر ندارد، در چنین شرایطی کاملاً دستپاچه شده و حتی ممکن است سوء تفاهم در ذهنش شکل گیرد اما این در حالی است که اگر در کلاس‌های زبانی که پیش از مهاجرت شرکت کرده بود، مدرس اش علاوه بر مهارت های چهارگانه ی Reading, Writing, Listening, Speaking مهارت پنجمی تحت عنوان Culture یا «فرهنگ» را نیز به وی آموخته بود، او هرگز دچار سوء تفاهم نمی شد. + +به خاطر داشته باشید لیست این خرده فرهنگ‌ها بسیار زیاد است اما اگر بخواهیم به نمونه یی دیگر از اختلافات فرهنگی میان ایران و غرب مثال بزنیم، این که در ایران وقتی ما بخواهیم عدم تمایل خود را برای انجام کار با سر نشان دهیم، سر خود را بالا می‌اندازیم و نظر منفی خود را القاء می‌کنیم اما در فرهنگ غرب، برای نشان دادن این حس، سر خود را به سمت راست و چپ تکان می دهند! +یادگیری زبان‌های برنامه نویسی هم تاحدودی شبیه به یادگیری یک زبان زنده ی دنیا است. به عبارت دیگر، علاوه بر یادگیری سینتکس یک زبان برنامه نویسی، شما باید «فرهنگ» استفاده از آن زبان به‌خصوص را نیز بیاموزید. خیلی اوقات ما به خاطر عدم آگاهی از زیر و بم یک زبان برنامه نویسی، نمی‌توانیم آن طور که باید و شاید از تمام پتانسیل زبان انتخابی خود بهره ببریم و به طور مثال از یک زبان شیء گرای قدرتمند، همچون یک زبان پروسیژرال ساده استفاده می‌کنیم. + +علاوه بر این، آشنایی با زبان‌های برنامه نویسی مختلف، می‌تواند به شما دید بازتری در پیاده‌سازی ایده های نرم افزاری بدهد. به طور مثال، اگر یک زبان برنامه نویسی مثل پایتون، زبان اصلی شما باشد اما در عین حال با زبان‌هایی همچون جاوا و پی اچ پی هم آشنایی داشته باشید، درک به مراتب بهتری از تفاوت زبان‌های مختلف و دلایل انتخاب یک زبان برای پروژه یی خاص خواهید داشت. علاوه بر این، آشنایی با زبان‌های برنامه نویسی مختلف، می‌تواند دید خوبی در درک دیزاین پترن ها به شما بدهد. + +هشدار این نکته که آشنایی با زبان‌های برنامه نویسی چیز خوبی است هرگز بدان معنا نیست که شما باید از هر زبان برنامه نویسی کمی بدانید اما در هیچ کدام حرفه یی نباشید؛ همچون اقیانوسی به عمق یک سانتی متر! همواره توصیه این است که به جای تست کردن تکنولوژی های مختلف، به یک زبان برنامه نویسی چسبیده و در آن حرفه یی شد اما در عین حال نیم نگاهی هم به سایر فناوری ها داشته باشیم. diff --git a/fa/thing_28/README.md b/fa/thing_28/README.md new file mode 100644 index 00000000..07e21950 --- /dev/null +++ b/fa/thing_28/README.md @@ -0,0 +1,15 @@ +# اکسپش‌ها را به راحت‌ترین شکل ممکن هَندل کنید + +فرض کنیم برای هندل کردن Exception ها یا بهتر بگوییم «خطاهای» برنامه ی خود، کلاسی مخصوص این کار می نویسیم که مسئول هندل کردن هر گونه اکسپشنی است. مثلاً در زبان PHP برای هندل کردن اکسپشن ها، از ساختار زیر استفاده می شود: +``` C +try { + // do something + } catch (Exception $e) { + return $e; + } + ``` +کدی که می‌خواهیم اجرا شود را داخل بلوک try قرار داده و در صورت بروز هر گونه اکسپشنی، بلوک داخل catch اجرا خواهد شد. برخی برنامه نویسان هستند که داخل بلوک catch از یک جفت try/catch دیگر نیز استفاده می‌کنند تا بتوانند به صورت لایه به لایه، اصطلاحاً اکسپشن ها را هندل کنند. + +چنین رویکردی گاهی اوقات منجر به سردرگمی های فراوانی می‌شود و نتیجه این که وقتی با یک اکسپشن رو به رو می شوید، متوجه نخواهید شد که مشکل دقیقاً از کجا است. همواره سعی کنید برای هندل کردن اکسپشن ها راحت‌ ترین و سر راست ترین رویکرد ممکن را انتخاب کنید تا در حین بزرگ شدن برنامه، با کمترین میزان سردرگمی مواجه شوید. + +علاوه بر این، توجه داشته باشید که کاربر نرم‌افزار شما تحت هیچ عنوان نباید اکسپشن هایی که اساساً راهنمای توسعه دهندگان برای رفع باگ های سیستم هستند را مشاهده کنند چرا که علاوه بر ایجاد یک تجربه کاربری نامطلوب، اکسپشن ها معمولاً اطلاعاتی زیرساخت از نرم‌افزار در اختیار کاربر قرار می‌دهند که همین مسأله می‌تواند منجر به پایین آمدن ضریب امنیتی نرم‌افزار شما شود. diff --git a/fa/thing_29/README.md b/fa/thing_29/README.md new file mode 100644 index 00000000..eec4c488 --- /dev/null +++ b/fa/thing_29/README.md @@ -0,0 +1,11 @@ +# فرایند توسعه یک نرم‌افزار خوب اصلاً شانسی نیست + +اگر ما به هر چیزی از مکانیکی گرفته تا نجاری و یا طراحی و سایر کارهای هنری نگاه کنیم، خارج از گود همه این کارها ساده به نظر می رسند؛ مدیران معمولاً بر این باورند که توسعه دهندگان اصلاً کار عجیب و غریبی انجام نمی‌دهند و توسعه دهندگان هم در مقابل فکر می‌کنند مدیران فقط در دفتر خود نشسته و دستور می دهند! + +برنامه نویسی صرفاً نوشتن کد نیست بلکه توانایی حل مسئله، الگوریتم نویسی، تحلیل دیتابیس و … جزو بخش‌های لاینفک حرفه ی برنامه نویسی اند که کمتر مد نظر قرار داده می‌شوند و سختی این دست مهارت ها در مقایسه با کدنویسی به مراتب بیشتر است. + +با در نظر گرفتن این مسائل، باز هم شاهد برخی برنامه نویسان هستیم که صرفاً درگیر فرایند توسعه ی نرم‌افزار بوده و هرگز در مسائلی همچون تحلیل بازار، تجربه ی کاربری، تأمین بودجه ی توسعه ی نرم افزار، راه اندازی سرور، تضمین کیفیت محصول نهایی، نگهداری نرم‌افزار و … دخالت نمی کنند و معمولاً فکر می‌کنند که دشوارترین کار ممکن در توسعه ی یک محصول نرم‌افزاری مختص به خودشان است و سایر اعضای تیم هیچ کار خاصی انجام نمی دهند. + +گاهی اوقات مدیران شرکت های نرم افزاری هم در چنین دامی می افتند. پروژه آنقدر سر وقت، بدون باگ و خوب تحویل مشتری می‌شود که مدیر فکر می‌کند همه چیز با «اجی مجی لاترجی» درست شده و حضور «مدیر پروژه» را اساساً اضافی تلقی می کنند. + +این‌ها دام‌هایی هستند که معمولاً اعضای تیم های نرم افزاری در آن‌ها می‌افتند که شدیداً باید از این‌گونه دام‌ها حذر کرد. در فرایند توسعه ی نرم‌افزار سعی کنید در یک حوزه عمیق شوید و به خوبی زیر و بم آن را فرا بگیرید اما هرگز از سایر حوزه ها مثل هاستینگ، کانفیگ سرور، مسائل امنیتی، بهینه سازی و … غافل نشوید چرا که آگاهی از این حوزه ها، منجر به این خواهد شد تا با دید بازتری بتوانید برای حل مسائل پیچیده ی پروژه ی خود، الگوریتم هایی اصولی و بهینه بنویسید. diff --git a/fa/thing_30/README.md b/fa/thing_30/README.md new file mode 100644 index 00000000..0dbb82d7 --- /dev/null +++ b/fa/thing_30/README.md @@ -0,0 +1,23 @@ +# آشنایی با قانون DRY + +در حوزه ی توسعه ی نرم افزار، اصول و قواعد بسیاری وجود دارد که گاها یکی از دیگری مهم‌تر جلوه می‌کند اما یکی از اساسی‌ترین قواعد برنامه نویسی، قانون DRY است که مخفف واژگان Don't Repeat Yourself به معنی«دوباره کاری نکن» است! + +این قانون توسط دو توسعه‌دهنده به نام های Andy Hunt و Dave Thomas ابداع شد که بسیاری از دیزاین پترن های معروف برنامه نویسی، ریشه در این قانون دارند. + +برنامه نویسی که بتواند تشخیص دهد کدام بخش‌های کد اصطلاحاً Duplicate یا «مشابه» هستند و تمام تلاش خود را به کار بندد تا با استفاده از کلاس‌ها و فانکشن های مختلف، میزان استفاده از کدهای تکراری در سراسر برنامه را به حداقل برساند، در نهایت سورس کد تمیز تری تحویل خواهد داد که در آینده نگهداری چنین پروژه یی به مراتب راحت‌تر از سورس کدی است که پر است از کدهای مشابه! + +هرچه میزان کدهای دوپلیکیت در سورس کد شما بیشتر باشد، احتمال ایجاد باگ در آینده به مراتب بیشتر خواهد شد؛ علاوه بر این، اگر روزی بخواهید بخشی از کد خود را ریفکتور کنید یا تغییر دهید، به جای یک بخش، می بایست چندین بخش را ریفکتور کنید که این کاری بس زمان گیر است. + +در فرایند توسعه ی نرم افزار، بخش‌های بسیاری از کد را می‌توان دید که تکراری هستند و قانون DRY دقیقاً برای چنین موقعیت هایی است. شما به عنوان یک توسعه‌دهنده ی حرفه یی، همواره باید این ذهنیت را داشته باشید که در نرم افزاری که می نویسید -خواه یک اپ موبایل باشد و خواه یک سایت- صرفاً از یک راه باید بتوان کار خاصی را انجام داد (مثلاً ارتباط با دیتابیس) و این راه‌کار باید تا حد ممکن ساده، ایمن و اثربخش باشد. + +دوپلیکیت شدن در منطق نرم‌افزار می‌تواند به اشکال مختلفی جلوه کند که از جمله ی رایج ترین آن‌ها می‌توان به آبجکت هایی که از روی کلاس خاصی ساخته می‌شوند اشاره کرد و اینجا است که بسیاری از دیزاین پترن ها به داد توسعه دهندگان می آیند. در واقع، ابداع دیزاین پترن ها یا «الگوهای طراحی» جلوگیری از استفاده از کدهای مشابه است. + +به طور مثال، اگر آبجکتی داریم که «عملکردها و رفتارهای» متنوعی از آن انتظار می رود، به جای استفاده از دستورات شرطی if برای هندل کردن چنین موقعیت هایی، چنین عملکردها و رفتارهایی را می‌توان با استفاده از دیزاین پترن Strategy عملی ساخت. + +علاوه بر دیزاین پترن ها، یکسری اصول کدنویسی که تحت عنوان SOLID شناخته می‌شوند نیز بر پایه ی اصل DRY هستند (برای آشنایی بیشتر با مفهوم SOLID، به آموزش آشنایی با قوانین پنج گانهٔ SOLID مراجعه نمایید.) به طور مثال، حرف S در ابتدای SOLID به اصطلاح Single Responsibility اشاره دارد. به عبارت دیگر، هر کلاسی که در پروژه ی خود ایجاد می‌کنیم فقط و فقط باید مسئول یک کار باشد و در صورت نیاز به اعمال تغییرات در کلاس مد نظر، فقط و فقط باید یک دلیل برای ایجاد آن تغییر وجود داشته باشد نه اینکه کلاس مد نظر در جای جای نرم‌افزار برای کارهای مختلفی استفاده شده باشد و به هر دلیلی، نیاز به اعمال تغییرات در آن کلاس داشته باشیم. + +به عنوان مثالی دیگر، حرف O در SOLID به اصلی تحت عنوان Open/Closed Principle اشاره دارد. این اصل حاکی از آن است که کدی که می نویسید باید «امکان توسعه یافتن را به برنامه نویسان دیگر بدهد اما تحت هیچ عنوان امکان ایجاد تغییر در کدهای قبلی را ندهد.» چنین اصلی این تضمین را ایجاد می‌کند که نرم‌افزار در فرایند توسعه و تکمیل با این مشکل مواجه نخواهد شد که برنامه نویس دیگری بیاید، بخش‌هایی را تغییر دهد غافل از اینکه این اعمال تغییرات، منجر به ایجاد خرابی در سایر بخش‌های نرم‌افزار شده است. + +به طور کلی، مد نظر داشتن قانون DRY در توسعه ی نرم افزار، راه‌کاری است که از آن طریق می‌توان برنامه‌هایی اصولی تر، ساده تر، بدون باگ تر، قابل نگهداری تر و مهم‌تر از همه، باکیفیت تر نوشت؛ البته هرگز فراموش نکنیم که گاهی اوقات شرایطی برای توسعه‌دهنده پیش می‌آید که مجبور به تکرار کد است -مثلا در فرایند Denormalization دیتابیس- که در چنین شرایطی دوباره کاری اصلاً مشکلی ندارد! + +به خاطر داشته باشید در کار با دیتابیس یا پایگاه داده، Denormalization به فرایندی گفته می‌شود که از آن طریق توسعه‌دهنده سعی می‌کند پرفورمنس یا عملکرد فراخوانی داده‌ها از دیتابیس را با اضافه کردن داده‌های تکراری یا اضافی و همچنین گروه بندی کردن داده‌ها ارتقاء بخشد. نقطه ی مقابل این فرایند، Normalization قرار دارد که تمرکزش بر کاهش هرچه تمام تر داده‌های اضافی و تکراری در دیتابیس است. diff --git a/fa/thing_31/README.md b/fa/thing_31/README.md new file mode 100644 index 00000000..b94439d4 --- /dev/null +++ b/fa/thing_31/README.md @@ -0,0 +1,34 @@ +# آشنایی با مراحل توسعهٔ نرم‌افزار + +ه طور کلی، فرایند توسعه ی نرم‌افزار به‌خصوص وب اپلیکیشن ها به ۴ دسته ی زیر تقسیم‌بندی می‌شوند که یک توسعه‌دهنده باید به خوبی با ویژگی‌های هر کدام آشنا باشد که در این آموزش، به تفصیل در مورد خصوصیات هر مرحله توضیح خواهیم داد. + +فرایند توسعه ی نرم‌افزار دارای مراحل مختلفی است که به هر کدام از آن‌ها اصطلاحاً Tier (تایر به معنی مرحله) گفته می شود. شرکت های کوچک دارای سه محیط Development و Stage و Production هستند اما شرکت های متوسط و بزرگ معمولاً یک محیط QA یا Quality Assurance به معنی «تضمین کیفیت» نیز می باشند. + +مفهوم Development: این محیط که به صورت خلاصه dev نامیده می شود، شامل کلیه ی سخت افزارها و نرم افزارهای مورد نیاز برای اجرای صحیح نرم‌افزار است که توسط توسعه‌دهنده مورد استفاده قرار می‌گیرد و معمولاً شامل آخرین تغییرات صورت گرفته روی نرم‌افزار است. توسعه‌دهنده تغییرات مد نظر خود را روی سورس کد اعمال کرده و آن‌ها را در محیط توسعه ی نرم‌افزار لوکال خود -مثلا لپ تاپش- تست می‌کند و از درست کار کردن کدها اطمینان حاصل می کند. + +لازم به ذکر است که این محیط توسعه ی نرم‌افزار کاملاً فردی است و تغییرات اعمال شده روی کد، عملکرد کدهای سایر توسعه دهندگان را تحت تأثیر خود قرار نخواهد داد. علاوه بر این، در محیط dev، توسعه‌دهنده از ابزارهای مختلفی برای توسعه ی نرم‌افزار استفاده می‌کند که از آن جمله می‌توان به ماشین‌های مجازی، لایبرری های مختلف، IDE های مختلف، کامپایلر و … اشاره کرد. با توجه به اینکه محیط توسعه ی dev یک محیط کاملاً فردی است و از توسعه‌دهنده یی به توسعه‌دهنده ی دیگر متفاوت است، این محیط را Local Environment یا Sandbox هم می نامند. + +مفهوم Staging: این مرحله از توسعه ی نرم‌افزار که تحت عنوان Integration هم شناخته می شود، مرحله یی است که سایت یا اپلیکیشن در محیطی کاملاً شبیه به محیط Production تست می‌شود و Quality Assurance به معنی «تضمین کیفیت» که به طور خلاصه QA نامیده می‌شود نیز روی آن اعمال می گردد. کانفیگ سروری که برای این مرحله از کار استفاده می شود کاملاً مشابه سرور اصلی است. تیم های توسعه ی نرم‌افزار حرفه یی برای اپلیکیشن هایی که هزاران کاربر دارند را پیش از فرستادن روی سرور اصلی، حتماً روی Staging Server تست می کنند. + +مفهوم Production: این محیط که اصطلاحاً محیط Live نامیده می شود، همان سروری است که نرم‌افزار -مثلا وب سایت- روی آن پیاده‌سازی شده و کاربران نهایی می‌توانند از آن استفاده کنند و آخرین مرحله از فرایند توسعه ی نرم‌افزار است. +اپلیکیشن پس از تست و اطمینال حاصل کردن از درست بودن همه چیز و Bug-free بودن آن، روی سرور Production فرستاده می شود. + +نکته توجه داشته باشید که آپدیت کردن اپلیکیشن در مرحله ی Production باید در زمانی صورت گیرد که حداقل تعداد کاربران در حال استفاده از اپلیکیشن -مثلا وب سایت- باشند (مثلا ساعت ۳ نیمه شب). علاوه بر این، زمانی که آخرین تغییرات روی سرور Live اعمال می شوند، باید تمامی اعضای تیم از این قضیه مطلع باشند تا در صورت بروز هرگونه مشکلی، خیلی سریع بتوان آن را مرتفع ساخت. + +در واقع Production Deployment شکل‌های مختلفی دارد که بسته به ماهیت اپلیکیشن، می‌توان یکی از آن‌ها را انتخاب کرد: +- جایگزین -Override- کردن کدهای قدیمی با کدهای جدید از طریف اف تی پی +- پیاده‌سازی نسخه یی جدید از اپلیکیشن روی سرور به موازات نسخه ی قبلی و هدایت کردن کاربران به نسخه ی جدید با تغییر کانفیگ سرور +- استفاده از یک سرور کاملاً جدید حاوی آخرین ریلیس و ریدایرکت کردن ترافیک از سرور قدیمی به سرور جدید + +چه موقع Rollback کنیم؟ +گاهی اوقات در فرایند توسعه نرم‌افزار پیش می‌آید که همه چیز به خوبی پیش نمی‌رود و بلافاصله پس از Deployment یا «فرستادن آخرین نسخه روی سرور اصلی» اپلیکیشن می ترکد! در چنین شرایطی ما نیاز به Rollback کردن داریم. به عبارت دیگر، اپلیکیشن خود را به آخرین ورژنی که به درستی کار می‌کرد باز گردانیم. گاهی اوقات با Rollback کردن نه تنها مشکل برطرف نمی شود، بلکه چندین مشکل دیگر نیز ایجاد می‌گردد؛ لذا در چنین شرایطی کاملاً باید با احتیاط عمل کنیم. زمانی که نیاز به رول بک پیدا کردید، پیش از هرگونه اقدامی، سؤالات زیر را از خود بپرسید؟ + +آیا مشکل به خاطر کدی که Deploy کردید بوجود آمد یا دلیل دیگری وجود دارد؟ شما صرفاً زمانی می‌توانید رول بک کنید که مشکل بوجود آمده مرتبط با فایل‌هایی باشد که آپلود کرده‌اید و در غیر این صورت، رول بک کاری از پیش نخواهد برد! ممکن است دقیقا در زمانی که شما آخرین ریلیس را آپلود می کنید، یک مشکل سروری هم بوجود آید و شما فکر کنید که مشکل از آخرین آپدیت بوده و کاملا گمراه شوید. + +آیا رول بک کردن امکان‌پذیر است؟ هر Release یا نسخه یی از اپلیکیشن قابل رول بک کردن نیست؛ فرض کنید که آخرین ریلیس نرم‌افزار شما حاوی اسکمای متفاوتی از دیتابیس است که در چنین شرایطی رول بک کردن اوضاع را وخیم تر هم می کند. + +به هر حال، اگر پاسخ شما به دو سؤال فوق «آری» است، با خیال راحت می‌توانید رول بک کنید اما توجه داشته باشید که پاسخ آری دادن به دو سؤال بالا هرگز کاری آسان نیست. + +نکته ی دیگری که در ارتباط با ریلیس نسخه های جدید نرم‌افزار باید مد نظر قرار داد، مفهومی است تحت عنوان Automatic Deployments to Production که این اصطلاح حاکی از آن است که ما به صورت اتوماتیک، آخرین تغییرات را بلافاصله روی سرور اصلی آپلود کنیم. به طور مثال، می‌توان نرم‌افزار اف تی پی را به گونه یی تنظیم کرد که بلافاصله پس از مشاهده ی تغییری در هر فایلی، آن فایل را جایگزین فایل متناظر روی سرور کند (جهت آشنایی بیشتر با مفهوم اف تی پی، به آموزش اف تی پی چیست؟ مراجعه نمایید.) + +چنین کاری را می‌توان به عنوان یکی از پر ریسک ترین و خطرناک ترین کارها در فرایند توسعه ی نرم‌افزار قلمداد کرد و شدیدا باید از آن پرهیز کرد. فرض کنید توسعه‌دهنده یی به اشتباه کدی را تغییر می‌دهد و آن کد هم بلافاصله روی سرور آپلود می‌شود و فرایند اجرای صحیح نرم‌افزار دچار اختلال می شود. diff --git a/fa/thing_32/README.md b/fa/thing_32/README.md new file mode 100644 index 00000000..91cc29a0 --- /dev/null +++ b/fa/thing_32/README.md @@ -0,0 +1,13 @@ +# به‌کارگیری درست از اصول برنامه‌نویسی شیٔ‌گرا + +در برنامه نویسی شیء گرا مفهومی داریم تحت عنوان Encapsulation که به زمانی اطلاق می‌شود که ما Attribute ها وBehavior های یک آبجکت را در کپسولی فرضی در کنار یکدیگر قرار می دهیم. علاوه بر این، با به کارگیری مفهومی تحت عنوان Encapsulation ما خواهیم توانست دسترسی به بخش یا بخش‌هایی از یک کلاس یا آبجکتی که بر اساس آن کلاس نوشته شده را محدود کنیم. + +حال ممکن است این سؤال برای شما پیش بیاید که "اگر من خودم اقدام به ساخت یک کلاس می کنم، چه لزومی دارد که بخش یا بخش‌هایی از کلاس ساخته شده را از خودم پنهان سازم؟" در پاسخ به چنین سؤالی بایستی گفت که در اینجا قضیه پنهان کاری و … نیست، بلکه در اینجا منظور به حداقل رساندن وابستگی میان بخش‌های مختلف برنامه است. در چنین شرایطی، ایجاد یک تغییر کوچک در کلاس مد نظر -مثلا محدود کردن سطح دسترسی به برخی قابلیت‌های کلاس- فوراً روی تمامی آبجکت های ساخته شده از روی این کلاس اعمال خواهد شد. + +امروزه برخی برنامه نویسان را می‌بینیم که مثلاً کلاسی ساخته‌اند که یک متد main چند صد خطی دارد و یا کلاسی که صرفاً داری متدهای set و get است. چنین نمونه‌هایی حاکی از آنند که توسعه دهندگان هنوز با مفهوم واقعی شیء گرایی آشنا نشده اند. + +پیش از این گفتیم که یک آبجکت دربرگیرنده ی یکسری Attribute ها وBehavior ها است و این در حالی است که رفتار آبجکت بسته به فضایی که در آن قرار گرفته متغیر است. برای روشن شدن این مسأله مثالی می زنیم. فرض کنیم یک درب منزل داریم. این در، می‌تواند چهار State (یا حالت) مختلف داشته باشد: بسته، باز، در حال بسته شدن و در حال باز شدن اما این درب منزل به هر حال دارای دو عملکرد بیشتر نیست: باز شدن و بسته شدن و بسته به حالتی که در آن قرار دارد، عملکردهای باز و بسته رفتارهای متفاوتی می توانند داشته باشند. + +برای روشن تر شدن مطلب، مثالی از دنیای برنامه نویسی بزنیم. فرض کنیم سه کلاًس داریم تحت عناوین Customer, Order و Item. کلاس Customer برای نگهداری اعتبار حساب مشتریان و سایر مسائل مربوطه مورد استفاده قرار می گیرد. آبجکتی هم که از روی کلاس Order ساخته می‌شود مسئول سفارش‌های مربوط به یک مشتری را هندل می‌کند و آبجکت های ساخته شده از روی کلاس Item هم مسئول اضافه کردن محصول به سبد خرید هستند. داشتن چنین کلاس هایی حاکی از آنند که ما به درستی اصول برنامه نویسی شیء گرایی را به کار می گیریم. + +اما در مقابل، برنامه نویسانی که تجربه ی کمتری در زمینه ی شیء گرایی دارند تمامی منطق نرم افزاری خود را مثلاً در کلاسی تحت عنوان OrderService قرار داده و بسته به نیاز خود آبجکت هایی از روی آن می سازند که این اصلا کار درستی نیست! به عنوان فصل الخطاب، سعی کنید تا حد ممکن یکی از اصول مهم برنامه نویسی شیء گرا یعنی Encapsulation را در حین کدنویسی رعایت کنید. diff --git a/fa/thing_33/README.md b/fa/thing_33/README.md new file mode 100644 index 00000000..89ede394 --- /dev/null +++ b/fa/thing_33/README.md @@ -0,0 +1,22 @@ +# اعداد اعشاری با خطای محاسباتی در کامپیوتر ذخیره می‌شوند + +در این بخش می خواهیم در مورد اعداد اعشاری و نحوه ی ذخیره ی آن ها در کامپیوتر صحبت کنیم، بنابراین بهتر است در ابتدا تعریفی از این نوع اعداد با ذکر مثالی داشته باشیم. + +یک خط کش ۱۰ سانتی متری را در ذهن خود متصور شوید؛ حال عدد ۳/۶ را روی این خط کش فرضی در نظر بگیرید. این عدد از 3 بزرگتر و از 4 کوچکتر است. برای نشان دادن این که این عدد چقدر از 3 بزرگتر و از 4 کوچکتر است از علامت ممیز یا اعشار / استفاده می کنیم که به طور کلی، به این دست اعداد «اعداد اعشاری» می گوییم. بنابراین می توان گفت که یک عدد اعشاری بین دو عدد صحیح قرار دارد. + +برای تعریف اعداد صحیح در کامپیوتر از استانداردهای IEEE استفاده می شود. بر اساس این استاندارد برای ذخیره ی هر عدد اعشاری سه فیلد در نظر گرفته می شود: +- اعشار یا مانتیس +- توان +- علامت + +برای مثال، بر طبق این استاندارد داریم: + +101 × 2.7495 = 27.495 + +که 2.7495 مانتیس، 1 توان و علامت آن نیز مثبت است (البته اعداد در کامپیوتر در پایه ی 2 ذخیره می شوند نه پایه ی 10). + +هر پیاده سازی اعداد اعشاری تعداد مشخصی بیت را برای مانتیس در نظر می گیرد، به عبارت دیگر تعداد اعداد قابل ذخیره سازی در کامپیوتر با محدودیت مواجه است. برای مثال برای ذخیره ی اعداد اعشاری در سیستم های ۳۲ بیتی، برای مانتیس ۲۳ بیت در نظر گرفته شده است. این موضوع باعث می شود که نتوانیم اعداد اعشاری که نمایش آن ها دارای تعداد رقم اعشاری متناهی نیست را به طور دقیق در کامپیوتر ذخیره کنیم. + +برای ذخیره سازی هر عدد بسته به فضای اختصاص داده شده به مانتیس، ابتدا عدد مورد نظر گرد می شود و سپس در کامپیوتر ذخیره می شود؛ به همین دلیل ممکن است نمایش یک عدد اعشاری در کامپیوتر 32 بیتی با کامپیوتر 64 بیتی متفاوت باشد، چرا که فضای اختصاص داده شده به مانتیس در آن ها متفاوت است. + +بنابراین باید توجه داشته باشیم که امکان ذخیره سازی دقیق تمام اعداد حقیقی که بخش اعشاری آن ها دارای تعداد نامتناهی رقم است در کامپیوترها وجود ندارد و به دلیل این نوع ذخیره سازی در زمان کدنویسی و انجام محاسبات روی اعداد صحیح ممکن است با خطای گرد کردن یا Roundoff Error مواجه شویم و جواب های غیر قابل انتظار از محاسبات کامپیوتری دریافت کنیم. بنابراین می توان گفت که بهتر است در برنامه هایی که نیازمند محاسبات دقیق هستند تا حد امکان از اعداد اعشاری استفاده نکنیم. diff --git a/fa/thing_34/README.md b/fa/thing_34/README.md new file mode 100644 index 00000000..c3d0db65 --- /dev/null +++ b/fa/thing_34/README.md @@ -0,0 +1,17 @@ +# جاه طلبی خود را با شرکت در پروژه های متن باز برآروده کنید! + +اگر شما برنامه نویسی باشید که در یک شرکت آی تی کار می‌کند، به احتمال قریب به یقین هر روز روی پروژه هایی کار می‌کنید که اصلاً جذاب نیستند به طوری که بارها و بارها می بایست یک کار واحد را انجام دهید؛‌ مثلاً بخش لاگین یک سایت را بنویسید و یا سیستم مالی یک نرم‌افزار حسابداری را تکمیل کنید. + +در چنین شرایطی حس جاه طلبی که یکی از خصیصه های اصلی اکثر توسعه دهندگانی است که دوست دارند کارهای کارهای خارق‌العاده یی انجام دهند تحت هیچ عنوان ارضاء نمی‌شود و نتیجه این که پس از مدتی از کار خود خسته می‌شوند. خبر خوشحال کننده برای این دست توسعه دهندگان این است که می‌توانند شروع به کار روی پروژه های اپن سورس کنند چرا که در چنین شرایطی می‌توانند واقعاً چیزی را که دوست دارند کدنویسی کنند. + +امروزه به یمن پلتفرم هایی همچون گیت هاب و غیره، هزاران پروژه ی اپن سورس پرطرفدار وجود دارد که بخش قابل توجهی از آن‌ها فعال بوده و توسعه دهندگان بسیاری روی آن‌ها کار می‌کنند. این پروژه های اپن سورس طیف گسترده یی را شامل می شوند؛ از سیستم عامل گرفته تا هوش مصنوعی، ربات ها، یادگیری ماشینی و غیره به طوری که برای هر سلیقه یی، می‌توان یک پروژه ی مناسب یافت! + +چیزی که در زمینه ی پروژه های اپن سورس همواره می بایست مد نظر داشت، این است که کار کردن روی این دست پروژه ها هیچ گونه عایدی برایتان نخواهد داشت؛ لذا اگر به دنبال کسب درآمد از طریق مشارکت در پروژه های اپن سورس هستید، بایستی بگوییم که متأسفانه مسیر نادرستی را انتخاب کرده اید. + +گرچه کار کردن روی پروژه های اپن سورس عایدی چندانی به صورت مستقیم برای توسعه دهندگان ندارد، اما خبر خوب این که مشارکت در این پروژه های اپن سورس منجر به تقویت رزومه ی توسعه‌دهنده شده به طوری که در آینده فرصت های شغلی به مراتب بهتری برایش رقم خواهد خورد و زمانی که روی توسعه ی پروژه های اپن سورس صرف کرده است، به شکلی دیگر جبران خواهد شد! + +علاوه بر ارضاء شدن حس درونی توسعه‌دهنده پس از مشارکت در پروژه های اپن سورس، اتفاقات خوبی دیگر نیز در انتظار وی هستند که از آن جمله می‌توان به این نکته اشاره کرد که ما با کار کردن روی پروژه های اپن سورس، با نحوه ی کدنویسی سایر برنامه نویسان سراسر دنیا آشنا شده و خواهیم دید که یک توسعه‌دهنده دیگر، چه راه‌کاری برای مسأله یی یکسان به در نظر گرفته است و همین مسأله می‌تواند به بهبود رویکردمان در برنامه نویسی کمک کند. + +در ضمن، زمانی که ما در یک پروژه ی اپن سورس مشارکت می‌کنیم و بخشی که کدنویسی کرده‌ایم مورد قبول واقع می‌گردد -البته در بسیاری مواقع هم سورس ما صد در صد رد خواهد شد- این مسأله می‌تواند به افزایش اعتماد به نفس ما کمک کند. چه چیزی بهتر از این که در حوزه ی فناوری اطلاعات فرد تأثیر گذاری باشیم و کمک به توسعه ی چیزی کنیم که تا سال‌های سال، چندین هزار نفر کاربر عادی از آن استفاده کرده و لذت ببرند! + +پس به راحتی می‌توانید شروع به کار روی پروژه های اپن سورس کنید، باگ های احتمالی آن‌ها را بیابید، پیشنهاداتی به منظور بهبود عملکرد پروژه بدهید، دوستان اپن سورسی دیگری از سراسر دنیا پیدا کنید، روی نرم‌افزار که دوست دارید کار کنید و در کل، از کاری که می‌کنید لذت ببرید! diff --git a/fa/thing_35/README.md b/fa/thing_35/README.md new file mode 100644 index 00000000..d171ba6b --- /dev/null +++ b/fa/thing_35/README.md @@ -0,0 +1,7 @@ +# قانون طلایی طراحی API + +به طور کلی، طراحی API کار دشواری است مخصوصاً اگر قصد طراحی برای سیستم‌های بزرگی را داشته باشیم؛ اگر شما قصد طراحی API را در سر می پرورانید که در آینده یی نه چندان دور چندین هزار کاربر از API شما استفاده خواهند کرد، حتماً می‌باید به این موضوع هم فکر کنید که تغییرات احتمالی در آینده چه اتفاقی برای کاربران رقم خواهد زد و اگر یک تغییر کوچک در API خود دادید، کاربران چگونه می‌باید با این تغییر کنار بیایند! + +علاوه بر این، توجه به این نکته که کاربران API مثلاً چگونه با Override کردن برخی متدهای کلاس‌های API شما، سرویس تان را تحت تأثیر قرار خواهند داد نیز حائز اهمیت است. یکی از استراتژی هایی که توسعه‌دهندگان از آن تبعیت می‌کنند، محدود کردن سطح دسترسی کاربران است؛ به طور مثال، در زبان جاوا بسیاری از متدها را می‌توان final کرد و در زبان سی‌شارپ، می‌توان از کیورد sealed استفاده کرد تا جلوی دستکاری سیستم توسط کاربران را گرفت اما این تمام ماجرا نیست. + +ما با نوشتن Unit Testها، تا حدودی می‌توانیم از صحت عملکرد API خود اطمینان حاصل کنیم اما این کافی نیست! قانون طلایی طراحی ای‌پی‌آی حاکی از آن است که «علاوه بر نوشتن یونیت تست برای ای‌پی‌آی، خود را جای کاربران ای‌پی‌آی گذاشته و اقدام به استفاده ی واقعی از ای‌پی‌آی کنید!» که در چنین شرایطی، خواهید دید که کاربران با چه مشکلاتی دست و پنجه نرم خواهند کرد، مشکلات احتمالی چیست، راه های در رو کدامند و ... diff --git a/fa/thing_36/README.md b/fa/thing_36/README.md new file mode 100644 index 00000000..ef3dc740 --- /dev/null +++ b/fa/thing_36/README.md @@ -0,0 +1,9 @@ +# کسی که چند سال است کدنویسی می‌کند، اصلاً علامهٔ دهر نیست! + +افرادی که چند سالی است در حوزه ی توسعه ی اپلیکیشن و برنامه نویسی کار می‌کنند و جزو حرفه یی های این حوزه محسوب می شوند، مسلماً حداقل یک بار با سؤال یا سؤالاتی از این دست رو به رو شده اند که «من فلان مشکل را در سورس کد خود دارم، می دونی مشکل از کجاست و چطور می‌شود آن را رفع کرد؟» + +کسانی که معمولاً از این دست سؤالات می‌پرسند، اطلاعات چندانی از ارور لاگ ها و یا شرایطی که منجر به ایجاد مشکل مربوطه می‌شوند در اختیار شما نمی‌گذارند؛ ایشان بر این باروند که یک توسعه‌دهنده ی حرفه یی علامه ی دهر است و پاسخ به هر سؤالی را می‌داند و بلد است که چگونه هر باگی را دیباگ کند! + +به طور کلی، چنین رویکردی را به کرات می‌توان در برنامه نویسان مبتدی مشاهده کرد؛ ایشان بر این باورند که منتور ایشان یا برنامه نویس ارشد تیم توسعه ی نرم‌افزار پاسخ به هر سؤالی را باید بداند بدون آن که جزئیاتی دقیق از مشکل مربوطه را در اختیارش قرار دهند. + +در دنیای برنامه نویسی، به کسانی که تجربه ی زیادی در کدنویسی دارند اصطلاحاً Guru گفته می‌شود اما همواره باید این نکته را به خاطر داشته باشیم که Guru ها هم همچون سایر افراد هستند با این تفاوت که به مسائل و مشکلات از زوایای مختلفی نگاه می‌کنند، تفکر الگوریتمیک دارند، کنجکاو هستند و زود دست از تلاش نمی کشند. لذا این دیدگاه که یک برنامه نویس باتجربه می بایست پاسخ به تمامی سوالات را بداند، دیدگاهی کاملا اشتباه است. diff --git a/fa/thing_37/README.md b/fa/thing_37/README.md new file mode 100644 index 00000000..63470543 --- /dev/null +++ b/fa/thing_37/README.md @@ -0,0 +1,17 @@ +# کار زیاد ضمانت موفقیت در برنامه‌نویسی نیست! + +به عنوان یک برنامه نویس، دیر یا زود متوجه خواهید شد که گرچه زیاد کار کردن و سخت کوشی شرط لازم برای موفقیت در این حوزه است، اما هرگز شرط کافی نبوده و صرفاً با کار زیاد نمی‌توان به موفقیت‌های چشمگیری در این زمینه دست یافت. + +به طور مثال، فرض کنیم که شما و تعدادی از همکارانتان روی پروژه یی در حال کار کردن هستید؛ ماندن زمان های طولانی در آفیس یا شرکت و کد زدن روی پروژه هرگز بدان معنا نیست که شما ارزش بیشتری در این پروژه می آفرینید. گاهی اوقات پیش می‌آید که حتی با کمتر کار کردن، شما می‌توانید ارزش بیشتری برای تیم نرم افزاری خود رقم بزنید. حال ممکن است بپرسید که چطور؟ + +برنامه نویسی و به طور کلی توسعه ی نرم‌افزار دربرگیرنده ی یادگیری مداوم است؛ هرچه شما بیشتر روی پروژه یی وقت می‌گذارید، بیشتر با جنبه‌های مختلف پروژه آشنا شده و بالتبع زوایای بیشتری از پروژه را درک کرده که در نهایت می‌توانند منجر به یافتن راه کارهای به مراتب بیشتر و بهینه‌تری گردند. + +برنامه نویسی حرفه یی همچون دوی سرعت نیست که شما موظف باشید یک مسیر مشخص را در سریع‌ترین زمان ممکن طی کرده تا به انتهای مسیر برسید. بسیاری از پروژه های برنامه نویسی همچون صخره نوردی است؛ به عبارت دیگر، هرگز نمی‌توان این‌گونه تصور کرد که یک مسیر از صخره ها را انتخاب کرده و با بیشترین سرعت ممکن از آن‌ها بالا رفت. پروژه های برنامه نویسی نیاز به تحلیل فرایندها -یا در صخره نوردی تحلیل مسیرهای مختلف و کم خطر- دارند و شما به عنوان یک برنامه نویس حرفه یی می بایست با سرعتی یکنواخت به مسیر خود ادامه داده و هر کجا که احساس کرده‌اید مسیر را اشتباه رفته اید،‌ بازگشته و مسیر به مراتب بهتری اتخاذ نمایید. + +علاوه بر این، یک برنامه نویس خوب می بایست همواره تشنه ی یادگیری اطلاعات عمومی در زمینه ی توسعه ی نرم‌افزار از یک سو و همچنین یادگیری تکنیک های برنامه نویسی با زبان مد نظر به صورت تخصصی از سوی دیگر باشد. در این راستا، نیاز به مطالعه ی کتب مختلف، شرکت در سمینار/وبینارهیا مربوطه، ارتباط با افراد حرفه یی این حوزه، امتحان کردن ابزارهای جدیدی که به بازار عرضه شده‌اند و … خواهید داشت. + +به عنوان یک برنامه نویس حرفه یی، همان‌طور که مثلاً پزشکان خود را آپدیت نگاه می‌دارند تا بتوانند جان بیماران خود را نجات دهند، نیاز دارید تا آپدیت باشید و همواره از آخرین دستاوردهای حوزه ی کاری خود مطلع بوده و آن‌ها را به خدمت گیرید. + +به جای این که در زمان استراحت خود -بعد از ظهرها، آخر هفته‌ها و در تعطیلات- کماکان روی پروژه یی که در دست دارید کد بزنید، این زمان گرانبها را به مطالعه در حوزه ی کاری خود اختصاص دهید و پس از مدت زمانی -مثلا ۶ ماه- تفاوت چشمگیری در توانمندی‌های خود مشاهده خواهید کرد. + + diff --git a/fa/thing_38/README.md b/fa/thing_38/README.md new file mode 100644 index 00000000..27ebc7e4 --- /dev/null +++ b/fa/thing_38/README.md @@ -0,0 +1,10 @@ +# چگونه به یک باگ نگاه کنیم؟ + +برخی توسعه دهندگان برچسب «باگ» روی مسائل خارج از عرف نرم افزاری می‌گذارند و برخی دیگر صرفاً به «مشکل» اکتفا می‌کنند؛ خواه این مسائل را باگ بنامییم خواه مشکل، آن‌ها وجود دارند و به راحتی می‌توانند موفقیت نرم‌افزار ما را تحت الشعاع قرار دهند و یکی از مهارت های اصلی هر توسعه‌دهنده ی حرفه یی، این می‌تواند باشد که چگونه باگ های یک نرم‌افزار را رصد کند و تمام تلاش خود را به کار گیرد تا آن‌ها را مرتفع سازد. + +برای رفع باگ ها، ما پیش از هر چیز به یک ‌Bug Report (باگ ریپورت) نیاز داریم تا بیش از پیش، با خصوصیات باگ احتمالی آشنا شده و دیگر اعضای تیم را نیز در جریان قرار دهیم؛ یک باگ ریپورت خوب از ویژگی‌های زیر برخوردار است: +- نحوه ی کار با نرم‌افزار به گونه یی که منجر به مشاهده ی باگ شود را ارائه می‌دهد؛ علاوه بر این، به ما می‌گوید که این باگ هر چند وقت یک بار پدید می‌آید. +- به نظر شما چه اتفاقی باید افتاده باشد که این باگ ایجاد شده؟ +- گزارشی کامل از اتفاقاتی که رخ داده‌اند به منظور درک بهتر ماهیت باگ و در صورت امکان، ارائه ی دلیل اصلی پدید آمدن باگ + +کمیت و کیفیت اطلاعاتی که ما از یک باگ پیدا می‌کنیم دارای ارتباطی مستقیم با فرایند Debugging (دیباگینگ یا رفع مشکل) است. به یاد داشته باشیم زمانی که با یک باگ در نرم‌افزار خود مواجه می‌شویم، تحت هیچ عنوان دست به انکار آن نزده و یا مشکل بوجود آمده را به گردن سایر اعضای تیم نیندازید! بلکه تا حد ممکن اطلاعات مرتبط در مورد باگ مربوطه کسب نمایید و در صدد رفع آن برآیید. diff --git a/fa/thing_39/README.md b/fa/thing_39/README.md new file mode 100644 index 00000000..956d0d24 --- /dev/null +++ b/fa/thing_39/README.md @@ -0,0 +1,7 @@ +# با حذف کدهای اضافی، سورس‌کد خود را بهبود بخشید + +آمریکایی ها شعاری دارند تحت عنوان Less Is More با این مضمون که «هرچه کمتر، بهتر!» و شاید بتوان گفت که این جمله خیلی کلیشه یی است و ممکن است در بسیاری مواقع کاربرد نداشته باشد، اما حداقل در کدنویسی کاربرد دارد به این شکل که با حذف کلاس‌ها، فانکشن ها و بلوک های کد اضافی از سورس کد خود، در نهایت سورس کد به مراتب بهتر و تمیزتری در اختیار خواهید داشت. + +گاهی اوقات در حین کدنویسی فکر می‌کنیم که یکسری کارها به بهبود نرم‌افزار ما منجر خواهند شد اما در نهایت کاشف به عمل می‌آید که در حین اجرا، باعث کاهش راندمان نرم‌افزار می‌شوند و تنها در صورت حذف آن‌ها است که بهبودی حاصل می‌شود. در کدنویسی همواره می بایست این نکته را به خاطر داشته باشیم که باید کدی بنویسیم که «ارزشی برای نرم‌افزار ما بیاورد نه این که صرفاً از نوشتن آن لذت ببریم». + +گاهی اوقات هم در تحلیل نرم‌افزار و مراحل اولیه ی کدنویسی، فکر می‌کنیم که یک قابلیت ممکن است در آینده به کارمان آید، لذا با خود فکر می‌کنیم که زمان زیادی از ما نمی‌برد و آن را در سورس کد خود می گنجانیم اما همواره به یاد داشته باشیم که اگر به قابلیتی در حال حاضر نیاز نداریم، نیاز به نوشتن آن نیست! diff --git a/fa/thing_40/README.md b/fa/thing_40/README.md new file mode 100644 index 00000000..bba45ec0 --- /dev/null +++ b/fa/thing_40/README.md @@ -0,0 +1,11 @@ +# برنامه‌هایی که می‌نویسید را کاربرپسند کنید + +اگر به فولدر Downloads سیستم خود نگاهی بیندازید، و ببینید که پر است از فایل‌های zip و exe که شاید حتی یک بار هم آن‌ها را استفاده نکرده باشید! شما جزو آن دسته از کاربرانی هستید که علاقمند به جمع آوری هرگونه نرم افزاری -از نرم افزاری های گرافیکی گرفته تا هک و غیره- هستید. + +در نقطه ی مقابل این دست کاربران، کاربرانی هستند که خیلی وسواسی هستند و دوست دارند که سیستم خود را تا حد ممکن تمیز نگاه دارند و صرفاً نرم افزارهایی را روی آن نصب کنند که به آن ها نیاز دارند. این دست کاربران خیلی برایشان مهم است نرم افزاری که Install می‌کنند، قابلیت Uninstall شدن داشته باشد؛ لذا اگر برنامه یی نوشته‌اید که نمی‌توان را آن را حذف نمود و یا اگر می‌شود، به سختی این کار صورت می‌گیرد، به طور حتم نظر مساعد این دست از کاربران را از دست خواهید داد. + +اگر برنامه یی که نوشته‌اید که Graphical User Interface (یا به اختصار GUI به معنی رابط کاربری گرافیکی) دارد، تا حد ممکن مراحل انجام کار را ساده نگاه دارید و همچون نرم افزارهای شرکت ادوبی، از منوهای تو در تو و گاها گیج‌کننده استفاده نکنید. + +اگر یک لایبرری نوشته اید، بهتر است که در سایت مربوطه یا صفحه ی گیت هاب لایبرری خود، راهنمایی خلاصه و مفید از نحوه ی کارکرد لایبرری خود در نظر بگیرید. نیاز به توضیح نیست که لایبرری های رغیب همیشه ادعا می‌کنند به بهینه‌تر هستند، راحت‌تر هستند، سبک‌تر هستند و بسیار مزیت دیگر؛ لذا اگر به هر دلیلی در چند دقیقه ی اول نتوانید مشتری بالقوه ی خود را به مشتری بالفعل درآورید، این رقبای شما هستند که برنده ی بازی خواهند بود. + +به طور کلی، شما به عنوان یک توسعه‌دهنده ی نرم‌افزار -خواه یک پروژه ی اپن سورس برای تفنن بنویسید و خواه پروژه ی بزرگ یک مشتری را کدنویسی کنید- می بایست این نکته را مد نظر داشته باشید که کاربران نرم افزاری بسیار بی‌وفا هستند و به محض آن که نرم افزاری بیابند که از نرم‌افزار شما ارزان‌تر، کاربرپسندتر، بهینه‌تر و در کل اثربخش تر باشد، به سمت رقبای شما خواهند رفت؛ لذا وقتی کدنویسی می‌کنید، به نیازهای پایه یی کاربران -که اغلب اوقات آنقدر بدیهی هستند که از قلم می‌افتند- تمام توجه خود را به کار گیرید. diff --git a/fa/thing_41/README.md b/fa/thing_41/README.md new file mode 100644 index 00000000..2fffa637 --- /dev/null +++ b/fa/thing_41/README.md @@ -0,0 +1,13 @@ +# فرایندهای برون برنامه‌ای، زمان پاسخگویی نرم‌افزار را تحت‌الشعاع خود قرار می‌دهند + +یکی از چیزهایی که در ارزیابی کیفیت یک نرم‌افزار مورد توجه قرار می‌گیرد، Response Time (ریسپانس تایم یا زمان پاسخگویی) نرم‌افزار است. این نرم‌افزار می‌تواند یک وب سایت آنلاین باشد و یا یک نرم‌افزار حسابداری که روی سیستم خود نصب می‌کنیم؛ هرچه که باشد، اگر نوع کاربری نرم‌افزار به گونه یی باشد که کاربران نیاز به تعامل مکرر با سیستم داشته باشد، ریسپانس تایم نقش تعیین کننده در تجربه ی کاربری نرم‌افزار ایفا می‌کند به طوری که اگر کاربری کاری را انجام دهد و چند ثانیه منتظر بماند تا سیستم پاسخ وی را بدهد، این حس به کاربر نرم افزارمان دست که می‌دهد که وقت اش تلف می‌شود. + +ریسپانس تایم یکی از چیزهایی است که در فرایند تحلیل نرم افزار، طراحی پایگاه داده و همچنین الگوریتم های به کار گرفته شده در سیستم می بایست مد نظر قرار داده شود؛ علاوه بر این موارد، نکته ی دیگری هم وجود دارد که در زیاد شدن ریسپانس تایم دخیل است و آن هم چیزی نیست جز برقراری ارتباط با سایر نرم‌افزارها همچون وب سرویس ها و … + +فرض کنیم که نرم افزاری نوشته‌ایم که قیمت روز خودرو را از یک API گرفته و در دسترس ما قرار می‌دهد؛ زمانی که کاربر مثلاً روی دکمه ی خودروهای داخلی کلیک می‌کنید، یک ریکوئست برای API مد نظر ارسال می‌شود تا قیمت خودروها را از دیتابیس سرویس مربوطه گرفته و در قالب یک ریسپانس -که معمولاً در فرمت جیسون است- در اختیار ما قرار می‌دهد. حال اگر این API هرگونه تاخیری در گرفتن دیتای مد نظر داشته باشد، این تأخیر به حساب نرم‌افزار ما نوشته شده و ریسپانس تایم آن را افزایش می‌دهد که در نهایت منجر به ایجاد یک تجربه ی کاربری نامطلوب برای کاربرانمان می‌شود. + +برای رفع این مشکل، راه کارهای متعددی را می‌توان اتخاد نمود؛ به عنوان مثال، می‌توان تعامل نرم‌افزار خود با مثلاً وب سرویس مربوطه را به حداقل رساند و در هر بار ریکوئست فرستادن، کمترین دیتای ممکن را درخواست کرد. + +راه‌کار دیگری که می‌توان به کار برد این است که داده‌هایی که قبلاً به دست آمده را Cache کرد، بنابراین کاربران جدیدی که ریکوئست مشابهی ارسال می‌کنند، پاسخ خود را خیلی سریع از روی کش سیستم دریافت می‌کنند. + +به طور کلی، ریسپانس تایم نقش تعیین کننده یی در موفقیت نرم افزارهایی که می نویسیم دارد و باید تمام تلاش خود را به کار بندیم تا آن را پایین نگاه داریم. diff --git a/fa/thing_42/README.md b/fa/thing_42/README.md new file mode 100644 index 00000000..3d761679 --- /dev/null +++ b/fa/thing_42/README.md @@ -0,0 +1,13 @@ +# بیلد (Build) اصولی ارائه کنید + +در فرایند کدنویسی گاهی اوقات برایمان پیش می‌آید که با لیست بلند بالایی از ارورها در حین اجرای نرم‌افزار مواجه می‌شویم و این در حالی است که با خود می‌گوییم «ان شاء الله اگر فرصتی شد، همه ی ارورها را بعداً رفع خواهم کرد!» + +زمانی که ما یک پروژه ی جدید را از پایه شروع به کدنویسی می‌کنیم، نه مشکلی وجود دارد و نه اروری اما همین که سورس کد ما به مرور زمان حجیم و حجیم تر می‌شود، احتمال این که ارورها، هشدارها و اکسپشن ها زیاد شوند هم بالا می‌رود و این در صورتی که اگر این ارورها را به‌ موقع رفع نکنیم، در آینده رفع کرد یک هشدار کوچک می‌تواند به دردسری بزرگ مبدل گردد! + +یکی از استراتژی های خوب در حین کدنویسی، به کارگیری سیاست Zero-tolerance Policy است؛ در‌ واقع این سیاست حاکی از آن است که IDE و محیط توسعه ی نرم افزار خود را به گونه یی تنظیم کنیم که هرگونه هشدار، خطا و اروری را به ما گوشزد کند حتی اگر خیلی کوچک و در ظاهر بی اهمیت باشند. + +برای درک بهتر این موضوع، مثالی از دنیای واقعی می‌زنیم؛ واژه ی «درد» معانی و تعاریف مختلفی می‌تواند داشته باشد. به طور مثال، اگر بخواهیم درد را تعریف کنیم، می‌توانیم از آن به عنوان یک «مکانیسم اطلاع رسانی» یاد کنیم. اگر درد وجود نداشت، ما به سادگی گرمای بیش از حد را نمی توانستیم حس کنیم و بالتبع از آن دوری کنیم و ممکن بود صدمات جبران ناپذیری به بدن خود وارد کنیم. + +در کدنویسی هم قضیه دقیقاً به همین شکل است؛ وجود ارورها، هشدارها و اکسپشن ها اصلاً چیز بدی نیستند چرا که همین هشدارها هستند که ما را از وجود باگی در سورس کد خود مطلع می‌کنند و باید قدر آن‌ها را دانست. در چنین شرایطی است که وقتی ما نرم افزار خود را Build می کنیم، نسخه ی بیلد شده ی سورس کد ما اصولی است و سایر توسعه دهندگانی که با آن‌ها روی یک پروژه کار می‌کنیم تا حد ممکن کمتر سردرگم خواهند شد. + +نکته به طور کلی، در شاخه ی برنامه نویسی و توسعه ی نرم‌افزار، Build به فرایندی گفته می‌شود که در آن سورس کد به برنامه یی قابل اجرا و قابل استفاده مبدل می‌گردد که معمولاً با یک شناسه -مثلا ۱۷- شناخته می‌شود که قبل از انتشار نهایی نرم‌افزار و در فرایند تست نرم افزار ایجاد می‌گردد. یکی از فرایندهای مهم در بیلد کردن، کامپایل کردن سورس کد است که در این فرایند سورس کد نرم‌افزار به کدهای قابل اجرا توسط ماشین تبدیل می‌شوند. diff --git a/fa/thing_43/README.md b/fa/thing_43/README.md new file mode 100644 index 00000000..16a02c2d --- /dev/null +++ b/fa/thing_43/README.md @@ -0,0 +1,20 @@ +# استفادهٔ بهینه از ابزارهای کامندلاینی + +امروزه بسیاری از ابزارهای توسعه ی نرم‌افزار در IDE ها به صورت پیکج های از پیش نصب شده در اختیار توسعه‌دهندگان قرار می‌گیرند و همین مسئله منجر به محبوبیت بیش از پیش IDE در مقایسه با ادیتورهای کد در میان توسعه‌دهندگان می‌شود چرا که نه تنها کدنویسی با این محیط‌های توسعه راحت تر است، بلکه برنامه‌نویس دیگر نیازی نخواهد داشت تا به یک سری جزئیات همچون فرایند کامپایل کردن و … فکر کند. + +به خاطر داشته باشید IDE مخفف واژگان Integrated Development Environment به معنی «محیط توسعه ی یکپارچه ی نرم‌افزار» است که از مهم‌ترین آن‌ها می‌توان به ویژوال استودیو، اکلیپس و نت بینز اشاره کرد. +سهولت در استفاده از IDE ها گرچه به عنوان یکی از نقاط قوت این دست نرم‌افزارها محسوب می‌گردد، اما IDE ها عاری از هر گونه عیبی هم نیستند! زمانی که ما می‌گوییم استفاده از یک نرم‌افزار بسیار سهل و آسان است، این بدان معنا است که نرم‌افزار بسیاری از کارها را به صورت خودکار انجام می‌دهد؛ به عبارت دیگر، بسیاری از تصمیماتی که بر عهده ی توسعه‌دهنده هستند را خود نرم‌افزار می‌گیرد و به همین دلیل هم هست که توسعه‌دهندگان ی که صد در صد وابسته به IDE انتخابی خود هستند -خواه ویژوال استودیوی مایکروسافت یا گزینه‌های اپن‌سورسی همچون اکلیپس- در یک سری از مواقع اصلاً متوجه نمی‌شوند که سورس‌کد ایشان چگونه بیلد می‌شود و ابزارهای مختلف دقیقاً چه کاری انجام می‌دهند (به طور مثال، شما یک دکمه را در اندروید استودیو می‌زنید و خروجی apk حاضر و آماده در اختیار شما قرار می‌گیرد.) + +در نقطه ی مقابل توسعه‌دهندگان ی که کاملاً وابسته به IDE ها هستند، برنامه‌نویسانی قرار دارند که از ابزارهای کامند لاینی استفاده می‌کنند؛ این دست برنامه‌نویسان زمانی که یک برنامه را بیلد می‌کنند -البته با استفاده از ابزارهای کامند لاین- دقیقاً می‌توانند متوجه شوند که پشت پرده چه اتفاقاتی رخ می‌دهد. + +برای شروع کار با ابزارهای بیلد کردن کامند لاین، می‌توان از نمونه‌های اپن‌سورسی همچون GCC شروع کرد. زمانی که شما شخصاً اقدام به کامپایل کردن، اسمبل کردن و لینک کردن سورس‌کد خود می‌کنید و در نهایت یک بیلد نهایی به دست می آورید، کاملاً با فرایند های توسعه ی نرم‌افزار آشنا خواهید شد و از آن پس، یک IDE برایتان صرفاً نرم‌افزاری گرافیکی است که یک سری ابزارهای کامند لاینی را در خود جای داده است. + +علاوه بر این که پس از استفاده از ابزارهای کامند لاین برای بیلد کردن سورس‌کد خود به ماهیت فرایندها پی می برید، یک سری کارهای دیگری نیز می‌توانید انجام دهید که در مقایسه با IDE ها از سهولت و اثربخشی بیشتری برخوردارند؛ برای مثال، ابزارهای جستجو و جایگزین کردنی همچون grep و sed گاهی اوقات از گزینه‌هایی که در نرم‌افزارهای گرافیکی در اختیار توسعه‌دهندگان قرار می‌گیرد اثربخش تر هستند. + +در ضمن، ابزارهای کامند لاینی امکان اسکریپت‌نویسی -خودکار کردن یک سری کارهای تکراری- را نیز به شما می‌دهند تا مثلاً در بازه های زمانی مشخص، نسخه‌های مختلفی از نرم‌افزار بیلد شده و ذخیره گردد. + +حال سؤالی که اینجا مطرح می‌شود این است که مگر به غیر از این است که IDE ها برای راحتی کار برنامه‌نویسان و افزایش بازدهی ایشان طراحی و ساخته شده‌اند؟ اگر پاسخ به این سؤال آری است، پس چرا باید برنامه‌نویسان را تشویق به استفاده از ابزارهای کامند لاینی کنیم؟ + +پاسخ به سؤال فوق «آری» است اما نکته یی که در این آموزش یاد آور شدیم هرگز بدان معنا نیست که شما از امروز باید IDE خود را کنار بگذارید و کلاً به صورت کامند لاینی فرایند توسعه ی نرم‌افزار خود را دنبال کنید بلکه منظور این است که آشنایی با ابزارهای کامند لاینی، دید به مراتب بازتری به شما به عنوان یک برنامه‌نویس می‌دهند و زمانی که کاری را در نرم‌افزارهای گرافیکی انجام می‌دهید که صرفا با چند کلیک به هدف خود می‌رسید، متوجه می‌شوید که پشت پرده چه اتفاقاتی رخ می‌دهد و بهترین رویکرد برای درک این موضوع هم استفاده از ابزارهای کامند لاین است. + +پس از آن که شما شروع به استفاده از ابزارهای کامند لاین کردید، هر وقت که با IDE خود کار کنید کاملاً متوجه می‌شوید که هر کلیک چه کاری انجام می‌دهد و با دید بازتری می‌توانید فرایند بیلد نرم‌افزار را کنترل کنید. نکته ی آخر هم این که وقتی به کامند لاین تسلط پیدا کنید، به احتمال قریب به یقین دیگر به سمت نرم‌افزارهای گرافیکی نخواهید رفت! diff --git a/fa/thing_44/README.md b/fa/thing_44/README.md new file mode 100644 index 00000000..ab4657d1 --- /dev/null +++ b/fa/thing_44/README.md @@ -0,0 +1,17 @@ +# یادگیری هم‌زمان بیش از یک زبان برنامه‌نویسی + +فلسفه ی برنامه نویسی حاکی از آن است که «مهارت برنامه نویسی مستقیماً وابسته به پارادایم های مختلف برنامه نویسی که یک برنامه نویس برای کدنویسی مورد استفاده قرار می‌دهد و با آن‌ها احساس راحتی می‌کند است نه دانش اندکی که وی ممکن است از یک زبان برنامه نویسی دیگر داشته باشد!» + +هر برنامه نویسی، با یک زبان برنامه نویسی پا به دنیای برنامه نویسی می‌گذارد و جالب است بدانیم که آن زبان، تأثیر بسزایی روی رویکرد فرد در مورد توسعه ی نرم‌افزار می‌گذارد؛ اصلاً مهم نیست که فرد برنامه نویس چند سال است که با زبان انتخابی اش کد می زند، بلکه مادامی که فرد در حال کار با آن زبان است، می‌توان گفت که فقط و فقط آن زبان را بلد است. جالب است بدانیم که برنامه نویسان اصطلاحاً تک-زبانه دایره ی فکر کردن خود را محدود به قابلیت‌های آن زبان می‌کنند اما برنامه نویسی که اقدام به یادگیری زبان دوم می‌کند، ذهنیت وی در مورد توسعه ی نرم‌افزار به چالش کشیده خواهد شد مخصوصاً اگر زبان دوم از لحاظ ساختاری دارای تفاوت‌های عمیقی نسبت به زبان اول باشد. + +برای روشن‌تر شدن این مسأله مثالی می‌زنیم؛ زبان‌های سی، پاسکال و فورترن دارای مدل های ساختاری تقریباً یکسانی هستند به طوری که اگر کسی زبان سی را بلد باشد و زبان دومش را فوترن انتخاب کند، به طور حتم با چالش های خیلی زیادی مواجه نخواهد شد اما مهاجرت از زبان‌هایی همچون سی یا فوترن به زبان دیگری همچون سی پلاس پلاس یا آدا، برنامه نویس را با موقعیت های بسیار متفاوتی در زمینه ی نحوه عملکرد زبان برنامه نویسی مواجه خواهد ساخت و بالتبع مهاجرت از سی پلاس پلاس به هسکل هم چالشی مضاعف خواهد بود. + +در‌ واقع پارادایم های برنامه نویسی مختلف من جمله Procedural یا رویه یی، Object-oriented یا شیء گرا، Functional یا تابعی و … وجود دارند که از لحاظ ساختاری دارای تفاوت‌هایی با یکدیگر هستند و در صورت مهاجرت در میان این پارادایم ها، می بایست منتظر چالش های فراوانی هم باشیم! + +نکته یی که در اینجا می بایست مد نظر داشته باشیم این است که این چالش ها هرگز بد نیستند بلکه اتفاقاً باید به استقبال آن‌ها برویم چرا که پارادایم های مختلف برنامه نویسی، نگاه ما به توسعه نرم‌افزار را دگرگون می‌کنند چرا که مسأله یی خاص در یک زبان برنامه نویسی ممکن است به شیوه یی نسبتاً دشوار حل شود در صورتی که با توجه به پارادایم های اعمال شده در زبانی دیگر، پاسخ به آن مسأله با دردسرهای به مراتب کمتری در دسترس مان قرار گیرد و در چنین شرایطی است که ما می‌توانیم به ماهیت واقعی هر دو زبان پی ببریم. + +به طور کلی، برنامه نویسان حرفه یی از یادگیری زبان‌های جدید اصلاً واهمه یی به خود راه نمی‌دهند و علاقمند به یادگیری زبان‌های جدید هستند؛ حتی اگر در کدنویسی روزمره ی خود، صرفاً از یک زبان برنامه نویسی استفاده کنند باز هم مشتاق به یادگیری زبان‌های دیگر هستند چرا که می‌دانند سایر زبان‌ها -مخصوصا اگر از پارادایم متفاوتی نسبت به آنچه زبان فعلی شان ارائه می‌کند- نگرش متفاوتی برای حل مسأله در اختیار ایشان قرار می‌دهند. + +مدیران شرکت های نرم‌افزار می بایست بخشی از تایم کاری تیم توسعه ی نرم‌افزار خود را به یادگیری زبان‌های جدید اختصاص دهند حتی اگر قرار نباشد هیچ پروژه یی با زبان‌های جدید نوشته شود چرا که اتخاذ چنین رویکردی منجر به بازتر شدن دید برنامه نویسان شرکت نسبت به همان زبانی که به صورت روزمره مورد استفاده قرار می‌دهند می‌شود. + +در پایان هم می بایست این نکته را یادآور شد که یادگیری یک زبان صرفاً به یادگیری سینتکس اش و نوشتن یک برنامه ی Hello World خلاصه نمی‌شود بلکه نیاز به ماه ها کار مستمر و نوشتن پروژه های مختلف با آن زبان و درگیر شدن با بخش‌های مختلف زبان دارد. diff --git a/fa/thing_45/README.md b/fa/thing_45/README.md new file mode 100644 index 00000000..fe8f119a --- /dev/null +++ b/fa/thing_45/README.md @@ -0,0 +1,22 @@ +# محیط کد نویسی (IDE) خود را مثل موم در دست بگیرید + +در دهه ی ۸۰ میلادی، برنامه نویسان محدود بودند به ویرایشگرهای کد ساده یی که اگر خیلی خوش شانس بودند، ویرایشگر کد ایشان به Syntax Highlighting مجهز بود! در آن دوران اگر کسی می‌خواست برنامه ی خود را دیباگ کند، می بایست ابزارهای مجزایی نصب کند و اصلاً این‌ گونه نبود که با یک کلیک، فرایند دیباگ آغاز شود بلکه نیاز به انجام فرایندهای مختلفی بود. + +در دهه ی ۹۰، شرکت های نرم‌افزار متوجه خلائی در بازار برنامه نویسی شدند و آن هم چیزی نبود جز برنامه‌هایی کاربردی که می توانستند زندگی برنامه نویسان را ساده‌تر و در عین حال لذت بخش تر سازند و نتیجه این که IDE های مختلف به بازار عرضه شدند که قابلیت‌های جدید همچون کامپایلر، دیباگر و … را به نرم افزارهای ویرایشگر کد معمولی افزوده بودند. + +در همین دوران بود که برنامه‌های کامپیوتری به «منو» های مختلف مجهز شدند و با‌ عرضه ی دیوایس «ماوس» به بازار، برنامه نویسان دیگر مجبور نبودند تا برای انجام کاری خاص، از ترکیب کلیدهای مختلف استفاده کنند بلکه به سادگی با نشانگر ماوس خود، می توانستند روی یکی از منوهای نرم‌افزار کلیک کرده و پشت پرده، کامند خاصی اجرا گردد. + +پس از سال ۲۰۰۰، محیط های توسعه ی یکپارچه ی نرم‌افزار آنقدر رایج شدند که بسیاری از شرکت های نرم افزاری این IDE ها را به رایگان در اختیار برنامه نویسان قرار می‌دادند تا از این طریق شناخته تر شده و بتوانند سایر سرویس ها و محصولات خود را به فروش برسانند. این نرم‌افزارها از آن زمان تاکنون، روز به روز به ابزارهای بهتر و بیشتری مجهز شده اند به طوری که امروزه شاهد IDE هایی هستیم که قابلیت‌های منحصر به فردی همچون Automated Refactoring و یا Extract Method دارند. + +نکته کاری که Extract Method انجام می‌دهد این است که بخشی از کد را انتخاب کرده، سپس نرم‌افزار آن بلوک کد را به یک متد با نامی خاص برایمان تبدیل می‌کند. +یکی دیگر از قابلیت‌های محیط های توسعه ی یکپارچه ی نرم‌افزار امروزی -IDE- این است که می‌توان در تنظیمات نرم‌افزار یکسری «قوانین» وضع کرد و از آن پس، هر موقع که آن قانون را نقض کنیم، یک هشدار در معرض دیدمان قرار خواهد گرفت. به طور مثال، می خواهیم در زبان پی اچ پی قانونی را نظر بگیریم که هر پراپرتی که در بدنه ی کلاس خود تعریف می‌کنیم، protected باشد؛ در چنین شرایطی، هر موقعی که فراموش کنیم کلیدواژه ی protected را استفاده کنیم، نرم‌افزار به ما هشدار خواهد داد. + +تفاوتی که نرم افزارهایی همچون vi که در سیستم عامل های مبتنی بری یونیکس همچون گنو/لینوکس در دسترس کاربران قرار دارد با IDE های مدرن این است که استفاده از نرم افزاری همچون vi نیاز به مطالعه ی زیادی صرفاً برای یادگیری کار کردن با این نرم‌افزار است اما محیط گرافیکی بسیاری از IDE های مدرن به گونه یی طراحی شده است که برنامه نویس طی چند ساعت می‌تواند کار با آن را یاد بگیرد اما در طول زمان، بسیاری از برنامه نویسان به همان کارهای ابتدایی که یاد می‌گیرند با نرم‌افزار مد نظر خود انجام دهند اکتفا کرده و خیلی علاقه یی به کشف زیر و بم IDE از خود نشان نمی‌دهند! + +برای روشن‌تر شدن این مسأله مثالی می‌زنیم. امروزه هر کاری که قبلاً از طریق کامند می‌شد انجام داد را می‌توان از طریق ماوس و منوهای تعبیه شده در نرم‌افزار انجام داد و برخی برنامه نویسان در طول زمان به استفاده از ماوس عادت می‌کنند اما غافل از این که برداشتن دست خود از روی کیبورد و استفاده از ماوس، زمان ایشان را هدر می‌دهد؛ برای کلیه ی کارهایی که از طریق ماوس می‌توان انجام داد، همچنین می‌توان «کلیدهای میانبر» نیز تعریف کرد به طوری که مثلاً برای باز کردن یک پنجره ی جدید، بستن پنجره، تغییر نام و … می‌توان بدون آن که دست خود را از روی کیبورد برداریم، کار مد نظر را انجام دهیم. + +اگر بخواهیم چکیده یی از این آموزش به دست آوریم، بایستی بگوییم که در توسعه ی نرم‌افزار زمان و مهم‌تر از آن صرفه جویی در زمان نقش بسیار تعیین کننده یی در موفقیت پروژه دارد و یکی از چیزهایی که می‌تواند به ما به عنوان یک برنامه نویس کمک کند، صرفه جویی در زمان کدنویسی با مسلط شدن به IDE مد نظر خود است؛ + +سعی کنیم به جای آن که بیشتر از ماوس استفاده کنیم، از کلیدهای میانبر از پیش تعیین شده در IDE استفاده کرده و یا خود کلیدهای میانبری بسته به نیازمان تعریف کنیم تا به جای آن که زمانی را صرف بلند کردن دست خود از روی کیبورد، بردن به سمت ماوس، حرکت دادن آن، کلیک روی یک منو و باز شدن پنجره ی مد نظر کنیم، به سادگی در همان حین که کدنویسی می کنیم، یکی دو کلید میانبر را هم‌زمان فشرده و کامند مد نظرمان اجرا گردد. + +شاید در ابتدای راه استفاده ی صرف از کلیدهای میانبر کمی سخت باشد و به خاطر سپردن آن‌ها کاری دشوار، اما در طول زمان کدنویسی برایمان به مراتب لذت بخش تر خواهد شد. diff --git a/fa/thing_46/README.md b/fa/thing_46/README.md new file mode 100644 index 00000000..bd75537a --- /dev/null +++ b/fa/thing_46/README.md @@ -0,0 +1,7 @@ +# ا محدودیت‌های خود دست و پنجه نرم کنید + +همواره به خاطر داشته باشید که منابع شما -شامل زمان و بودجه- محدود هستند؛ برای انجام پروژه های نرم افزاری یک زمان و پول کاملاً مشخصی در اختیار شما قرار می‌گیرد و این در حالی است که در این زمان محدود و بودجه ی کاملاً مشخص، علاوه بر تکمیل پروژه، شما می بایست دانش خود را به روز نگاه دارید، مهارت های جدید یاد بگیرید، با زبان‌های برنامه نویسی جدید آشنا شوید و … + +علاوه بر این، در حین پیاده‌سازی پروژه های نرم افزاری همواره بایستی به این نکته توجه داشته باشیم که برای به دست آوردن بیشترین میزان Performance (پرفورمنس یا عملکرد)، می بایست دید نسبتاً عمیقی از سخت افزاری که در اختیار ما قرار گرفته شامل سی پی یو، حافظه ی رم، زیرساخت های شبکه، هارد دیسک و … داشته باشیم به علاوه این که باید تمام تلاش خود را به کار گیریم تا الگوریتم هایی که می نویسیم را با توجه به این محدودیت‌ها، پیاده‌سازی کنیم تا بهترین نتیجه را بگیریم. + +به عبارت دیگر، به منظور ایجاد یک پرفومنس بهینه، بایستی یک «سازگاری و آشتی» مابین مفاهیم انتزاعی همچون الگوریتم ها و سخت افزاری که در اختیار ما قرار گرفته است ایجاد کنیم و صرفاً در این صورت است که می‌توانیم ادعا کنیم یک نرم‌افزار بهینه تولید کرده ایم. diff --git a/fa/thing_47/README.md b/fa/thing_47/README.md new file mode 100644 index 00000000..4939c5be --- /dev/null +++ b/fa/thing_47/README.md @@ -0,0 +1,10 @@ +# همواره بدانید چه چیزی را قرار است کامیت کنید + +به نوعی می‌توان برنامه نویسان را به ۲ گروه مختلف تقسیم‌بندی کرد: گروهی که وقتی از ایشان می‌پرسید که مشغول به چه کاری هستند، به وضوح می‌توانند بگویند که مثلاً «در حال کار کردن روی کلاس مرتبط با یوزر هستم» و گروهی که پاسخی همچون «در تلاش برای بهبود روند سرویس یوزرها ام» که به نظر می‌رسد برنامه نویسی که پاسخ اول را داده است، دقیقاً می‌داند در حال انجام دادن چه کاری است اما در این در حالی است که برنامه نویس دوم بیشتر یک دید کلی نسبت به پروژه دارا است! + +در همین راستا اگر از برنامه نویسی که پاسخ اول را داده است بپرسیم که چه چیزی را در نهایت کامیت خواهی کرد، به سادگی قادر خواهد بود تا نام تک تک فایل‌هایی که روی آن‌ها کار کرده و قرار است آن‌ها را کامیت کند ببرد اما برنامه نویسانی که به گروه دوم تعلق دارند، نه تنها نمی‌دانند که کارشان دقیقاً چه زمانی تمام خواهد شد، بلکه حتی نمی‌دانند که آیا قصد دارند فایل‌های قبلی را ریفکتور کنند یا مجبور می‌شوند که چند فایل جدید هم به پروژه بیافزایند. + +نکته به طور کلی، در سیستم‌های کنترل نسخه همچون Git، منظور از اصطلاح «Commit» ذخیره سازی تغییرات صورت گرفته روی سورس کد به صورت لوکال و روی سیستم خود برنامه نویس است و در صورتی که این تغییرات مورد تأیید باشند، در نهایت می‌تواند آن‌ها را اصطلاحاً Push کند تا سایر برنامه نویسان تیم هم بتوانند تغییرات صورت گرفته را در اختیار داشته باشند. +برنامه نویسی که پاسخی مشابه پاسخ اول را در اختیار ما می‌دهد، دقیقاً می‌داند که قرار است چه کاری انجام دهد و اصطلاحاً «فوکوس» روی پروژه دارد؛ کارهایی که می بایست روی پروژه انجام شوند را تقسیم‌بندی کرده، هر بخش را در بازه ی زمانی مشخصی انجام داده و در نهایت می‌داند که کدنویسی اش منجر به بهبود کدام بخش از پروژه شده است. اما برنامه نویسانی که پاسخی مشابه پاسخ دوم ارائه می‌دهند نمی‌توانند دقیقاً بگویند که مشغول به چه کاری هستند چرا که در آن واحد می‌خواهند یک بهبود کلی روی سیستم اعمال کنند که چنین بهبودی ممکن است نیاز به ریفکتورینگ بخش قابل توجهی از سورس کد داشته باشد. + +برنامه نویسان گروه اول همواره این شانس را دارند که اگر بخواهند به گذشته بازگردند، این کار را به سادگی با چند بار Ctrl +Z انجام دهند اما این قضیه در مورد برنامه نویسان گروه دوم اصلاً صدق نمی‌کند! پس به خاطر داشته باشیم که در انجام پروژه های نرم افزاری، همواره تسک ها را به بخش های کوچک و قابل کنترلی تقسیم بندی کرده، برای هر کدام از آن ها یک Deadline (ددلاین یا ضرب الاجل) در نظر بگیریم و در آن واحد فقط و فقط روی یکی از آن ها کار کرده و به محض تکمیل یک تسک، با خیال راحت سراغ تسک بعدی برویم. diff --git a/fa/thing_48/README.md b/fa/thing_48/README.md new file mode 100644 index 00000000..07e70605 --- /dev/null +++ b/fa/thing_48/README.md @@ -0,0 +1,20 @@ +# آشنایی با نحوهٔ به‌کارگیری دیتابیس‌های رابطه‌ای + +درصورتی‌که دست به توسعهٔ اپلیکیشنی زده‌اید که قرار است حجم قابل‌توجهی از دیتاهای مرتبط با یکدیگر را جمع‌آوری کند، بدون شک نیاز به دیتابیسی از نوع Relational (رابطه‌ای) خواهید داشت. پیش از این، سیستم‌های مدیریت دیتابیس‌های رابطه‌ای یا اصطلاحاً RDBMS (که مخفف واژگان Relational DataBase Management System است) برای دولوپرها هزینه‌بر بودند و از سوی دیگر نیز استفاده از آن‌ها به سادگی آنچه امروزه می‌بینیم نبود. + +اما خوشبختانه درحال‌حاضر RDBMSهایی اپن‌سورس و رایگان به بازار عرضه شده‌اند که از جملهٔ مهم‌ترین آن‌ها می‌توان به MySQL و PostgreSQL اشاره کرد؛ خبر بهتر این‌که دیتابیس‌های به‌اصطلاح Embedded را به‌سادگی استفاده از یک لایبرری در داخل اپلیکیشن‌های مختلف و تقریباً بدون نیاز به هرگونه ستاپ یا پیکربندی مورد استفاده قرار داد که از جملهٔ مهم‌ترین آن‌ها می‌توان به SQLite و HSQLDB اشاره کرد. + +درصورتی‌که دیتای اپلیکیشن‌ شما از توان پردازش میزان حافظهٔ RAM سرورتان بیشتر است، سیستم‌های RDBMS این امکان را در اختیار دلوپرها قرار داده‌اند تا با Index (ایندکس یا اندیس) کردن جداول، به‌سادگی بر این مشکل فائق آیند. + +مسلماً کار با سیستم‌های RDBMS نیازمند آشنایی با زبان SQL است؛ جالب است بدانید سینتکس زبان SQL بسیار قابل‌فهم بوده و پس از یادگیری این زبان پس از کمی تکرار و تمرین، به‌سادگی قادر خواهید بود دست به عملیات CRUD بزنید (منظور از اصطلاح CRUD،‌ انجام به‌اصطلاح Update، Read، Create و Delete به‌ترتیب به‌معنی ایجاد، فراخوانی، به‌روزرسانی و حذف است). + +نکته SQL که به‌صورت «اس‌کیو‌ال» تلفظ می‌شود، مخفف واژگان Structured Query Language است که به‌منزلهٔ زبان استانداری برای ارتباط با دیتابیس‌های مختلف مورد استفاده قرار می‌گیرد. +یکی دیگر از مزایای آموختن کار با دیتابیس‌های RDBMS این است که این‌نوع سیستم‌های مدیریت دیتابیس همان‌طور که از نامشان پیدا است، اصطلاحاً Relational (رابطه‌ای) هستند؛ به‌عبارت دیگر، می‌توان بین جداول مختلف، ستون‌های یک جدول با سایر ستون‌های جداول دیگر و به‌طورکلی مابین دیتای ذخیره شده نوعی از ارتباط را برقرار ساخت. + +وجود چنین ارتباطی چندین مزیت دارا است؛ اولین مزیت این که درحین فراخوانی یک داده، می‌توان پی به ارتباطش با سایر داده‌های ذخیره‌سازی شده برد (مثلاً می‌شود مشخص کرد که اگر یک کاربر از جدول مخصوص ذخیره‌سازی اطلاعات کاربران پاک شد، کلیهٔ کامنت‌های ثبت شده توسط آن کاربر هم در جدول مخصوص این‌کار به‌صورت خودکار پاک شود). + +علاوه‌بر این، وجود چنین ارتباطی می‌تواند این تضمین را ایجاد کند که به‌صورت ناخواسته، تحت هیچ‌ عنوان نمی‌شود دیتایی را از دیتابیس حذف کرد؛ به‌عبارت دیگر، اگر مابین ستون‌های ۲ جدول مختلف نوعی ارتباط محدودکننده درنظر گرفته شده باشد، مادامی‌که دیتای یکی از جداول در جایی مورد استفاده قرار گرفته باشد،‌ دیگر امکان حذف آن داده وجود ندارد و همین مسأله این تضمین را ایجاد می‌کنند که یکپارچگی مابین کلیهٔ داده‌های ذخیره‌شده حفظ می‌گردد. + +یکی دیگر از نکاتی که در مورد RDBMSها می‌بایست مدنظر قرار داد این است که این سیستم‌های مدیریت دیتابیس با زبان‌های برنامه‌نویسی مختلفی سازگار هستند و امکان استفادهٔ هم‌زمان توسط چندین زبان مختلف را به دولوپر می‌دهند. + +به‌طور مثال، فرض کنیم وب اپلیکیشنی داریم که برای کدنویسی بخش صفحات دینامیک آن از زبان PHP استفاده کرده‌ایم اما درعین‌حال باتوجه به این که برای تحلیل داده‌ها به زبان و لایبرری‌هایی نیاز داریم که این فرایند را برایمان ساده‌تر کنند، برای این‌کار به‌سادگی بااستفاده از زبان Python می‌توان به تعامل با دیتابیس پرداخت. diff --git a/fa/thing_49/README.md b/fa/thing_49/README.md new file mode 100644 index 00000000..f364002f --- /dev/null +++ b/fa/thing_49/README.md @@ -0,0 +1,20 @@ +# آشنایی با مهارت‌های ارتباطی و فراگیری زبان‌های خارجی + +یکی بخش‌های لاینفک حرفه‌ٔ کدنویسی، ارتباطات است؛ گرچه بخش قابل‌توجی از زمان دولوپرها به تعامل با کامپیوتر، کامپایلر، ابزارهای توسعهٔ نرم‌افزار و مهم‌تر از همه پروژه‌ای که درحال کار کردن روی آن هستند می‌گذرد، اما درعین‌حال دولوپرها گاهی‌اوقات می‌بایست با سایرین نیز به دلایل مختلفی ارتباط داشته باشند. + +موفقیت پروژه‌های بزرگ و مهم برنامه‌نویسی امروزه دیگر بیش از آن‌که دلیل فنی داشته باشد، مستلزم وجود تعاملی سازنده به‌صورت گروهی-اجتماعی است؛ بسیاری از برنامه‌نویسان موفق کسانی هستند که علاوه‌بر تسلط به یک یا چند زبان برنامه‌نویسی، به مهارت‌های ارتباطی و دیگر زبان‌های زندهٔ دنیا به‌غیر از زبان مادری خود نیز مسلط هستند. + +نیاز به توضیح نیست که در فرایند کدنویسی، دولوپر به‌نوعی از طریق کدهایی که می‌نویسد صحبت کرده و از سیستم می‌خواهد تا تسک‌های مدنظرش را به انجام برساند. یک برنامه‌نویس خوب در تعامل با دیگر افراد نیز به‌خوبی می‌داند که با چه زبانی و با چه شیوه‌ای به تعامل با ایشان بپردازد تا به بهترین شکل ممکن بتواند منظورش را به دیگران منتقل کرده و ارتباطی اثربخش ایجاد نماید. + +نکته‌ٔ دیگری که در زمینهٔ ارتباطات فردی در حوزهٔ توسعهٔ نرم‌افزار می‌بایست مدنظر قرار داد این است که به غیر از دولوپرها، افراد ذی‌نفع بسیاری در یک پروژهٔ نرم‌افزاری نسبتاً‌ بزرگ دخیل هستند که از آن جمله می‌توان به مدیر محصول، مدیر پروژه، کارشناس تجربهٔ کاربری، مدیر بازاریابی، تسترهای نرم‌افزار، دولوپرهای فرانت‌اند و همچنین صاحب اصلی محصول (مشتری) اشاره کرد که برخی از ایشان دارای دانش فنی هستند و برخی دیگر خیر. + +یک دولوپر خوب کسی است که به‌خوبی با نیازهای تک‌تک افراد فوق‌الذکر آشنایی داشته و ایشان را به‌خوبی درک کند و برای نیل به چنین مهمی، ما می‌بایست با هریک از افراد بالا با زبان خودش بتوانیم صحبت کنیم؛ به‌عبارت دیگر، جایی نیاز است فنی صحبت کنیم و جایی هم می‌بایست در غیرفنی‌ترین حالت ممکن منظور خود را بیان کنیم تا مخاطب کاملاً متوجه منظورمان شود. + +اجازه دهید برای روشن‌تر شدن این مسأله، مثالی بزنیم؛ فرض کنیم یک مشتری داریم که حسابدار است و قرار است برایش یک نرم‌افزاری مالی بنویسیم؛ برای این که ارتباط کلامی با این مشتری به بهترین شکل ممکن صورت گیرد، ما می‌بایست با برخی مفاهیم حسابداری همچون ترازنامه، بدهکار، بستانکار، صورت مالی، دارایی جاری، اصل بهای تمام‌شده، بدهی، معوقه و غیره آشنایی داشته باشیم که اصطلاحاً به این موارد Jargon گفته می‌شود. + +نکته Jargon به اصطلاحات تخصصی هر حرفه‌ای گفته می‌شود که بخش قابل‌توجهی از مکالمات افراد فعال در آن حوزه بااستفاده از این اصطلاحات تخصصی صورت می‌گیرد؛ به‌عنوان مثال، افراد مختلفی همچون پزشکان، وکلا، حسابداران، مکانیک‌ها، برنامه‌نویس‌ها و دیگر متخصصین هرکدام اصطلاحات کاری خود را دارند که در حین صحبت با همکارانشان، به‌سادگی از آن‌ها استفاده کرده و هردو طرف هم به‌خوبی منظور یکدیگر را متوجه می‌شوند. +به‌طور‌کلی، زمانی‌که یک برنامه‌نویس این وظیفه را دارا است تا نیازها، ایده‌ها و دغدغه‌های مشتریان را به کد تبدیل کند، آشنایی با این جارگون‌ها یک ضرورت است. همچنین جدای از تمامی این مباحث و دانستن این نکته که مهارت‌های ارتباطی و اجتماعی بخشی جدایی‌ناپذیر از زندگی یک دولوپر است، برخورداری از دانش زبان انگلیسی برای دولوپری که قصد دارد برچسب حرفه‌ای روی خود بزند یک باید است. + +به‌عبارت دیگر، دولوپری که بخواهد پابه‌پای دانش روز نرم‌افزاری دنیا حرکت کند، به‌راحتی داکیومنت‌های زبان‌های برنامه‌نویسی، لایبرری‌ها و غیره را بخواند، به‌راحتی در گوگل و استک‌اورفلو سرچ کند و با دیگر دولوپرهای سراسر دنیا در ارتباط باشد، داشتن مهارت زبان انگلیسی (حداقل خواندن و نوشتن) کم‌ترین چیزی است که از وی انتظار می‌رود. + +به‌عبارت دیگر، اگر دولوپر تازه‌کاری هستید که قصد دارید حرفه‌ٔ توسعه‌ٔ نرم‌افزار را به‌عنوان شغل اصلی خود و محل درآمدتان انتخاب کنید اما دانش کافی در زمینهٔ زبان انگلیسی ندارید، توصیه می‌شود فراگیری زبان برنامه‌نویسی خود را متوقف کرده و شروع به یادگیری زبان انگلیسی کنید چراکه پس از مسلط شدن به مهارت‌های خواندن و نوشتن -و البته درصورت امکان مهارت‌های صحبت کردن و گوش کردن- سرعت یادگیری و پیشرفت شما در زمینهٔ کدنویسی به‌مراتب بیش از زمانی خواهد بود که زبان نمی‌دانستید! diff --git a/fa/thing_50/README.md b/fa/thing_50/README.md new file mode 100644 index 00000000..880b106e --- /dev/null +++ b/fa/thing_50/README.md @@ -0,0 +1,28 @@ +# خود را با مهارت تخمین زدن تجهیز کنید! + +به‌عنوان یک دولوپر، گاهی‌اوقات نیاز است تا در مورد چیزهای مختلف همچون زمان تکمیل یک تسک و غیره به مدیران، همکاران و حتی گاهی هم کاربران سرویسی که درحال توسعهٔ آن هستند تخمین بزنید تا ایشان به‌راحتی بتوانند در مورد زمان، هزینه‌های جاری، فناوری‌ و دیگر منابع مورد نیاز برای دستیایی به اهدافشان تصمیم‌گیری کنند. + +تخمین زدن چیزهای مختلف، یک مهارت است که می‌بایست تکنیک‌هایی برای هرچه بهتر انجام دادن این کار آموخت؛ پیش از هرچیز، باید بدانیم که اصلاً «تخمین زدن» به چه معنا است و برای «چه کارهایی» می‌بایست از آمار و ارقام تخمینی استفاده کرد. اجازه دهید برای روشن‌تر شدن این مسأله، مکالمه‌ای فرضی مابین یک مدیر پروژه و یکی از دولوپرهای تیم نرم‌افزاری‌اش را در ادامه مدنظر قرار می‌دهیم: + +مدیر پروژه: می‌تونی یک زمان تخمینی از تکمیل فیچر X بدی؟ +دولوپر: ۱ ماه + +مدیر پروژه: خیلی طولانیه! ما فقط ۱ هفته زمان داریم. +دولوپر: حداقل ۳ هفته زمان نیاز دارم تا بتونم چنین چیزی رو بنویسم. + +مدیر پروژه: بیش از ۲ هفته برام راه نداره. +دولوپر: اوکی مشکلی نیست. + +در پایان این مذاکره، دولوپر به تخمینی از انجام فیچر X دست پیدا می‌کند که مطلوب مدیر پروژه است؛ اما از آنجا که قبول ضرب‌العجل ۲ هفته‌ای از طرف دولوپر به‌نوعی زمان تخمینی مورد تأیید وی نیز محسوب می‌شود، هرگونه مسئولیتی درصورت نرسیدن به این ضرب‌العجل متوجه دولوپر خواهد بود و وی باید پاسخگو باشد. برای این که به درک درستی از چیزی که در این مکالمه اشتباه است برسیم، می‌بایست معنا و مفهوم ۳ چیز مختلف را به‌خوبی درک کنیم: تخمین، هدف و تعهد. + +1 - تخمین (Estimate) یک محاسبهٔ تقریبی یا قضاوت کردن در مورد کیفیت یا کمیت چیزی است؛ چنین تعریفی حاکی از آن است تخمین چیزی است که براساس تجربیات گذشته و دیتایی که در دسترس داریم صورت می‌گیرد و این درحالی است که احساسات و آمال و آرزوها در تخمین زدن همواره می‌بایست مدنظر قرار داده نشوند. تعریفی که از تخمین به‌دست می‌آید همچنین حاکی از آن است یک تخمین هرگز دقیق نیست (مثلاً نمی‌شود گفت که تکمیل فلان تسک برنامه‌نویسی، ۳ روز کاری کامل و ۵ ساعت ۳۰ دقیقه به‌طول خواهد انجامید.) + +2 - هدف (Target) در کسب‌وکار به نقطه‌ای اشاره دارد که پس از رسیدن به آن نقطه، نتیجه‌ای دلخواه نصیبمان می‌شود (مثلاً در یک پروژهٔ نرم‌افزاری این هدف را داریم تا پس از انجام یک تسک، اپلیکیشن بتواند در آن واحد هم‌زمان ۱۰۰۰ کاربر را بدون کمبود در منابع سخت‌افزاری و نرم‌افزاری ساپورت کند). + +3 - تعهد (Commitment) قولی است که یکی از طرفین به دیگری می‌دهد تا تسک خواسته شده را در زمان مقرر با کیفیت مدنظر طرف مقابل به‌صورت مشخصی که روی آن از قبل توافق شده تحویل دهد (به‌طور مثال، در یک پروژهٔ طراحی سایت می‌توان گفت که افزودن شدن قابلیت سرچ به سایت در نسخهٔ ۲.۰ تعهدی است که دولوپر به مشتری می‌دهد). + +گرچه تخمین، هدف و تعهد مجزا از یکدیگر می‌باشند، اما این درحالی است که اهداف و تعهدات می‌بایست براساس تخمین‌های درستی صورت گیرند؛ به‌عبارت دیگر، هدف اصلی از تخمین زدن در فرایند توسعهٔ نرم‌افزار این نیست که خروجی یک پروژه را پیش‌بینی کنیم بلکه هدف اصلی آن است که مشخص کنیم آیا اهداف پروژه به‌اندازهٔ کافی واقع‌گرایانه هستند تا بر آن اساس بتوان مدیریت و برنامه‌ریزی درستی انجام داد یا خیر تا درنهایت بتوان به تعهدات قول داده شده دست یافت. + +اگر مجدد به مکالمهٔ صورت گرفته مابین مدیر پروژه و دولوپرش باز گردیم، می‌بینیم که این مدیر قصد داشت تا براساس هدفی نادرست که در ذهنش داشت، دولوپر را مجبور کند متعهد به انجام تسک X شود و در این مکالمه اصلاً منظور مدیر پروژه گرفتن یک زمان تخمینی از دولوپر نبود! + +در پایان هم یادآوری یک نکته ضروری است که هروقت از شما خواسته شد تا به‌عنوان یک برنامه‌نویس در مورد چیزی تخمین بزنید، اطمینان حاصل کنید که از تمامی جنبه‌های کار آگاهی دارید، پس از تخمین زدن و وسط کار از شما تکمیل تسک‌های جانبی خواسته نمی‌شود، تمامی ابزارها و حداقل شرایط لازم برای به انجام رساندن تسک خواسته شده را دارید و از همه مهم‌تر، کلیهٔ شرایط پیش‌روی شما واقع‌گرایانه هستند. diff --git a/fa/thing_51/README.md b/fa/thing_51/README.md new file mode 100644 index 00000000..72f3e3f3 --- /dev/null +++ b/fa/thing_51/README.md @@ -0,0 +1,23 @@ +# کدام یک؟ IDE یا Editor ، مسأله این است! + +یکی از نکاتی که در ۹۷ چیزی که هر برنامه‌نویسی باید بلد باشد پیش از این گفته شد، مسألهٔ «IDE خود را مثل موم در دست بگیرید» بود؛ در این آموزش گفتیم که یک دولوپر حرفه‌ای کسی است که آنقدر به IDE خود مسط باشد که به‌سادگی و بااستفاده از کلیدهای میانبر بتواند به‌بخش‌های نرم‌افزار مورداستفادهٔ خود دسترسی یافته و به‌سرعت کدنویسی کند. + +به خاطر داشته باشید IDE مخفف واژگان Integrated Development Environment به‌معنی «محیط توسعهٔ یکپارچهٔ برنامه‌نویسی» است که از جمله IDEهای معروف و محبوب می‌توان به Eclipse ،Visual Studio و IntelliJ IDEA اشاره کرد. +اما درعین‌حال، برخی متخصصین بر این باورند که IDEها -اگر نگوییم همیشه، اما در ابتدای راه فراگیری اصول کدنویسی- دولوپرها را به‌نوعی تنبل و وابسته می‌کنند. اجازه دهید برای روشن‌تر شدن دلیل چنین اتفاقی، چند مثال ساده بزنیم. + +یکی از خصوصیات منحصربه‌فرد IDEها چیزی است تحت‌عنوان Code Completion؛ به‌عبارت دیگر، نرم‌افزار وقتی که شما ابتدای نام تابعی از پیش تعریف شده در زبان برنامه‌نویسی مدنظر خود را می‌نویسید، برای این که به فرایند کدنویسی شما سرعت بخشد پیشنهاداتی به شما داده و درنهایت کد تابع شما را تکمیل می‌کند. + +علاوه‌بر این، یکی دیگر از خصوصیات بسیار کاربردی IDEها برقرار ارتباط بین بخش‌های مختلف پروژه است؛ به‌عبارت دیگر، اگر مثلاً زبانی همچون PHP را درنظر بگیریم، وقتی که قصد داریم یک کلاس از یکی از ماژول‌های پروژه را در کلاسی در ماژولی دیگر مورد استفاده قرار دهیم، می‌بایست کلاس مدنظر را به‌اصطلاح use کنیم اما این درحالی است که نرم‌افزاری همچون اکلیپس این‌کار را به‌صورت خودکار برای برایمان انجام داده به‌طوری‌که اصلاً روحمان هم خبردار نخواهد شد که چنین اقدامی صورت‌ گرفته است! + +این‌ها صرفاً ۲ مثال از صدها کاربرد اثربخش، مفید و منحصر‌به‌فرد IDEها است و اگر فقط‌وفقط به یک روی سکه نگاه کنیم، این ۲ مورد و صدها مورد دیگر را می‌توان به‌عنوان نقاط قوت یک IDE قلمداد کرد. + +اما روی دیگر سکه چه‌طور؟ +برخی دولوپرها بر این باورند که روی دیگر سکه مادامی‌که برنامه‌نویسی مبتدی از یک IDE استفاده می‌کند را می‌توان به‌عنوان یک نقطهٔ ضعف قلمداد کرد. مجدد اجازه دهید برای روشن‌تر شدن این مسأله، به ۲ مثالی که در بالا بدان‌ها اشاره شد بازگردیم. + +وقتی که ما از یک IDE استفاده می‌کنیم و این نرم‌افزار هم صرفاً قصد این را دارا است تا فرایند کدنویسی را برایمان لذت‌بخش‌تر سازد و مثلاً وقتی نام فانکشنی همچون explode در زبان پی‌اچ‌پی را می‌نویسیم، به‌صورت خودکار ادامهٔ نام این فانکشن را تکمیل کرده و حتی پارامترهای ورودی پیش‌فرض را نیز مدنظر قرار می‌دهد. + +نقطهٔ منفی چنین کاری این است که یک دولوپر -به‌خصوص زمانی‌که در ابتدای راه کدنویسی است- دیگر مبانی زبان مدنظرش در ذهنش نهادینه نشده و هموراه وابسته به نرم‌افزار برای تکمیل کدها است و اگر روزی قرار باشد تا با نرم‌افزاری مثلاً همچون Nodepad ویندوز، Gedit لینوکس و یا TextMate مکینتاش اقدام به ویرایش سورس‌کدی کند، به احتمال قریب‌به‌یقین در این رابطه به مشکل خواهد خورد. + +یا حتی وقتی که در مثال دوم گفتیم اکلیپس به‌صورت خودکار کلاس‌های مورد استفاده را اصطلاحاً use می‌کند، در دراز مدت ممکن است ما هرگز متوجهٔ بایدی بودن چنین کاری نشویم و از آنجا که همواره کلاس‌های use شده در بالای فایل هستند و معمولاً ما هم در بخش‌های پایینی یک فایل کدی را اضافه کرده و یا اقدام به ریفکتور کردن بخشی از کد می‌کنیم، هرگز متوجه نمی‌شویم که این کار باید صورت گیرد و مجدد اگر روزی قرار باشد تا با یک ادیتور ساده دست به ویرایش سورس‌کد بزنیم، ممکن است عدم توجه به این مسأله منجر به سردرگمی‌مان برای دقیقه‌های -و شاید ساعت‌های- متمادی گردد. + +در کل، IDEها بسیار خوب هست اما به‌نظر می‌رسد که در ابتدای راه کدنویسی،‌ بیش از آن‌که مفید باشند و در دراز مدت کمک برنامه‌نویس کنند، وی را تنبل و وابسته بار می‌آورند؛ لذا توصیه آن است که در حین یادگیری اصول کدنویسی و یا مبانی یک زبان برنامه‌نویسی، همواره از ادیتورهای ساده‌ای مثل موارد فوق‌الذکر استفاده نمایید تا اصول و زیروبم زبان مدنظر در ذهنتان نهادینه شود سپس زمانی‌که احساس کردید به‌خوبی می‌دانید که مثلاً فانکشن‌های مختلف به‌ چه شکلی نوشته می‌شوند، ارتباط بخش‌های مختلف یک زبان‌ برنامه‌نویسی خاص به چه شکل است و غیره، در آن موقع می‌توانید برای آن‌که سرعت کدنویسی خود را افزایش دهید -که خود این مسأله هم به‌نوعی حاکی از حرفه‌ای بودن است- می‌توانید به استفاده از یک IDE روی آورید. diff --git a/fa/thing_52/README.md b/fa/thing_52/README.md new file mode 100644 index 00000000..ac82681f --- /dev/null +++ b/fa/thing_52/README.md @@ -0,0 +1,13 @@ +# ارسال پیام خطا به دولوپر توسط نرم‌افزار + +شما ممکن است پروژه‌های نرم‌افزاری‌تان را بااستفاده از تست‌های خودکار (Automated Tests) سنجیده، آمار و ارقام مفیدی در مورد سورس‌کد، باگ‌ فیکس‌ها و … داشته باشید که حاوی اطلاعات ارزشمندی دربارهٔ فرایند تکامل پروژه در طول زمان باشند. + +دولوپرهای حرفه‌ای همواره یک خط قرمزی دارند که هرگز اجازه نمی‌دهند کیفیت کدها پایین‌تر از آن قرار گیرد؛ حال اگر چنین خط قرمزی توسط خود پروژه مدیریت شود چه اتفاقی رخ خواهد داد؟ به‌عبارت دیگر، خود سورس‌کد به گونه‌ای طراحی شود که اگر چیزی در شرف خراب شدن بود، به دولوپر هشدار دهد. + +یک اپلیکیشن هم می‌تواند همچون ما آدم‌ها سخنگو باشد اما به این شکل که یا از طریق ایمیل و یا از طریق دیگر راه‌های ارتباطی همچون پیامک، نوتیفیکشن و غیره اطلاعاتی از چند و چون کارکرد اپلیکیشن را در اختیار دولوپر قرار دهد. + +اگر در حین کدنویسی به چنین قابلیتی هم فکر کنیم -یعنی خود نرم‌افزار در مورد تعداد اکسپشن‌ها، ارورها و غیره به دولوپرش هشدار دهد- می‌توانیم اطمینان حاصل کنیم قبل از آن که اوضاع روبه وخامت بگذارد، می‌توانیم دست به اصلاح سورس‌کد بزنیم. + +برخی دولوپرها هم به‌خاطر مهم دانستن این موضوع، کمی خلاقیت به‌خرج داده و سیستمی طراحی می‌کنند که درصورت بروز مشکلات فنی در اپلیکیشن طراحی شده، یک چراغ قرمز هشدار چنین پیامی را به اعضای تیم توسعهٔ نرم‌افزار منتقل کند و شاید هم برخی پا را از این هم فراتر گذاشته و سیستمی طراحی کننده که بااستفاده از یک اسپیکر، نرم‌افزار درصورت بروز مشکل به صدا درآمد و مثلاً بگوید «دولوپرم عزیزم من اصلاً حالم خوب نیست و باگ‌ها امانم رو بریده‌اند!» + +به‌طورکلی، لاگ‌ها اطلاعات بسیار ارزشمندی از نحوهٔ کارکرد نرم‌افزار در اختیار دولوپر قرار می‌دهند و این درحالی است که بسیاری از دولوپرها اصلاً توجهی به این دست اطلاعات ارزشمند نمی‌کنند! ما به‌سادگی و بااستفاده از لاگ‌های نرم‌افزارمان می‌توانیم روزبه‌روز دست به بهبود سورس‌کد زده و باگ‌ها، خطا‌ها و اکسپشن‌ها را به حداقل برسانیم. diff --git a/fa/thing_53/README.md b/fa/thing_53/README.md new file mode 100644 index 00000000..c367f6b2 --- /dev/null +++ b/fa/thing_53/README.md @@ -0,0 +1,14 @@ +# چیزهای اضافی را لود نکنید! + +به لطف جامعهٔ اپن‌سورس، امروزه می‌بینیم که بسیاری از زبان‌های برنامه‌نویسی، فریمورک‌ها، لایبرری‌ها و غیره به‌صورت اپن‌سورس و رایگان در اختیار دولوپرها قرار گرفته‌اند؛ این وفور نعمت، گاهی منجر به ایجاد آشفتگی در پروژه‌های نر‌م‌افزاری می‌شود زیرا از آنجا که دولوپر نمی‌خواهد برای استفاده از مثلاً لایبرری X در پروژه‌اش هزینه‌ای بپردازد، گرچه دیگر نیازی به این لایبرری ندارد، اما کماکان این لایبرری داخل پروژه قرار دارد که نه‌تنها فضایی را اشغال کرده است (ولو چند کیلوبایت) بلکه لینک به این لایبرری در جای‌جای سورس‌کد هم مشاهده می‌شود و این درحالی است که اگر دولوپر دیگری بخواهد این پروژه‌ را در آینده نگهداری کرده و یا توسعه دهد، ممکن است دچار سردرگمی شود. + +در چنین مواقعی می‌بایست تمام تلاش خود را به‌کار بندیم تا وابستگی‌های پروژه همچون ماژول‌ها، لایبرری‌ها و غیره کاملاً شفاف بوده و اگرهم تمایل نداریم تا مثلاً لایبرری‌های بلااستفاده را حذف کنیم، حتماً می‌بایست به‌نوعی مشخص شوند (که این کار را با کامنت‌گذاری صحیح می‌توان انجام داد). + +این قضیه نه‌تنها در مورد لایبرری‌های به‌اصطلاح Third Party صدق می‌کند، بلکه در مورد کلاس‌ها، متدها و حتی متغیرها هم صادق است؛ به‌عبارت‌دیگر، گاهی در سورس‌کد برخی پروژه‌ها فانکشن‌هایی را می‌بینیم که در هیچ کجای پروژه فراخوانی نشده‌اند و اما کماکان وجود داشته و حتی کامنت‌ هم نشده‌اند! + +نکته در صنعت توسعهٔ نرم‌افزار منظور از اصطلاح Third Party، کامپوننت‌های توسعه داده شده توسط هر تیم توسعه، شرکت و یا گروهی به‌غیر از توسعه‌‌دهندهٔ اصلی یک محصول (لایبرری، زبان‌برنامه‌نویسی، فریمورک و غیره) است که چنین کامپوننت‌هایی یا به‌صورت اپن‌سورس و رایگان و یا به‌صورت پولی عرضه می‌گردند. +در چنین شرایطی، وقتی که می‌خواهیم اقدام به حذف بخش‌هایی از سورس‌کد کنیم که دیگر مورد استفاده قرار نمی‌گیرند -همچون لایبرری‌های قدیمی یا حتی کلاس‌های بلااستفاده- حتماً می‌بایست به‌خاطر داشته باشیم اصلاً نباید این اطمینان را داشته باشیم که ۱۰۰٪ در هیچ‌کجای پروژه از موارد مدنظر استفاده نشده‌ است. + +برای اطمینان حاصل کردن از این موضوع، ابتدا باید لایبرری را به‌صورت موقت حذف کرده سپس به انحاء مختلف شروع به تست پروژه کنیم تا مطمئن شویم که بدون حضور مثلاً لایبرری X، پروژه کماکان بدون مشکل کار می‌کند. + +به‌طورکلی، تمیز بودن سورس‌کد پروژه -که نبود لایبرری‌ها، ماژول‌ها، کلاس‌ها و فانکشن‌های بلااستفاده در آن به‌نوعی مرتبط با تمیز بودن است- نشان از حرفه‌ای بودن دولوپرش دارد اما این تمیزی سورس‌کد بیش از هر چیزی، کمک به دیگر دولوپرهایی خواهد کرد که ممکن است در آینده بخواهند روی چنین پروژه‌ای کار کنند. diff --git a/fa/thing_54/README.md b/fa/thing_54/README.md new file mode 100644 index 00000000..1cef0a2d --- /dev/null +++ b/fa/thing_54/README.md @@ -0,0 +1,21 @@ +# چه‌موقع و چگونه از راه‌کارهای موقتی در کدنویسی استفاده کنیم؟ + +در پاسخ به این سؤال که چرا برخی دولوپرها دست به استفاده از سولوشن‌های (راه‌کارهای) موقتی می‌زنند بایستی گفت که علت اصلی مشکلات غیرمنتظره‌ای هستند که پیش می‌آیند و بایستی در کوتاه‌ترین زمان ممکن رفع شوند. + +در بسیاری از تیم‌های توسعه‌ٔ نرم‌افزار همواره بخش‌‌هایی وجود دارند که هرگز از استانداردهای کدنویسی تبعیت نکرده و با سایر بخش‌های سورس‌کد هم‌خوانی ندارند و بالاخره روزی می‌بایست ریفکتور شده و با سایر بخش‌های سیستم هارمونی پیدا کنند. + +نیاز به توضیح هم نیست که اکثر دولوپرها همواره از این موضوع شاکی هستند؛ گرچه دلایل بسیاری برای وجود این دست «راه‌کارهای موقتی» بسیارند اما کلید موفقیت این دست راه‌کارها کاربردی بودنشان است! + +باتوجه به این که Interim Solutions (راه‌کارهای موقتی) به‌نوعی مفید واقع شده و مورد قبول برخی دولوپرها قرار گرفته‌اند، کمتر کسی را می‌توان یافت که برای رفع آن‌ها گامی بردارد چراکه مفید، کاربردی و مشکل‌گشا بوده و تنها نقطه‌ضعفی که دارند این است که استانداردهای کدنویسی را فالو نمی‌کنند (البته این درحالی است که چنین چیزی در بسیاری از شرکت‌های نرم‌افزاری و تیم‌های توسعه اصلاً مشکل خاصی محسوب نمی‌شود). + +حال ممکن است زمان‌هایی پیش آید که پس از پیاده‌سازی راه‌کارهای موقتی به‌منظور رفع یک باگ و یا افزودن یک فیچر جدید، نرم‌افزار پس از مدتی به مشکل می‌خورد و از آنجا که استانداردهای کدنویسی در پیاده‌سازی این دست راه‌کارها اعمال نشده، طبق روال هم به‌سادگی نمی‌توان دست به رفع مشکلات پیش آمده زد. + +در پاسخ به این سؤال که در چنین مواقعی چه باید کرد؟ بایستی گفت که معمولاً آپدیت‌های موقعی روی باگ‌های موجود در راه‌کارهای موقتی جواب می‌دهند و از لحاظ ماهیت، آپدیت‌های موقتی دقیقاً شبیه راه‌کارهای موقتی هستند با این تفاوت که کمی به‌روزشده‌تر می‌باشند. + +همواره این نکته را به‌خاطر داشته باشیم زمانی‌که پروژه‌ای حاوی راه‌کارهای موقتی بسیاری باشد، از یک سو پیچیدگی سورس‌کد افزایش یافته و از سوی دیگر نگهداری، آپدیت و دیباگینگ نرم‌افزار هم به‌مراتب دشوارتر خواهد شد. به‌عنوان یک Best Practice کلی، وقتی در فرایند توسعه‌ٔ نرم‌افزار با مشکلی روبه‌رو شدید، ابتدا مراحل زیر را به ترتیب اولویت انجام دهید: + +۱- تا حد ممکن از ارائهٔ راه‌کارهای موقتی خودداری کنید. خودداری‌هایی از این دست در بسیاری از موارد چارهٔ کار نیست چراکه ممکن است مشکلی جدی بوجود آمده باشد که نیاز است تا در اسرع وقت رفع گردد و اگر دولوپر پروژه بخواهد استانداردهایی که تا پیش از این به‌کار می‌‌بسته را در رفع مشکل فعلی مدنظر گیرد، این استانداردها دست‌وپاگیر خواهند بود اما به‌هرحال به‌عنوان اولین تلاش چنین چیزی توصیه می‌شود. + +۲- تا حد ممکن مقابل اصرارهای مدیر پروژه به‌منظور اعمال یک فیچر خاص در کمترین زمان ممکن مقابله نمایید. در برخی موارد، اصرارهای مدیر پروژه آنقدرها هم که وی وانمود می‌کند لازم‌الاجرا نیست و از همین روی ضرری ندارد که تا حدی در مقابل اصرارهای وی مقاومت کرد. + +۳- اگر هم مجبور به این کار شدید، تا حد ممکن حداقل‌ استانداردهای کدنویسی را رعایت نمایید. به‌عبارت دیگر، اگر گایدلاین‌ها و استانداردهای کدنویسی را گروه‌بندی کنید، می‌توانید در اعمال چنین راه‌کارهایی آن‌دسته از استانداردهایی که به‌مراتب مهم‌تر از بقیه هستند را رعایت نموده و الباقی را نادیده بگیرید. diff --git a/fa/thing_55/README.md b/fa/thing_55/README.md new file mode 100644 index 00000000..d33e3270 --- /dev/null +++ b/fa/thing_55/README.md @@ -0,0 +1,62 @@ +# استفادهٔ نادرست از اینترفیس‌ها را غیرممکن سازید + +در برنامه‌نویسی شیٔ‌گرا به‌خصوص در مبحث Abstraction (انتزاع)، یکی از کارهای رایج ایجاد Interface است؛ اینترفیس‌ها بخشی لاینفک از فرایند کدنویسی حرفه‌ای هستند و این درحالی است که اگر شما به‌عنوان یک دولوپر به‌خوبی از عهدهٔ این‌کار برآیید، از یک سو استفاده از اینترفیس‌ها فرایند کدنویسی را بسیار لذت‌بخش خواهد ساخت و از سوی دیگر، سرعت کدنویسی تک‌تک‌ اعضای تیم افزایش می‌یابد اما درعین‌حال اگر طراحی اینترفیس‌ها به‌درستی صورت نپذیرد، به یک عامل مهم در ایجاد مشکلات پس از پیشروی پروژه مبدل شده و بیش از آن که منجر به سرعت کدنویسی اعضای تیم شود، بیشتر به یک گلوگاه مبدل خواهد شد! + +اینترفیس چیست؟ +اگر خیلی غیرفنی بخواهیم توضیح دهیم، در برنامه‌نویسی شیٔ‌گرایی (OOP) منظور از Interface مجموعه فانکشن‌ها و قابلیت‌هایی است که یک آبجکت می‌بایست داشته باشد تا بتواند تسک‌های مورد انتظار را به انجام برساند. حال اگر بخواهیم کمی فنی‌تر صحبت کنیم، منظور از یک اینترفیس، یک Abstract Class (کلاس انتزاعی) است حاوی یکسری فانکشن و دیگر ویژگی‌ها اما این درحالی است که این فانکشن‌ها تسک خاصی را انجام نمی‌دهند بلکه صرفاً مشخص‌کنندهٔ قابلیتی‌ هستند که یک کلاس می‌تواند داشته باشد و این وظیفهٔ کلاس است تا عملکرد خاصی را برای آن فانکشن‌ها تعریف نماید. + +به‌طورکلی، یک اینترفیس خوب اینترفیسی است که اولاً استفادهٔ درست از آن آسان باشد، ثانیاً استفادهٔ نادرست از آن غیرممکن -یا حداقل مشکل- باشد! + +استفادهٔ درست از اینترفیس می‌بایست آسان باشد +وقتی اینترفیسی جهان‌شمول و خوب طراحی شده باشد، دولوپرها همواره تمام تلاش خود را به کار می‌گیرند تا از آن استفاده کنند چراکه می‌دانند در آینده کمتر به مشکل برخواهند خورد. + +به‌طورمثال، استفاده از اینترفیس‌های اصولی در طراحی API منجر به این خواهد گشت تا دولوپرها همواره مجبور باشند پارامترهای درستی را به‌همراه مقادیر درست به فانکشن‌های مورد استفادهٔ خود پاس دهند. به‌عبارت دیگر، اینترفیس‌هایی که استفاده از آن‌ها آسان است، منجر به انجام طبیعی فرایندهای مورد انتظار از نرم‌افزار می‌شوند. + +استفادهٔ نادرست از اینترفیس می‌بایست دشوار باشد +اینترفیس‌های خوب و اصولی اشتباهات احتمالی کاربران را پیش‌بینی کرده و بروز چنین اشتباهاتی را غیرممکن -یا حداقل دشوار- می‌سازند. اگر مجدد به مثال API فوق‌الذکر بازگردیم، یک اینترفیس غیراصولی استفاده شده در یک API این امکان را به کاربر می‌دهد تا پارامتری که صرفاً می‌بایست Integer باشد را با هر دیتاتایپی ارسال کند که این اصلاً خوب نیست. + +چگونه اینترفیس‌هایی طراحی کنیم که استفادهٔ درست از آن‌ها آسان باشد؟ +در پاسخ به سؤال فوق بایستی گفت که یک راه مناسب برای طراحی اینترفیس‌های اصولی این است که پیش از ایجادشان، اقدام به استفاده از آن‌ها نماییم! از آنجا که ممکن است کمی گیج شده باشید، با ذکر مثالی به بررسی این موضوع می‌پردازیم. + +پیش از هر چیز، خود را جای دیگر دولوپرها بگذارید و از نگاه ایشان به فرایند کدنویسی پروژه‌ٔ‌تان نگاه کنید؛ سپس پیش از آن که دست‌به‌کد شوید، سناریوهای مختلف را روی کاغذ نوشته و به بررسی آن‌ها بپردازید. + +به‌عبارت دیگر، اگر فرضاً شما یکی از کاربران APIیی بودید که در طراحی آن از اینترفیسی استفاده شده است، دوست داشتید اینترفیس مدنظر تا چه اندازه دست شما با باز بگذارد تا به ساده‌ترین شکل ممکن بتوانید اقدام به استفاده از آن API نمایید. + +چگونه اینترفیس‌هایی طراحی کنیم که استفادهٔ نادرست از آن‌ها دشوار باشد؟ +برای به‌دست آوردن چنین قابلیتی، می‌بایست ۲ نکته را مدنظر قرار دهیم: اول این که باید ارورهایی که کاربران ممکن است مرتکب شوند را پیش‌بینی کرده و به هر شکلی که شده جلوی آن‌ها را بگیرید و دوم این که در ماه‌های ابتدایی عرضهٔ‌ اینترفیس می‌بایست کاربری‌های اشتباهش را رصد کرده و در صورت بروز کاربری‌های اشتباه، دست به ریفکتور کردن اینترفیس بزنید (مثلاً اگر مشاهده می‌کنید کاربرانی که از اینترفیس شما استفاده می‌کنند بارها‌وبارها اقدام به پاس دادن پارامترهای اشتباه به فانکشن X می‌کنند، سعی کنید کدها را به شکلی ریفکتور کنید که هم‌راستا با نیازهای کاربران باشد و فانکشن X موجب دردسر کاربران نشود). + +مثالی کاربردی از اینترفیس‌ها در زبان برنامه‌نویسی PHP +در زبان برنامه‌نویسی PHP همچون دیگر زبان‌های برنامه‌نویسی، اینترفیس‌ها این امکان را به دولوپر می‌دهند تا ساختاری واحد برای کلاس‌های مورد استفاده در پروژه تعریف کرده و کلیهٔ آبجکت‌ها از ساختاری استاندارد بهره‌مند گردند. علاوه‌بر این، زمانی‌که شما می‌دانید یک کلاس می‌بایست حاوی چه متدهایی باشد اما در مورد جزئیات داخل متدها مطمئن نیستید، استفاده از اینترفیس‌ها لازم می‌گردد. + +در زبان PHP تعریف کردن اینترفیس دقیقاً شبیه‌ به کلاس‌ها است با این تفاوت که به‌جای کلیدواژهٔ class می‌بایست از کلیدواژهٔ interface استفاده نمود و کلاس‌هایی که قرار است از یک اینترفیس بهره‌مند گردند نیز بااستفاده از کلیدواژهٔ implements به چنین قابلیتی دست خواهند یافت. + +در ادامه اینترفیسی خواهیم ساخت به‌نام Car که حاوی ۲ فانکشن انتزاعی تحت‌عناوین ()setModel و ()getModel است: +``` C +interface Car { + public function setModel($name); + + public function getModel(); +} +``` +همان‌طور که می‌بینیم، یکی از فانکشن‌ها شامل یک پارامتر ورودی نیز هست؛ حال کلاسی می‌سازیم تحت‌عنوان MyCar که قرار است حاوی ویژگی‌های انتزاعی اینترفیسی باشد که پیش از این نوشتیم: +``` C +class MyCar implements Car { + private $model; + + public function setModel($name) + { + $this->model = $name; + } + + public function getModel() + { + return $this->model; + } +} +``` +همان‌طور که می‌بینیم، کلاس MyCar بااستفاده از کلیدواژهٔ implements کلیهٔ ویژگی‌های اینترفیس Car را به‌دست آورده است. + +به خاطر داشته باشید وقتی کلاسی از یک اینترفیس implements می‌کند، می‌بایست کلیهٔ فانکشن‌های نوشته شده در اینترفیس در کلاس مدنظر نیز تعریف شوند حتی اگر مورد استفاده قرار نخواهند گرفت که در غیر این‌صورت با ارور مفسر پی‌اچ‌پی مواجه خواهیم شد. +حال اگر بخواهیم کلاس دیگری مثلاً تحت‌عنوان YourCar داشته باشیم، می‌توانیم این کلاس را نیز از اینترفیس Car بهره‌مند گردانده تا این اطمینان حاصل شود که کلیهٔ کلاس‌های مدنظر -همچون MyCar و YourCar و غیره- و بالتبع آبجکت‌های ساخته شده از روی آن‌ها دارای استاندارد واحدی هستند. + +در پایان هم به‌خاطر داشته باشیم که فلسفهٔ وجودی Interface سهولت دولوپرهایی یا کاربرانی است که از آن استفاده می‌کنند نه سهولت دولوپرهایی که اقدام به طراحیش نموده‌اند! diff --git a/fa/thing_56/README.md b/fa/thing_56/README.md new file mode 100644 index 00000000..2de0d19b --- /dev/null +++ b/fa/thing_56/README.md @@ -0,0 +1,17 @@ +# تا حد ممکن همه‌ چیز را شفاف‌سازی کنید + +یکی از مشکلاتی که همواره مدیران پروژه و دولوپرها با آن دست‌وپنجه نرم‌ می‌کنند، ددلاین (ضرب‌العجل) هایی است که به حقیقت نمی‌پیوندند! به‌عبارت دیگر، مدیر پروژه قولی را به مشتری می‌دهد که مثلاً پروژه‌ای در تایم مشخصی تکمیل خواهد شد و یا دولوپر به مدیر پروژه قول می‌دهد که فلان ماژول پروژه ظرف مثلاً ۱ هفته به اتمام خواهد رسید اما این درحالی است که هیچ‌کدام از این قول و قرارها به واقعیت تبدیل نمی‌‌شوند! + +یکی از دلایل چنین معضلی این است که روند پیشرفت پروژه شفاف نیست؛ درواقع،‌ وقتی که ما فرایند پیشرفت پروژه را به‌صورت لحظه‌ای رصد کنیم، اگر مشکلات پیش‌رو به اندازه‌ای باشند که ما را از رسیدن به ددلاین مدنظر باز دارند، پیش از آن که بدقول شویم می‌توانیم سیاست دیگری اتخاذ کنیم (مثلاً یا تعداد دولوپرهای پروژه را افزایش دهیم و یا به مذاکره برای گرفتن زمان بیشتر بپردازیم). + +به‌طورکلی، بااستفاده از استیک‌نوت‌ها می‌توان فرایند تکمیل پروژه را دائماً در معرض دید خود و سایر اعضای تیم قرار داد بدین شکل که از عناوینی همچون «شروع نشده»، «در دست اقدام» و «تکمیل شده» برای نشان دادن روند انجام کار استفاده کرد. + +شفاف‌سازی فقط در ارتباط با زمان تکمیل پروژه حائز اهمیت نیست بلکه شفاف‌سازی چیزی است که در تمامی مراحل توسعه‌‌ٔ نرم‌افزار می‌بایست مدنظر قرار داده شود که در ادامه به برخی چیزهایی که منجر به شفاف‌تر شدن کار می‌شوند خواهیم پرداخت: + +- مستندسازی پروژه: نیاز به توضیح نیست که کامنت‌گذاری بخش‌های کلیدی نرم‌افزار امری حیاتی است که درنهایت منجر به شفاف‌تر شدن سورس‌کد می‌شود (البته به‌خاطر داشته باشیم که کامنت‌گذاری بیش از اندازه هم اصلاً کار درستی نیست). + +- یونیت تست: تست کردن صحت عملکرد نرم‌افزار از طریق Unit Testها چیز دیگری است که منجر به شفاف‌تر شدن پروژه می‌شود؛ به‌عبارت دیگر، یونیت تست‌ به دولوپرها کمک می‌‌کنند تا کاملاً با وابستگی‌های پروژه آشنا شده و درصورت اعمال تغییر در یکی از بخش‌های پروژه، متوجه شوند که کدام‌یک از سایر بخش‌ها نیز دستخوش تغییر خواهند شد. + +- دیپلوی کردن سریع: چنانچه بتوان یک پروژهٔ نرم‌افزاری به را بخش‌های کوچک و مجزا از یکدیگر تقسیم‌بندی نمود و سپس با تکمیل هر بخش آن‌را دیپلوی (منتشر) کرد، به‌طور شفاف می‌توان خروجی کار را دید. + +به‌طورکلی، شفافیت در فرایند توسعه‌ٔ نرم‌افزار بسیار ويژگی خوبی است چراکه درنهایت منجر به بهبود خروجی کار می‌شود؛ وقتی همه‌چیز شفاف، صریح و قابل‌اندازه‌گیری باشد، اعضای تیم هم بهتر تکلیف خود را خواهند دانست و درنهایت پروژه به شکل بهتری به پیش خواهد رفت. diff --git a/fa/thing_57/README.md b/fa/thing_57/README.md new file mode 100644 index 00000000..030161c8 --- /dev/null +++ b/fa/thing_57/README.md @@ -0,0 +1,28 @@ +# ضرورت آشنایی با مفاهیم کانکارنسی و پاراللیزم + +بسیاری از دولوپرها بر این باورند که Concurrency (کانکارنسی یا هم‌زمانی) و Parallelism (پاراللیزم یا موازات) فرایندهای بسیار پیچیده‌ای بوده و فقط حرفه‌ای‌ها می‌توانند به شکل صحیحی آن‌ها را پیاده‌سازی کنند. + +شاید به‌نوعی بتوان گفت که این دو مفهوم فرایندهای پیچیده‌ای بوده و برای پیاده‌سازی اصولی آن باید باتجربه بود، اما اگر دولوپری بخواهد برچسب حرفه‌ای روی خود بزند، چاره‌ای جز این ندارد که علاوه‌بر آشنایی با این مفاهیم، نحوهٔ پیاده‌سازی آن‌ها در سیستم‌هایی با تعداد پروسس‌های زیاد را هم بلد باشد. + + مفهوم Concurrency چیست؟ +به‌طور خلاصه، بایستی گفت که منظور از کانکارنسی این است که ۲ یا بیش از ۲ تسک به‌صورت هم‌زمان شروع شده، اجرا شوند و درنهایت توسط منابع مشترک -همچون یک پردازنده یا حافظهٔ به اشتراک گذاشته شده- بدون ترتیب خاصی تکمیل گردند. به‌عبارت دیگر، زمانی‌که یک اپلیکیشن قادر به پردازش حداقل ۲ تسک در یک زمان باشد، آن را اپلیکیشنی کانکارنت (Concurrent) می‌نامیم. + +گرچه به‌نظر می‌رسد که تمامی‌ تسک‌ها به‌صورت موازی درحال اجرا هستند اما در عمل این‌چنین نیست بلکه بدین شکل است که تسک اول شروع شده سپس به حالت انتظار درمی‌آید و منابع به تسک دوم اختصاص می‌یابند و در ادامه سیستم‌عامل هم براساس اولویت تسک‌ها، سی‌پی‌یو و دیگر منابع سیستمی همچون مموری در اختیار تسک‌ها قرار داده تا تکمیل گردند. + +مقهوم Parallelism چیست؟ +درصورتی‌که چندین تسک یا یک تسکی که به چندین بخش تقسیم‌بندی شده و در آن واحد توسط پردازنده‌ای چندهسته‌ای (Multi-Core) هندل شود ما با Parallelism سروکار داریم بدین شکل که هر هسته به یک تسک یا یکی از بخش‌های تسکی که به چندین بخش تقسیم‌بندی شده اختصاص می‌یابد. + +به‌خاطر داشته باشیم که در Parallelism ما به سخت‌افزارهایی با پردازندهٔ چندهسته‌ای نیاز داریم و این درحالی است که اگر پردازده صرفاً یک هسته داشته باشد، کانکارنسی اتفاق خواهد افتاد نه پاراللیزم. + +تفاوت‌های Concurrency و Parallelism چیست؟ +1 - کانکارنسی زمانی است که حداقل ۲ تسک در بازهٔ زمانی Overlapping (روی‌هم افتاده) شروع، اجرا و تکمیل می‌گردند درحالی‌که پاراللیزم به زمان اطلاق می‌گردد که تسک‌ها به‌معنای واقعی کلمه در آن واحد -مثلاً در یک پردازندهٔ چندهسته‌ای- اجرا می‌شوند. + +2 - کانکارنسی مرتبط با اجرای پروسه‌های مجزا از یکدیگر است درحالی‌که پاراللیزم اجرای هم‌زمان تسک‌های -احتمالاً- مرتبط است. + +3 - یک اپلیکیشن می‌تواند کانکارنت باشد اما پارالل نباشد؛ به‌عبارت دیگر، چنین اپلیکیشنی بیش از یک تسک را در آن واحد پردازش می‌کند اما هیچ ۲ تسکی در یک لحظه اجرا نمی‌شوند. + +4 - یک اپلیکیشن می‌تواند پارالل باشد اما کانکارنت نباشد؛ به‌عبارت دیگر، چنین اپلیکیشنی بخش‌های مختلف یک تسک را توسط یک پردازندهٔ چندهسته‌ای در آن واحد پردازش می‌کند. + +5 - یک اپلیکیشن می‌تواند نه پارالل باشد و نه کانکارنت؛ به‌عبارت دیگر، چنین اپلیکیشنی تمامی تسک‌ها را به‌ترتیب یکی پس از دیگری پردازش می‌کند. + +6 - یک اپلیکیشن هم می‌تواند پارالل باشد و هم کانکارنت؛ به‌عبارت دیگر، چنین اپلیکیشنی می‌تواند چندین تسک‌ را به‌صورت هم‌زمان از طریق یک پردازندهٔ چندهسته‌ای در آن واحد پردازش کند. diff --git a/fa/thing_58/README.md b/fa/thing_58/README.md new file mode 100644 index 00000000..c43b4643 --- /dev/null +++ b/fa/thing_58/README.md @@ -0,0 +1,76 @@ +# یافتن راه‌کارهای ساده برای مشکلات سخت + +برخی برنامه‌نویسان بر این باورند از آنجا که برخی مشکلات توسعهٔ نرم‌افزار که بسیار چالشی و دشوار هستند را می‌بایست با راه‌کارهای پیچیده مرتفع سازند به‌طوری که اگر سورس‌کد چند ماه پس از کدنویسی در اختیارشان قرار گیرد، به سختی قادر خواهند بود تا اولاً آن‌را درک نموده ثانیاً آن‌را توسعه دهند! برای روشن‌تر شدن این مسأله، قصد داریم مقایسه‌ای مابین حرفه‌ٔ نویسندگی و برنامه‌نویسی داشته باشیم. + +در عصر حاضر کدام رمان‌نویس مشهوری را می‌شناسید که در نگارش رمانش از لغات سخت، پیچیده و تاریخ‌گذشته استفاده کند؟ مگر غیر از این است که رمان‌هایی که امروزه در بازار به چاپ صدم و بالاتر می‌رسند همگی از نثری ساده و قابل‌فهم -حتی برای گروه‌های سنی پایین- برخورداند. اصلاً منکر فاخر بودن گلستان سعدی نیستیم، اما بعید به‌نظر می‌رسد که نثر زیر به‌سادگی قابل درک باشد: + +یاد دارم که در ایام طفلی متعبد بودمی و شب‌خیز و مولع زهد و پرهیز. شبی در خدمت پدر -علیه الرحمه- نشسته بودم و همه شب دیده برهم نبسته و مُصحف عزیز در کنار گرفته و طایفه‌ای گرد ما خفته. پدر را گفتم یکی از اینان سر بر نمی‌دارد که دوگانه‌ای بگذارد و چنان خواب غفلت برده‌اند که گویی نخفته‌اند که مرده‌اند. گفت جان پدر! تو نیز اگر بخفتی به که در پوستین خلق افتی. + +حال به بخشی از کتاب دا نوشته سیده زهرا حسینی تحت‌عنوان «و بالاخره خرمشهر آزاد شد» نگاهی می‌اندازیم: + +بالاخره ساعت ۲، روز سوم خرداد سال 1361 اعلام کردند خرمشهر آزاد شد؛ چه‌کسی می‌توانست حال‌و‌هوای ما را از شنیدن این خبر درک کند. توی ساختمان کوشک ولوله‌ای افتاد، همه یکدیگر را بغل کرده و از خوشحالی گریه می‌کردند. مردم و همسایه‌های تهرانی ما تبریک می‌گفتند؛ همه خوشحال بودند. از خوشحالی نمی‌دانستیم چه‌کار کنیم و رفتیم بیرون ساختمان؛ مردم و کارمندان اداره‌ها همه از شادی این خبر کارشان را رها کرده و به خیابان آمده بودند. همه‌جا پر از هیاهو و سر‌و‌صدا شده بود. همه‌جا شادی موج می‌زد و ... + +از مقایسهٔ این ۲ نثر می‌توان به‌ این نتیجه رسید که فارغ از ارزش ادبی هر کدام، نثر برگرفته از کتاب دا به‌مراتب قابل‌فهم‌تر است. به‌ یاد داشته باشیم که یک رمان‌نویس حرفه‌ای می‌داند که خوانندگان از خرید کتابش چند هدف دارند که مهم‌ترین آن‌ها عبارتند از: +- گذران وقت +- آشنایی با تاریخ +- لذت بردن +- ارتباط برقرار گرفتن با داستان +- کسب تجربه +- یادگیری و … + +حال اگر هریک از پارامترهای فوق -و حتی دیگر ویژگی‌های یک رمان خوب- غايب باشند، احتمال فراگیر شدن رمان در بین خوانندگان کم‌رنگ و کم‌رنگ‌تر خواهد شد. + +در صنعت توسعهٔ نرم‌افزار هم دقیقاً با چنین مسأله‌ای روبه‌رو هستیم؛ به‌عبارت دیگر، یک دولوپر کاری شبیه به نویسندگان دارد با این تفاوت که به‌جای نگارش به زبان فارسی -یا دیگر زبان‌ها- با زبان برنامه‌نویسی مدنظرش و با سینتکس خاصی شروع به نوشتن می‌کند. + +همان‌طور که یک نویسنده در نگارش یک رمان نباید هرگز دامنهٔ لغات و دستور زبانش را بااستفاده از ساختارهای متکلف و پیچیده به رخ خواننده بکشد، یک برنامه‌نویس خوب هم هرگز نباید آن‌قدر پیچیده کد بزند که در آینده دیگر دولوپرها با سورس‌کد خوانی گیج شوند. + +حال همان‌طور که ۲ نثر متکلف و ساده را در بالا با یکدیگر مقایسه کردیم، در ادامه قصد داریم برنامه‌ٔ معروف Hello World را به ۲ صورت پیچیده و ساده بااستفاده از زبان ++C بنویسیم؛ ابتدا با برنامه‌ٔ پیچیده شروع می‌کنیم: + +``` C +#include < iostream > + + class AbstractHello { + public: + virtual~AbstractHello() { + std::cout << " World!"; + } + void Prnt() { + std::cout << "Hello"; + } + + + }; + +class ChildHello: public AbstractHello { + public: + ~ChildHello() { + Prnt(); + } +}; + +int main() { + ChildHello * Obj; + Obj = new ChildHello; + delete Obj; +} +``` +حال همین برنامه‌ را می‌توان با تعداد خطوط کد کمتر و درعین‌حال قابل‌فهم‌تر به‌صورت زیر نوشت: +``` C +#include < iostream > + +int main() { + std::cout << "Hello World!"; +} +``` +به‌عنوان خروجی هر دو برنامه داریم: +``` +Hello World! +``` +به‌طور خلاصه، یک دولوپر خوب کسی است که کدی بنویسد که از ویژگی‌های زیر برخوردار باشد: +- اسامی کلاس‌ها، فانکشن‌ها، متغیرها و … قابل‌فهم اما درعین‌حال ساده باشند. +- ساختار فولدرها و فایل‌ها همگون و سرراست باشند. +- استاندارد کدنویسی یکسانی در جای‌جای پروژه اعمال شده باشد. +- به‌گونه‌ای کدنویسی کند که به‌جای کامنت‌گذاری، خود سورس‌کد گویای ماهیتش باشد. +- و درنهایت کدنویسی‌اش طوری باشد که اگر یک برنامه‌نویس تازه‌کار هم به مرور سورس‌کد پرداخت، بتواند ارتباط بین اجزای مختلف کد را درک کند. + +هر برنامه‌ای -خواه کوچک باشد و خواه بزرگ- بالاخره روزی توسط دولوپری به غیر از دولوپر اولیه‌اش می‌بایست دیباگ، نگهداری و توسعه داده شود؛ به همین دلیل، در حین کدنویسی همواره این نکته را مدنظر داشته باشید که در آینده بالاخره روزی یکی از همکارانتان قرار است روی کدهایی که نوشته‌اید کار کند پس ضروری است تا به‌گونه‌ای کدنویسی کنید که دیگر دولوپرها تا حد ممکن کمتر دچار سردرگمی‌ شوند. diff --git a/fa/thing_59/README.md b/fa/thing_59/README.md new file mode 100644 index 00000000..25eb612f --- /dev/null +++ b/fa/thing_59/README.md @@ -0,0 +1,66 @@ +# دولوپری که نداند Polymorphism چیست، دولوپر نیست! + +مفهوم Polymorphism (پالیمورفیزم یا چندشکلی) یکی از ستون‌های برنامه‌نویسی شیٔ‌گرایی است؛ این اصلاح ریشهٔ یونانی دارد که از ۲ بخش Poly به‌معنی «چند» و Morph به‌معنی «شکل» تشکیل شده است و این اصطلاح در برنامه‌نویسی شیٔ‌گرایی به الگویی اشاره دارد که بر آن اساس، کلاس‌های مختلف با عملکردهای مجزا از یکدیگر می‌توانند از ساختار و کاربری یکسانی بهره‌مند گردند. + +پالیمورفیزم یا چندشکلی در برنامه‌نویسی مفهوم نسبتاً پیچده است که صرفاً با ذکر مثال می‌توان به‌خوبی مفهوم آن را درک کرد؛ لذا در ادامه سعی خواهیم کرد این مفهوم را بااستفاده از زبان PHP تشریح کنیم. + +فرض کنیم یکسری کلاس داریم که مسئول ایجاد اشکالی همچون، دایره، مستطیل و … هستند؛ هریک از این اشکال دارای شکل متفاوتی نسبت به بقیه هستند اما همگی در یک چیز مشترک هستند و آن‌هم این که همهٔ اشکال دارای مساحتی هستند که بااستفاده از یک فانکشن می‌توان آن‌را محاسبه کرد. + +مثلاً برای این‌کار می‌توان فانکشنی تحت‌عنوان ()calcArea درنظر گرفت که در تمامی کلاس‌ها وجود دارد، اما در کلاس دایره مساحت را به یک شکل (Morph) محاسبه می‌کند و در کلاس مستطیل به شکلی دیگر. + +چگونه پالیمورفیزم را پیاده‌سازی کنیم؟ +به‌منظور پیاده‌سازی این مفهوم در برنامه‌نویسی شیٔ‌گرایی، یا باید از Interfaceها استفاده نمود و یا از کلاس‌های به‌اصطلاح Abstract؛ که در ادامه استفاده از اینترفیس‌ها را با ذکر مثال توضیح خواهیم داد (جهت آشنایی بیشتر با مفهوم اینترفیس، به آموزش نود و هفت چیزی که هر برنامه‌نویسی باید بداند: استفادهٔ نادرست از اینترفیس‌ها را غیرممکن سازید مراجعه نمایید). + +همان‌طور که در ادامه مشاهده می‌کنید، اینترفیسی داریم تحت‌عنوان Shape که حاوی فانکشنی تحت‌عنوان ()calcArea است و هر کلاسی که از این اینترفیس استفاده کند، باید دارای چنین فانکشنی باشد: +``` C +interface Shape { + public function calcArea(); +} +حال اقدام به نوشتن کلاس مربوط به دایره می‌کنیم که اینترفیس فوق‌الذکر روی آن اعمال شده است: + +class Circle implements Shape { + private $radius; + + public function __construct($radius) { + $this->radius = $radius; + } + + // calcArea calculates the area of circles + public function calcArea() { + return $this->radius * $this->radius * pi(); + } +} +``` +مجدد دست به ساخت کلاس دیگری این‌بار برای شکل مستطیل می‌زنیم که همانند کلاس مربوط به دایره است با این تفاوت که کدهای قرار گرفته داخل فانکش ()calcArea متفاوت است: +``` C +class Rectangle implements Shape { + private $width; + private $height; + + public function __construct($width, $height) { + $this->width = $width; + $this->height = $height; + } + + // calcArea calculates the area of rectangles + public function calcArea() { + return $this->width * $this->height; + } +} +``` +حال اقدام به ساخت آبجکت‌هایی از روی این ۲ کلاس کرده سپس بااستفاده از فانکشن ()calcArea مساحت شکل را محاسبه می‌کنیم: +``` C +$circ = new Circle(3); +echo $circ->calcArea(); + +$rect = new Rectangle(3, 4); +echo $rect->calcArea(); +``` +خروجی کدهای فوق به‌صورت زیر خواهد بود: +``` +28.274333882308 +12 +``` +در حقیقت، چندشکلی یا پالیمورفیزم این‌گونه تفسیر می‌شود که ما فانکشنی ثابت داریم تحت‌عنوان ()calcArea اما این درحالی است که این فانکشن بسته به این‌که در کدام کلاس قرار گرفته باشد، عملکردی متفاوت از خود نشان خواهد داد و به‌نوعی خود را در چند شکل مختلف عرضه می‌کند. + +وقتی دلوپرها با این مفهوم در OOP آشنا باشند، به‌سادگی به‌جای استفاده از دستورات شرطی مختلف و یا سوئیچ‌ها به‌منظور هندل کردن شرایط مختلف، می‌توانند با به‌کارگیری از مفاهیم اینترفیس و پالیمورفیزم، شرایط مختلفی که در کدنویسی با آن‌ها مواجه می‌شوند را با نوشتن حداقل میزان کد مدیریت کنند. diff --git a/fa/thing_60/README.md b/fa/thing_60/README.md new file mode 100644 index 00000000..ba047db1 --- /dev/null +++ b/fa/thing_60/README.md @@ -0,0 +1,16 @@ +# تستر‌های نرم‌افزار دشمن دولوپرها نیستند! + +کسانی که اقدام به تست نرم‌افزار به‌منظور اطمینان حاصل کردن از صحت عملکردش می‌کنند معمولاً با نام‌هایی همچون Quality Assurance ،Quality Control و یا Tester شناخته می‌شوند اما از دید دولوپرها فرقی نمی‌کند این متخصصین را چه بنامیم چراکه ایشان این گروه از افراد را «معضل» قلمداد می‌کنند! + +جالب است بدانیم که وقتی در مورد تسترها و یا مسئولین کنترل کیفیت از دولوپرها سؤال می‌کنیم، جملاتی همچون «خیلی گیر هستن»، «بیش از حد مته به خشخاش می‌گذارن» و چیزهایی از این است از زبان ایشان می‌شنویم. + +چرا باید به تستترها به شکل یک رفیق نگاه کنیم؟ +ماحصل کار تسترها این است که آبروی ما جلوی مشتری نرود، کارفرما از دست ما شاکی نشود و درنهایت شغل خود را از دست ندهیم! با این تفاسیر، گرچه درظاهر تسترها با ریپورت کردن مشکلات نرم‌افزار ممکن است موجبات ناراحتی دولوپرها را فراهم آورند اما درنهایت این کار تسترها منجر به این خواهد گشت تا دولوپرها حرفه‌ای‌تر جلوه پیدا کنند و از همین روی بهترین رفیق دولوپرها محسوب می‌شوند. + +برای روشن‌تر شدن اهمیت این مسأله، مثالی می‌زنیم؛ فرض کنیم شما دولوپری هستید که روی پروژه‌ای مرتبط با هوش مصنوعی کار می‌کنید (یکی از پیچیده‌ترین نمونه نرم‌افزارهایی که در صنعت IT می‌توان پیاده‌سازی کرد). + +در ادمین پنل اپلیکیشن، یکسری Typo (تایپو یا غلط املایی) وجود دارد، برخی لینک‌ها به صفحهٔ درستی ارجاع نمی‌دهند و چیزهایی از این است که در مقایسه با باگ‌های ساختاری، اصلاً چیزی به‌حساب نمی‌آیند. + +وقتی‌که درحال ارائهٔ دمویی از اپلیکیشن به مشتری هستید، مشتری متوجه مشکلاتی جزئی از این دست می‌شود و اتفاقی که می‌افتد این است که باخود می‌گوید «کسی‌که چیزهایی ابتدایی از این دست رو نتونسته درست کنه، احتمال داره در طراحی الگوریتم‌های هوش مصنوعی، آنالیز داده‌ها و غیره هم بی‌دقتی کرده باشه!». + +به همین سادگی ایماژی منفی از شما در ذهن مشتری یا کارفرما می‌تواند شکل گیرد و این احتمال نیز وجود دارد که ماهیت قرارداد نیز به خطر بیافتد و اینجا است که نقش تسترها اهمیت پیدا می‌کند؛ به‌عبارت دیگر، این گروه از اعضای تیم -که حتی منشی شرکت هم اگر فرد بادقتی باشد می‌تواند به‌نوعی یک تستر خوب محسوب شود- نه‌تنها منجر به این خواهند گشت که آبروی شما نرود، بلکه این کار ایشان درنهایت هم به‌نفع شرکت و هم مشتری خواهد شد. diff --git a/fa/thing_61/README.md b/fa/thing_61/README.md new file mode 100644 index 00000000..42ec3ccf --- /dev/null +++ b/fa/thing_61/README.md @@ -0,0 +1,11 @@ +# همواره یک نسخه از نرم‌افزار برای ریلیس داشته باشید + +برخی تیم‌های توسعهٔ نرم‌افزار هستند که برای پلتفرم‌های مختلف، خروجی‌های مختلفی از نرم‌افزاری که توسعه داده‌اند می‌گیرند اما این درحالی است که چنین سیاستی صرفاً منجر به پیچیده‌تر شدن کارها می‌شود! + +به‌عبارت دیگر، با چنین کاری تیم توسعه نسخه‌های تقریباً شبیه به همی تولید کرده که هریک از آن‌ها صرفاً در پلتفرم اختصاصی خودش می‌بایست دیپلوی گردد و همین مسأله ضریب خطا را بالا خواهد برد (مثلاً نسخهٔ توسعه‌ داده شده برای پلتفرم A روی پلتفرم B دیپلوی گردد یا بالعکس). + +در یک کلام، وقتی دست به توسعهٔ یک نرم‌افزار می‌زنید همواره تمام تلاش خود را به‌کار گیرید تا صرفاً یک نسخهٔ نهایی از نرم‌افزار داشته باشید که از مراحل تست گرفته تا بارگزاری روی سرور اصلی، تمامی کارها روی همان یک نسخه صورت می‌گیرد. + +حال ممکن است این سؤال پیش بیاید که یکسری تفاوت‌های مبتنی بر Environment وجود دارند که بایستی هندل شوند (منظور از Environment، پلتفرمی است که نرم‌افزار قرار است روی آن پیاده‌سازی گردد)؛ در پاسخ به این سؤال بایستی گفت که چنین تفاوت‌هایی را باید داخل همان Environment یا پلتفرم هندل کرد. + +حال ممکن است در زمان طراحی معماری نرم‌افزار آن‌قدر که باید و شاید دقت به‌خرج داده نشده باشد و برخی تنظیمات پیکربندی در سورس‌کد اعمال شده باشد که چنین مسأله‌ای مشکل‌زا خواهد شد؛ برای رفع چنین معضلی، می‌بایست تنظیمات پیکربندی کلی نرم‌افزار در فایلی مثلاً تحت‌عنوان global-config قرار داده شده و تنظیمات مرتبط با پلتفرمی که این نرم‌افزار قرار است روی آن پیاده‌سازی شود در فایلی مثلاً تحت‌عنوان env-config تا به‌سادگی بتوان نرم‌افزار را روی محیط‌های متفاوت به‌کار گرفت. diff --git a/fa/thing_62/README.md b/fa/thing_62/README.md new file mode 100644 index 00000000..b819c29f --- /dev/null +++ b/fa/thing_62/README.md @@ -0,0 +1,18 @@ +# فقط سورس‌کد است که حرف اول و آخر را می‌زند + +سورس‌کد باید آن‌قدر واضح و شفاف باشد که با نگاه کردن به آن، بتوان به ماهیت نرم‌افزار پی برد و این درحالی است که کامل‌ترین مستندات نرم‌افزار هم آن‌طور که بایدوشاید ماهیت نرم‌افزار را روشن نمی‌کنند و در این‌گونه مستندات صرفاً به یکسری کلیات بسنده می‌شود. + +در همین راستا، در حین کدنویسی همواره این سؤال را از خود بپرسید که آیا سورس‌کدتان به‌وضوح کامل چند و چون نرم‌افزار را هم برای خودتان و هم برای دیگر دولوپرها بیان می‌کند؟ + +در پاسخ به این سؤال ممکن است بگویید که کامنت‌های نوشته شده در جای‌جای سورس‌کد اطلاعات مورد نیاز را ارائه خواهند داد اما همواره به‌خاطر داشته باشید از آنجا که کامنت‌ها -همچون دیگر مستندات نرم‌افزار- در اجرای نرم‌افزار نقشی ندارند، می‌توانند حاوی اشتباهاتی باشند که ممکن است دولوپرها را گمراه سازند (این اشتباهات زمانی دوچندان می‌شوند که سورس‌کد ریفکتور شده، چیزی از آن کم شده و یا چیزی به آن افزوده گردیده اما درعین‌حال کامنت مدنظر آپدیت نشده است). + +کامنت‌ها اصلاً چیز خوبی برای شفاف‌سازی سورس‌کد نیستند! +اگر کدی که می‌زنید نیاز به کامنت دارد، در اولین فرصت اقدام به ریفکتور کردن کدتان کنید به شکلی که دیگر کد برای نشان دادن ماهیتش نیاز به کامنت نداشته و خود سورس‌کد گویای کاری باشد که قرار است انجام دهد. + +برای انجام چنین کاری هم صرفاً نیاز به چند تغییر کوچک خواهید داشت؛ از نام‌های مناسب و بامسمی برای کلاس‌ها، فانکشن‌ها، متغیرها و … استفاده کنید. ساختار فولدرها را به‌گونه‌ای بچینید که هارمونی بین بخش‌های مختلف پروژه وجود داشته باشد. کد را به‌گونه‌ای ریفکتور کنید که خواندن آن ساده‌تر گردد و کارهایی از این دست. + +همان‌طور که یک شاعر یا نویسنده به‌گونه‌ای اقدام به نوشتن یک شعر یا اثر ادبی می‌کند که سال‌ها پس از انتشار آن اثر -و حتی پس از مرگ پدید آورنده‌اش- بدون نیاز به هیچ‌‌گونه راهنما یا مفسری می‌توان آن اثر را درک کرد‌، یک دولوپر خوب هم به‌گونه‌ای کد می‌زند که خود سورس‌کد می‌تواند با دیگر دولوپرها ارتباط برقرار سازد. + +اگر چنین مواردی در کدنویسی رعایت شوند، زمانی‌که پروژه‌ٔ شما به‌اصطلاح Legacy می‌شود، دعای خیر دولوپرهایی که قرار است چنین پروژه‌ٔ قدیمی را مدیریت کنند همواره پشت‌ سر شما خواهد بود. + +نکته به‌طور‌کلی، منظور از سورس‌کدهای Legacy کدهایی است که خیلی قدیمی هستند و دیگر ساپورت نمی‌شوند. diff --git a/fa/thing_63/README.md b/fa/thing_63/README.md new file mode 100644 index 00000000..6059110c --- /dev/null +++ b/fa/thing_63/README.md @@ -0,0 +1,12 @@ +# فقط کد نزنید بلکه Build Process را نیز مدنظر قرار دهید + +دولوپرهایی هستند که تمام تمرکز خود را روی سورس‌کد اصلی نرم‌افزاری که درحال توسعهٔ آن هستند می‌گذارند و این درحالی است که برخی نرم‌افزارها هستند که برای اجرای کامل، نیاز به یکسری اسکرپیت‌های جانبی، پیکربندی‌ها و … دارند که در کنار یکدیگر منجر به ایجاد یک Build می‌شود. + +نکته در صنعت توسعهٔ نرم‌افزار، منظور از Build فرایندی است که از آن طریق سورس‌کد نرم‌افزار به برنامه‌ای قابل‌اجرا مبدل می‌گردد که به‌تنهایی قابل‌‌استفاده بوده و نتایج قابل‌مشاهده‌ای ارائه می‌دهد. +به‌طورکلی، Build بخشی مهم از فرایند توسعه است و درصورتی‌که این فرایند به درستی پیاده‌سازی نشود، سورس‌کد نرم‌افزار ارزشی نخواهد داشت! همان‌طور که قبلاً گفتیم، برخی نرم‌افزارها برای اجرای صحیح نیاز به یکسری اسکرپیت‌نویسی‌ها دارند که از آن جمله می‌توان به Bash Scripting در لینوکس اشاره کرد. + +اسکریپت‌نویسی معمولاًً به زبانی به غیر از زبان اصلی دولوپر صورت‌ می‌گیرد و همین مسأله منجر به این خواهد گشت تا دولوپرها خیلی تمایلی به این کار نداشته و این‌گونه اسکریپت‌نویسی‌ها را به دیگر اعضای تیم واگذار کنند! + +برخی دولوپرها هم بر این باورند که فرایند بیلد کار متخصصین کنترل کیفیت است اما واقعیت امر آن است که در حین کدنویسی،‌ تست نرم‌افزار هم می‌بایست صورت گیرد که با این‌کار هم می‌توان از صحت عملکرد نرم‌افزار اطمینان حاصل کرد و هم هزینه‌های توسعهٔ نرم‌افزار را کاهش داد. در یک کلام، Build Process بخشی از کار دولوپر است نه کسی دیگر! + +به‌طور خلاصه، آنچه دولوپرها می‌بایست همواره مدنظر داشته باشند این است که از آماده‌سازی پلتفرمی که نرم‌افزار قرار است روی آن اجرا شود تا پیکربندی و اسکریپت‌نویسی و غیره جزو وظایف یک دولوپر است که درنهایت منجر به این خواهد گشت که نرم‌افزار به‌طور کامل و بدون هیچ‌گونه نقصی اجرا گردد. diff --git a/fa/thing_64/README.md b/fa/thing_64/README.md new file mode 100644 index 00000000..2571875c --- /dev/null +++ b/fa/thing_64/README.md @@ -0,0 +1,15 @@ +# اهمیت برنامه‌نویسی دونفره + +یکی از چیزهایی که باعث ارتقاء تیم‌های برنامه‌نویسی می‌شود، Pair Programming یا «برنامه‌نویسی دونفره» است؛ اگر شما برنامه‌نویس تازه‌کاری هستید که زیردست یک برنامه‌نویس ارشد هستید، می‌بایست به‌معنای واقعی کلمه صبور بوده و از مواجهه با دولوپرهای باتجربه‌تر از خود ترس به دلتان راه ندهید چراکه ایشان به‌منزلهٔ منبع ارزشمندی از اطلاعات هستند که چیزهای بسیاری از آن‌ها می‌توانید یاد بگیرید. + +برنامه‌نویسی دونفره در تیم‌های نرم‌افزاری کمک به انتقال دانش مابین اعضای تیم می‌کند گرچه درظاهر ممکن است به‌نوعی اتلاف وقت تلقی گردد. برنامه‌نویسی دونفره مزایای بسیاری دارا است که در ادامه برخی از مهم‌ترین آن‌ها را برخواهیم شمرد: + +- برخی پروژه‌ها هستند که وابسته به یک دولوپر یا گروه خاصی از دولوپرها هستند و این درحالی است که اگر ایشان حضور نداشته باشند، روند پیشرفت پروژه نیز متوقف خواهد شد اما اگر برنامه‌نویسی دونفره در تیم توسعهٔ نرم‌افزار به‌کار گرفته شده باشد، همواره این امکان وجود دارد تا دیگر دولوپرها نیز بتوانند پروژه‌ای نیمه‌کاره را تکمیل نمایند. + +- وقتی تیم‌های توسعهٔ نرم‌افزار در پیاده‌سازی پروژه‌های مختلف از برنامه‌نویسی دونفره کمک بگیرند، چالش‌های پیش‌روی ایشان همواره سریع‌تر مرتفع می‌گردند چراکه مشکلات مابین اعضای مختلف تیم پخش شده و ممکن است هرکسی ایده‌ای منحصربه‌فرد برای رفع آن در ذهن داشته باشد و این درحالی است که اگر دولوپری به‌تنهایی قصد داشته باشد مشکلی را رفع کند، از دریافت ایده‌های سایر همکاران محروم خواهد شد. + +- همواره یکی از چالش‌های دولوپرهایی که قرار است روی پروژه‌ٔ سایر همکاران کار کنند، نامگذاری کلاس‌ها، فانکشن‌ها، متغیرها و … است اما اگر برنامه‌نویسی دونفره به شکلی اصولی به‌کار گرفته شود، این مشکل نیز تا حد قابل‌توجهی مرتفع خواهد شد زیرا تمامی دولوپرها روی بخش‌های مختلف پروژه اشراف داشته، با نحوهٔ نامگذاری دیگر همکاران آشنا بوده و درصورت بروز مشکل، می‌توانند روی کمک یکدیگر حساب کنند. + +- وقتی در تیمی از دولوپرها برنامه‌نویسی دونفره به‌کار گرفته شده باشد، دولوپرها دیگر نگران ددلاین‌های پروژه و عدم توانایی برای گرفتن مرخصی برای رسیدگی به‌ کارهای شخصی نخواهند بود چراکه دیگر اعضای تیم به‌سادگی قادر خواهند بود تا ادامهٔ پروژه را با همان سبک کدنویسی دولوپر سابق ادامه دهند. + +- در تیم‌های توسعهٔ نرم‌افزار همواره این احتمال وجود دارد که یکسری دولوپر جدید به تیم اضافه شده و یکسری دولوپر قدیمی تیم را ترک کنند و این درحالی است که اگر برنامه‌نویسی دونفره مابین اعضای تیم صورت گیرد، چالش‌های این آمدن و رفتن‌ها به حداقل خواهد رسید چراکه تک‌تک اعضای تیم با پروژه‌های مختلف آشنا شده و کسانی که تازه‌وارد هستند خیلی سریع با چند و چون پروژه‌ها آشنا شده و بالتبع با رفتن برخی دولوپرها، تازه‌واردها می‌توانند جای ایشان را با حداقل چالش پر کنند. diff --git a/fa/thing_65/README.md b/fa/thing_65/README.md new file mode 100644 index 00000000..7be13cce --- /dev/null +++ b/fa/thing_65/README.md @@ -0,0 +1,23 @@ +# آشنایی با تفاوت Static Typing و Dynamic Typing در برنامه‌نویسی + +پیش از هرچیز، به این نکته توجه داشته باشیم که در اینجا منظور از Type، نوع داده‌ای است که با آن سرورکار خواهیم داشت. به‌طورکلی، زبانی که به‌اصطلاح Statically Typed است در آن نوع متغیرها در زمان کامپایل شدن (Compile Time) برنامه‌ مشخص می‌گردد که از آن جمله می‌توان به زبان‌های جاوا، اسکالا، سی‌شارپ، سی و سی‌پلاس‌پلاس اشاره کرد و همین مسأله منجر به این خواهد گشت که پرفورمنس برنامه بالا رود چراکه هر دفعه که برنامه اجرا می‌گردد، دیگر نیازی به چک کردن نوع متغیرها نخواهد بود (لازم به‌ذکر است که این فیچر به‌عنوان یکی از برگ‌برنده‌های زبان‌هایی از این دست است). + +علاوه‌بر این، در این نوع زبان‌ها زمانی‌‌که دولوپر تایپی را برای یک متغیر درنظر می‌گیرد، دیگر قادر به تغییر آن نخواهد بود چراکه در این نوع زبان‌ها تایپ به متغیر اختصاص می‌یابد نه مقدار درنظر گرفته شده برای آن متغیر و درصورتی‌که تغییر تایپ صورت گیرد، با اکسپشن مواجه خواهیم شد. به‌عنوان نمونه در زبان جاوا داریم: +``` +String str = "Hello World"; +str = 7; +``` +همان‌طور که در کد فوق ملاحظه می‌شود، ابتدا متغیری از جنس String با مقدار Hello World ایجاد کرده‌ایم که در این صورت برنامه بدون هیچ مشکلی کامپایل خواهد شد اما در خط دوم، مجدد مقدار این متغیر را برابر با یک عدد صحیح درنظر گرفته‌ایم و از آنجا که تایپ عدد صحیح با تایپ استرینگ متفاوت است، در حین کامپایل شدن برنامه با اکسپشن مواجه خواهیم شد. + +یکی از خوبی‌های این نوع زبان‌ها این است که چک کردن برنامه توسط کامپایلر و در حین فرایند کامپایل شدن صورت می‌گیرد و بنابراین باگ‌های جزئی که ممکن است از دید پنهان بمانند خیلی زود یافت خواهند شد. + +زبانی هم که به‌اصطلاح Dynamically Typed است در آن نوع متغیرها در حین اجرای برنامه‌ (Run Time) مشخص می‌شود و دولوپر در حین کدنویسی نیازی به مشخص کردن دیتاتایپ‌ متغیر نخواهد داشت که از آن جمله می‌توان به زبان‌های پایتون، جاوااسکریپت و پی‌اچ‌پی اشاره کرد. + +علاوه‌بر این، در این نوع زبان‌ها پس از آن که تایپی برای یک متغیر درنظر گرفته شد، مجدد می‌توان تایپ آن متغیر را تغییر داد چراکه در این نوع زبان‌ها، دیتاتایپ به مقادیر متغیرها بر‌می‌گردد نه خود آن‌ها؛ به‌عنوان‌مثال، در زبان پی‌اچ‌پی داریم: +``` +$str = "Hello World"; +$str = 7; +``` +می‌بینیم که در خط اول متغیری تحت‌عنوان str$ ساخته‌ایم که حاوی مقدار Hello World است و در خط دوم هم این مقدار که پیش از این استرینگ بود را به یک عدد صحیح (Integer) تغییر داده و برنامه هم بدون هیچ مشکلی اجرا خواهد شد. + +به خاطر داشته باشید باتوجه به‌ این که در زبان‌های Dynamically Typed چک کردن دیتاتایپ‌ها در حین اجرا صورت می‌گیرد، برنامه‌های نوشته شده با این زبان‌ها تاحدودی مشکل پرفورمنسی دارند چراکه هردفعه در حین اجرا، فرایند چک کردن دیتاتایپ‌ها می‌بایست صورت گیرد. diff --git a/fa/thing_66/README.md b/fa/thing_66/README.md new file mode 100644 index 00000000..852bcc44 --- /dev/null +++ b/fa/thing_66/README.md @@ -0,0 +1,23 @@ +# تا حد ممکن از نمایش ارورها برای کاربر اجتناب کنید! + +پیام‌های خطا (Error Messages) یکی از رایج‌ترین راه‌های ارتباطی کاربران با سیستم پیش‌رویشان است و درواقع این پیام‌‌ها خبر از اتفاقی غیرمنتظره می‌دهند. + +آنچه در ارتباط با تعامل کاربران با یک سیستم نرم‌افزاری می‌بایست همواره مدنظر قرار داد این است که کاربران معمولاً به شکلی سیستماتیک و قابل‌پیش‌بینی منجر به ایجاد ارورها می‌شوند (به‌طورمثال، وارد کردن یک ورودی غیر عددی در فیلدی که صرفاً عدد می‌گیرد). از همین روی، به دلیل قابل‌پیش‌بینی بودن این نوع تعامل، به‌سادگی قادر خواهیم بود همان‌طور که سایر بخش‌های سیستم را دیباگ می‌کنیم، دست به دیباگ کردن نحوهٔ تعامل کاربران با سیستم نیز بزنیم. + +برای روشن‌تر شدن این مسأله، مثالی می‌زنیم؛ فرض کنیم یک فیلد ورودی داریم که صرفاً مخصوص دریافت تاریخ است آن‌هم در یک بازهٔ خاص؛ در چنین شرایطی، به‌جای آن که به کاربر اجازه دهیم تا هر تاریخی را وارد کند، به‌سادگی می‌توانیم طیفی از تاریخ‌هایی که مجاز هستند را درمعرض دیدش قرار داده تا وی یکی از آن‌ها را انتخاب کند. چنین کاری احتمال آن‌که کاربر تاریخی خارج از طیف مدنظر را وارد سازد کاهش داده و همین مسأله منجر به ایجاد تجربهٔ کاربری به‌مراتب بهتری می‌گردد. + +علاوه‌بر این، گاهی‌اوقات تنبلی دولوپرها هم منجر به سختی کشیدن بیشتر کاربران درحین استفاده از اپلیکیشن می‌شود. برای روشن‌تر شدن این مسأله، مجدد به مثال فوق بازمی‌گردیم؛ وقتی که کاربران با فیلدی که برای درج تاریخ درمعرض دیدشان قرار می‌گیرند مواجه می‌شوند، ممکن است تاریخ مدنظر خود را به‌صورت مثلاً 14-12-1390 وارد کنند اما این درحالی است که پس از ارسال دیتا برای سرور، صرفاً فرمتی همچون ۱۳۹۰/۱۲/۱۴ قابل‌قبول است و دادهٔ ورودی کاربر غیرقابل‌قبول تلقی می‌گردد. + +در چنین شرایطی، دولوپرها ۲ راه‌کار پیش‌رو دارند؛ راه‌کار اول این که انواع فرمت‌هایی که کاربر می‌تواند وارد کند را تفسیر کرده و در دیتابیس ذخیره سازند (مثلاً فرمت‌هایی همچون 14-12-1390 یا ۱۳۹۰/۱۲/۱۴ یا حتی بااستفاده از اسپیس و به‌صورت 14 12 1390) و راه‌کار دوم این که صرفاً یک فرمت را مدنظر قرار داده و اگر کاربری چیزی به غیر از آن‌را وارد ساخت، خیلی ساده یک پیام خطا درمعرض دیدش قرار دهند. + +از آنجا که راه‌کار دوم بار کدنویسی کمتری روی دولوپر دارا است، اکثر دولوپرها چنین راه‌کاری را انتخاب می‌کنند غافل از این‌که انتخاب چنین رویکردی باعث سردرگمی بیشتر کاربران می‌شود! + +حال اگر هم راه‌کار دوم مدنظر دولوپر باشد، بازهم راه‌کارهایی برای به حداقل رساندن خطاها از طرف کاربران وجود دارد؛ مثلاً به‌سادگی می‌توان لیبل‌هایی حاوی متنی مرتبط با فرمت مدنظر درمعرض دید کاربر قرار داد و یا ۳ فیلد مجزا یکی برای سال، یکی برای ماه و دیگری برای روز با لیبل‌های گویا و مشخص درنظر گرفت تا احتمال خطا را به حداقل رساند. + +به‌طورکلی، برخی دولوپرها هستند که دستورالعمل‌هایی برای نحوهٔ تعامل کاربر با اپلیکیشن درنظر می‌گیرند اما این درحالی است که بسیاری از این دستورالعمل‌های توسط کاربران اصلاً خوانده نمی‌شوند چراکه کاربران یا حوصلهٔ مطالعهٔ چنین دستورالعمل‌هایی را ندارند و یا فرض را بر این می‌گذارند که نحوهٔ تعامل با سیستم -باتوجه به تجربیات گذشتهٔ خود در تعامل با سرویس‌هایی مشابه- را بلد هستند. + +در همین راستا، توصیه می‌شود که به‌جای استفاده از دستورالعمل‌های نحوهٔ استفاده از یک سرویس، اصطلاحاً Hint در اختیار کاربران قرار گیرد. درواقع، تفاوت Hint (به‌معنی ایما، تذکر و اشاره) با Instruction (دستورالعمل) در این است که دستورالعمل‌ها همواره پیش از تعامل کاربر با سیستم در قالب یک پاپ‌آپ، پیام، باکس و … درمعرض دیدش قرار می‌گیرد اما این درحالی است که هینت‌ها درحین تعامل کاربر با سیستم چیزی را به وی گوشزد می‌کنند و به همین دلیل هم هست که اثربخش‌تر هستند (مثلاً وقتی که در یکی از فیلدهای فرمی کلیک می‌کنیم و پیامی درمعرض دیدمان قرار می‌گیرد، این پیام نوعی Hint است). + +راه‌کار دیگری که برای جلوگیری از وقوع ارورها می‌توان اتخاذ کرد این است که مثلاً در فیلدهای یک فرم از مقادیر دیفات (پیش‌فرض) استفاده کرد؛ در همان مثال فیلد مرتبط با تاریخ، می‌توان تاریخ روز را به‌صورت مقدار پیش‌فرض درنظر گرفت و این درحالی است که اگر تاریخ مدنظر کاربر تاریخ همان روز باشد که آن‌را دست‌نخورده باقی می‌گذارد و در غیر این صورت، می‌داند که فرمت مدنظر سیستم چیست و چگونه دیتا را می‌بایست وارد کند. + +به‌طورکلی، دولوپرها پیش از هرچیز می‌بایست به این درک برسند که کاربران هدفشان چگونه فکر می‌کنند و بر همین اساس هم سیستم را مطابق به نحوهٔ فکر کردن اکثر کاربران هدف طراحی کنند و همین مسأله منجر به بروز پیام‌های خطای کمتر و درنتیجه تجربهٔ کاربری بهتر از جانب کاربران می‌گردد. diff --git a/fa/thing_67/README.md b/fa/thing_67/README.md new file mode 100644 index 00000000..1368d6f0 --- /dev/null +++ b/fa/thing_67/README.md @@ -0,0 +1,15 @@ +# به چه برنامه‌نویسی حرفه‌ای می‌گویند؟ + +اصلی‌ترین خصیصهٔ یک برنامه‌نویس حرفه‌ای، مسئولیت‌پذیری است. برنامه‌نویسان حرفه‌ای مسئولیت کاری که انجام می‌دهند، پیش‌بینی‌هایشان، تعهداتشان و اشتباهاتشان را پذیرفته و تحت هیچ عنوان انگشت اتهام به‌سوی دیگر دولوپرها دراز نمی‌کنند. + +اگر دوست دارید برچسب حرفه‌ای روی شما بخورد، همواره می‌بایست مسئولیت کاری که انجام می‌دهید را بپذیرید؛ شما در قبال به‌روز بودن در حوزهٔ کاری خود و آخرین تکنولوژی‌های عرضه شده به بازار مسئول هستید. جالب است بدانید بسیار از دولوپرهای تازه‌کار هستند که بر این باورند وظیفهٔ کارفرمای ایشان است که به ایشان آموزش دهد که این تصور کاملاً اشتباه است! هیچ کارفرمایی آن‌قدر وقت و هزینه ندارد که شروع به آموزش و به‌روز کردن تک‌تک اعضای تیم توسعهٔ نرم‌افزار خود کند با علم به این که در آینده‌ای نه‌چندان دور، دولوپر خود را از دست خواهد داد (لازم به‌ذکر است که عمر دولوپرها در شرکت‌های نرم‌افزاری بیش از ۳ الی ۴ سال نیست). + +بازهم اگر دوست دارید حرفه‌ای دیده شوید، می‌بایست مسئولیت کدی که می‌زنید را ۱۰۰٪ قبول کنید. هیچ دولوپر حرفه‌ای را سراغ نداریم که پیش از اطمینان حاصل کردن از عملکرد کدش، آن‌را ریلیس کند. درواقع، دولوپرهای حرفه‌ای اصلاً واهمه‌ای از متخصصین QA (این اصطلاح مخفف واژگان Quality Assurance به‌معنی تضمین کیفیت است) ندارند چراکه می‌دانند ایشان هیچ باگی در کدی که ایشان نوشته‌اند نخواهند یافت. + +یکی دیگر از خصیصه‌های دولوپرهای حرفه‌ای این است که ایشان در کار تیمی (Team Work) مهارت دارند. ایشان مسئولیت خروجی کار کل تیم را برعهده می‌گیرند و تحت هیچ عنوان از زبان ایشان نمی‌شنویم که «من فقط فلان X رو نوشتم و این کد مال من نیست». دولوپرهای حرفه‌ای به دیگر همکاران خود -به‌خصوص کسانی‌که تازه‌کار هستند- کمک می‌کنند، به یکدیگر یاد می‌دهند، از همدیگر یاد می‌گیرند و در یک کلام، دیگران را ساپورت می‌کنند. + +برنامه‌نویسان که تصمیم گرفته‌اند جزو حرفه‌ای‌های صنعت کاری خود باشند، تحت هیچ عنوان لیست طولانی از باگ‌های موجود در نرم‌افزار را تحمل نمی‌کنند و به‌محض مواجه با یک باگ -خواه کوچک و خواه بزرگ- درصدد رفع آن بر‌می‌آیند. + +کدنویسی تمیز هم یکی دیگر از خصیصه‌های دولوپرهای حرفه‌ای است. کدی که یک دولوپر حرفه‌ای زده باشد در مقایسه با یک شخص غیرحرفه‌ای، بسیار تمیز با ساختاری قابل‌درک و درعین‌حال قابل‌ خواندن است. دولوپرهای حرفه‌ای همواره از استانداردهای کدنویسی (Best Practices) در حین کدنویسی استفاده می‌کنند و همین مسئله منجر به این خواهد گشت که دیگر دولوپرها در خواندن سورس‌کد ایشان به مشکل برنخواهند خورد. + +در یک کلام، حرفه‌ای‌ها جزو آدم‌های مسئول هستند؛ به‌عبارت دیگر، کسانی که مسئولیت کار خود را پذیرفته و سعی می‌کنند کدی بنویسند که بهینه بوده و به بهترین شکل کار کند. دولوپرهای حرفه‌ای زمانی که با کمبود وقت مواجه می‌شوند، هرگز بزن و برویی کد نمی‌زنند و تحت هیچ عنوان استانداردهای سفت و سخت کدنویسی خود را زیر پا نمی‌گذارند تا به ددلاین مدنظر برسند بلکه برعکس، در چنین شرایطی بیشتر به استانداردها پایبند می‌شوند چراکه می‌دانند در شرایط استراس‌زا، احتمال بروز خطا بسیار بالا خواهد بود. diff --git a/fa/thing_68/README.md b/fa/thing_68/README.md new file mode 100644 index 00000000..5045e292 --- /dev/null +++ b/fa/thing_68/README.md @@ -0,0 +1,25 @@ +# از ورژن کنترل غافل نشوید! + +یکی از نشانه‌های حرفه‌ای بودن در صنعت توسعهٔ نرم‌افزار، استفاده از Version Control است. گرچه درظاهر سوییچ کردن به ورژن کنترل کمی دشوار به‌نظر می‌آید اما پس از آن‌که مزایای چنین کاری بر دولوپرها -اعم از تازه‌کار و باتجربه- آشکار شد، ثابت می‌شود که یادگیری کار در چنین فضایی ارزشش را دارا است. + +از جمله پلتفرم‌های ورژن کنترل رایج می‌توان به Git و SVN اشاره کرد(لازم‌ به‌ذکر است که گیت توسط لینوس توروالدز -خالق کِرنِل لینوکس- طراحی شده است و امروزه به‌عنوان معروف‌ترین و محبوب‌ترین سیستم کنترل نسخه شناخته می‌شود). + +امروزه وب‌سایت‌های زیادی هم اقدام به ارائهٔ خدمات ورژن کنترل می‌کنند که از معروف‌ترین آن‌ها می‌توان به گیت‌هاب و گیت‌لب اشاره کرد (برای آشنایی بیشتر با نحوهٔ عمل‌کرد ورژن کنترل، می‌توانید به مقالهٔ ورژن کنترل (Version Control) چگونه کار می‌کند؟ مراجعه نمایید). + +زمانی که شما به ورژن کنترل مهاجرت می‌کنید، به‌سادگی می‌توانید به تاریخچه‌ای از تغییرات صورت گرفته در پروژه دسترسی یافته و مهم‌تر از آن، ببینید که کدام‌یک از اعضای تیم و در چه زمانی آن تغییرات را ایجاد کرده‌‌اند. باتوجه به این‌که کلیه‌ٔ تغییرات صورت گرفته در سورس‌کد، ریفکتورینگ‌ها، باگ فیکس‌ها و … تحت ورژن کنترل ذخیره می‌شوند، دولوپرها بدون هیچ‌گونه نگرانی و دغدغه‌ای می‌توانند دست به اعمال تغییرات در سورس‌کد پروژ‌هایش بزنند چراکه این اطمینان خاطر را دارند که نسخه‌های پیشین پروژه را ذخیره دارند. + +یکی از چیزهایی که در ورژن کنترل اهمیت دارد، تگ‌‌گذاری نسخه‌های مختلف پروژه است چرا که براساس همین تگ‌ها -که توصیه می‌شود براساس تاریخ باشند- در آینده به‌سادگی امکان جستجوی نسخهٔ خاصی از نرم‌افزار امکان‌پذیر می‌گردد. + +علاوه‌بر این، در ورژن کنترل مفهومی داریم تحت‌عنوان Branch (برنچ یا شاخه) که بااستفاده از آن می‌توان نسخه‌هایی موازی از پروژه‌ای واحد ایجاد کرد مثلاً یکی تحت‌عنوان Development (توسعه) و یک یا تعدادی برنچ دیگر تحت‌عنوان Maintanance (نگهداری) بدین شکل که کدنویسی پروژه روی برنچ توسعه صورت می‌گیرد و چنانچه پس از اعمال تغییرات و یا افزودن فیچر جدید به پروژه و ریلیس کردن آن نرم‌افزار و برخورد کردن به مشکلی خاص، به‌سادگی و درصورتی‌که نیاز به نسخه‌های قبلی باشد، می‌توان به یکی از برنچ‌های نگهداری مراجعه کرد. + +درصورتی‌که ورژن کنترل به‌درستی به‌کار گرفته شود، اصطکاک مابین دولوپرهایی که روی پروژه‌ای یکسان کار می‌کنند نیز به حداقل می‌رسد. درواقع، تغییرات صورت گرفته روی پروژه خیلی راحت به اطلاع تک‌تک دولوپرها رسیده و درصورتی‌که کانفلیکتی به‌وجود آید، به‌سادگی می‌توان آن‌را مرتفع ساخت. + +زمانی که قصد دارید پروژه‌ای را روی یک سرویس ورژن کنترل -مثل گیت‌لب که رایگان هم هست- قرار دهید، اصلاً خساست به‌خرج ندهید! به‌عبارت دیگر، تمامی فایل‌های پروژه از سورس‌کد گرفته تا تصاویر، مستندات، اسکمای دیتابیس + دیتای اولیه جهت تست، ابزارها و … را روی ورژن کنترل ارسال کنید (حتی توصیه می‌شود لایبرری‌ها که معمولاً به‌اصطلاح Ignore هستند و به‌صورت اتوماتیک روی سرور ارسال نمی‌شوند را هم آپلود کنید). با اتخاذ چنین رویکردی، این اطمینان حاصل می‌شود که همواره نسخه‌ای کامل از پروژه به‌صورت بکاپ در اختیار خواهیم داشت (فرض کنیم که سیستم‌عامل خود را تغییر می‌دهیم و یا کلاً سیستم‌مان عوض می‌شود که بااستفاده از چنین رویکردی، به‌راحتی می‌توان کل پروژه را از پلتفرم ورژن کنترل مدنظر گرفته و به‌کار خود ادامه داد). + +معرفی استراتژی‌های به‌منظور بهره‌وری بیشتر از Version Control +زمانی‌که شما به ورژن کنترل مهاجرت کردید و مزایای آن‌را درک نمودید، یکسری استراتژی‌ها و به‌اصطلاح Best Practice وجود دارد که چنانچه از آن‌ها پیروی کنید، می‌توانید اطمینان حاصل نمایید که از تمام پتانسیل یک سیستم ورژن کنترل استفاده می‌نمایید که عبارتند از: +1 - تغییرات اساسی در نرم‌افزار را در قالب یک Commit (کامیت) مجزا روی سرور بفرستید. چنانچه چند تغییر نامرتبط با یکدیگر را در قالب یک کامیت درنظر بگیرید، در آینده یافتن تاریخچهٔ پروژه کار دشواری خواهد شد. + +2 - برای هر کامیت، توضیحاتی واضح و شفاف درنظر بگیرید (اگر هم این کار برایتان دشوار است، حداقل توضیح دهید که چه‌چیزی را تغییر داده‌اید). این دست توضیحات می‌توانند در آینده چنانچه نیاز به نسخه‌های قبلی نرم‌افزار شد، بسیار مؤثر واقع شوند. + +3 - تحت هیچ عنوان کدی را قبل از تست کردن کامل و اطمینان حاصل کردن از این‌که نرم‌افزار به‌طور کامل کار می‌کند کامیت نکنید چراکه این‌کار در دراز مدت اعتبار شما در دید دیگر دولوپرهایی که روی پروژه کار می‌کنند را کم خواهد کرد. diff --git a/fa/thing_69/README.md b/fa/thing_69/README.md new file mode 100644 index 00000000..92d5e6ef --- /dev/null +++ b/fa/thing_69/README.md @@ -0,0 +1,9 @@ +# ماوس و کیبورد را کنار بگذارید! + +آیا تاکنون برایتان اتفاق افتاده که ساعت‌ها مشغول سروکله زدن با مشکل یا باگی بوده‌اید اما هیچ راه‌کاری به ذهنتان نرسیده، خسته شده و از پشت سیستم‌تان بلند شده تا کمی استراحت کنید یا چیزی بنوشید اما در کمال ناباوری ناگهان راه‌کار مدنظر به ذهنتان رسیده است؟ + +دلیلی که پشت این قضیه نهفته این است که وقتی شما درحال کدنویسی هستید، بخش منطقی مغز شما (سمت چپ مغز) فعال بوده و بخش احساسی مغز (سمت راست مغز) غیرفعال؛ مادامی‌که بخش منطقی مغز -که از قضا مسئول یافتن راه‌کار یا رفع باگ است- استراحت کافی نداشته باشد، هرگز قادر به کمک برای یافتن راه‌کاری مناسب نیست! + +درواقع، همان‌طور که پس از انجام کارهای فیزیکی مثل ورزش کردن و … بدن نیاز به استراحت دارد، پس از کارهای ذهنی مثل کدنویسی هم باید به عضوی از بدنمان که بیشترین درگیری را دارا است (مغز) استراحت دهیم که در غیر این‌ صورت راندمانش به‌طرز قابل‌توجهی کاهش خواهد یافت. + +به‌عنوان راه‌کاری عملی، می‌توان گفت که پس از گیر کردن در یافتن یک باگ و یا به‌طورکلی پس از چندین ساعت کدنویسی، کمی استراحت کردن شامل گوش دادن به موسیقی مورد علاقه،‌ نوشیدن چای یا قهوه و کارهایی از این دست می‌تواند انرژی مورد نیاز برای ادامهٔ کارمان را تأ‌مین سازد. به‌عبارت دیگر، گاهی‌اوقات بهترین روش حل مسأله، کنار گذاشتن ماوس و کیبورد است. diff --git a/fa/thing_70/README.md b/fa/thing_70/README.md new file mode 100644 index 00000000..6c60a354 --- /dev/null +++ b/fa/thing_70/README.md @@ -0,0 +1,20 @@ +# کدخوانی کنید! + +اکثر دولوپرها از کدزنی لذت می‌برند اما زمانی‌که پای کدخوانی به میان می‌آید، کمتر کسی را می‌توان یافت که از این کار لذت ببرد! از آنجا که کدزنی به‌مراتب لذت‌بخش‌تر از کدخوانی است و همچنین فرایند کدخوانی کاری سخت، طاقت‌فرسا و گاهی‌اوقات غیرممکن است، دولوپرها معمولاً تمایلی به انجام این کار ندارند مگر آن‌که مجبور شوند! + +به‌عنوان یک قانون کلی، معمولاً خواندن کدهایی که توسط دیگر دولوپرها نوشته شده است سخت است البته این بدان معنا نیست که دیگر دولوپرها کار خود را بلد نیستند بلکه این سختی بدین دلیل است که هیچ ۲ دولوپری همچون یکدیگر به یک Problem (مسأله) به شکلی یکسان نگاه نکرده و مشابه یکدیگر آن‌را حل نمی‌کنند. + +آیا کدخوانی منجر به بهبود کدنویسی می‌شود؟ +وقتی سورس‌کدی را می‌خوانید، همواره این سؤال را از خود بپرسید که آیا این فرایند راحت است یا دشوار؟ اگر پاسخ به چنین سؤالی «دشوار» بود،‌ بایستی بیابید که دلیل اصلی دشواری کدخوانی چیست، آیا فرمت‌ سورس‌کد مناسب نیست یا نامگذاری کلاس‌ها، متدها، متغیرها و … نامناسب است و یا این که زبان برنامه‌نویسی مدنظر به‌طورکلی دارای سینتکسی دشوار است! + +در چنین شرایطی می‌توان از اشتباهات دیگر دولوپرها درس گرفت به‌طوری‌که درحین کدنویسی، هرگز آن اشتباهات را مرتکب نشویم تا درنهایت سورس‌کدی که تحویل دیگر دولوپرها می‌دهیم، از دید ایشان سورس‌کدی حرفه‌ای، خوانا و قابل‌فهم باشد. + +اگر هم خواندن سورس‌کدی را «راحت» یافتیم، بازهم درس‌هایی می‌توان از آن آموخت. شاید از دیزاین پترنی استفاده شده که تاکنون از آن مطلع نبوده‌اید، شاید فانکشن‌ها کوتاه‌تر به‌همراه نامگذاری بهینه‌تری هستند و چیزهایی از این دست. + +به‌طورکلی، پروژه‌های اپن‌سورس فراوانی را در گیت‌هاب و دیگر پلتفرم‌ها می‌توان یافت که نمونه‌های خوبی از کدنویسی حرفه‌ای هستند که با دنبال کردن استراتژی‌های چنین دولوپرهایی، می‌توانیم خود را به یک Role Model برای دیگر دولوپرهای تازه‌کار مبدل سازیم. + +جالب است بدانید کدخوانی سورس‌کدهایی که چندین سال پیش نوشته‌ایم نیز می‌تواند درس‌های بسیاری برایمان به‌ ارمغان آورد بدین شکل که متوجه خواهید شد قدیمی‌ترین کدهایی که نوشته‌اید تحت هیچ عنوان مورد پسند شما -با استانداردهای کدنویسی کنونی‌تان- نیستند و گاهی‌اوقات هم اصلاً خوانا و قابل‌فهم نیستند! + +مشاهدهٔ چنین سیر پیشرفتی می‌تواند انگیزهٔ شما را دوچندان سازد و اگر هم می‌بینید که همان استانداردهای کدنویسی نامطلوبی که در گذشته استفاده می‌کرده‌اید درحال‌حاضر هم در کدهای شما موجود است، این زنگ خطری است که باید خیلی به آن توجه کنید. + +در یک کلام، هرموقع که تمایل داشتید مهارت‌های کدنویسی خود را ارتقاء بخشید، به‌جای شروع به خواندن یک کتاب آموزشی یا مراجعه به یک وب‌سایت آموزشی مرتبط با برنامه‌نویسی، می‌توانید شروع به خواندن سورس‌کد دیگر دولوپرهای حرفه‌ای نمایید. diff --git a/fa/thing_71/README.md b/fa/thing_71/README.md new file mode 100644 index 00000000..2adb0bce --- /dev/null +++ b/fa/thing_71/README.md @@ -0,0 +1,13 @@ +# تعاملات اجتماعی کلید موفقیت است! + +آدم‌ها با کمک دیگر آدم‌ها برای آدم‌های دیگر کدنویسی می‌کنند! شاید چنین جمله‌ای در نگاه اول کمی عجیب به‌نظر برسد، اما واقعیت دارد. درواقع، این جمله تأکیدش برروی ارتباط افراد با یکدیگر و کار گروهی است. + +از بشر اول تاکنون، آدم‌ها به این دلیل که بتوانند به بقای خود ادامه دهند، سعی کرده‌اند روی کمک یکدیگر حساب کرده و در گروه‌ها زندگی کنند و این درحالی است که امروزه هم که در عصر فناوری به‌ سر می‌بریم از این قاعده مستثنی نیستیم. + +با این حال، برخی از دولوپرها را می‌بینیم که به‌نوعی از جامعه بریده شده و در انزوا کد می‌زنند و این درحالی است که دیگر دولوپرهایی که اجتماعی‌تر بوده،‌ به کار تیمی اعتقاد دارند و قبل از آن‌که برنامه‌نویس باشند، یک «موجود اجتماعی» هستند می‌توانند علاوه‌بر زندگی شخصی، در حرفهٔ برنامه‌نویسی‌شان نیز بیشتر پیشرفت کنند. + +به‌طورکلی، دولوپرهایی که در پروژه‌های اپن‌سورس شرکت می‌کنند، در رویدادهای کدنویسی مشارکت دارند و دانسته‌های خود را با دیگر دولوپرهای غالباً تازه‌کار به اشتراک می‌گذارند، وبلاگ‌نویسی می‌کنند و به هر شکلی به تعامل با دیگر افراد می‌پردازند، تأثیر به‌مراتب بیشتری در صنعت نرم‌افزار می‌توانند داشته باشند. + +علاوه‌بر این، یک روی دیگر سکه هم کاربرانی است که قرار است از حاصل کدنویسی‌های دولوپرها استفاده کنند. در اینجا هم مجدد نیاز به تعاملات اجتماعی داریم؛ به‌عبارت دیگر، مادامی‌که دولوپرها به تعامل با کاربران هدف نرم‌افزار یا اپلیکیشن نپردازند، ایشان تحت هیچ عنوان نخواهند توانست به رفع باگ‌ها، بهبود نرم‌افزار و درنهایت رقم زدن یک تجربه‌ٔ کاربری عالی بپردازند. + +درنتیجه، همواره به‌خاطر داشته باشیم که در صنعت توسعهٔ نرم‌افزار تعملات اجتماعی همچون هر حرفه‌ٔ دیگری دارای اهمیت بسیار بالایی است؛ از تعامل ما مشتریان گرفته تا مدیر پروژه، تستر نرم‌افزار و دیگر دولوپرها، همواره می‌بایست روی مهارت ارتباطات و مذاکره کار کرده و در این حوزه هم علاوه بر مهارت‌های کدنویسی تسلط یابیم. diff --git a/fa/thing_72/README.md b/fa/thing_72/README.md new file mode 100644 index 00000000..a149f925 --- /dev/null +++ b/fa/thing_72/README.md @@ -0,0 +1,7 @@ +# تا حد ممکن دست به اختراع مجدد چرخ نزنید! + +شاید وقتی پای توسعهٔ نرم‌افزار به میان می‌آید بارهاوبارها شنیده باشید که «تا حد ممکن باید از کدهای موجود استفاده کرد و اختراع مجدد چرخ کار احمقانه‌ای است!» حال ممکن است این سؤال پیش بیاید که چرا در دنیای توسعهٔ نرم‌افزار دوباره‌ کاری این‌قدر بد دیده می‌شود؟ پاسخ به این سؤال و سؤالات دیگری از این دست بسیار ساده است و آن‌ هم چیزی نیست جز این که کدهای موجود کار می‌کنند و در یک کلام، آزمون خود را پس داده‌اند. + +اختراع مجدد چرخ صرفاً به این مسأله اشاره نمی‌کند که چگونه کدی بزنیم که نیاز ما را مرتفع سازد بلکه دارای ریزه‌کاری‌های بسیاری است که اگر ساده به این قضیه نگاه کنیم، شاید هیچ‌وقت متوجه آن‌ها نشویم! به‌طور مثال، سیستم‌هایی که پیش از این نوشته شده‌اند به‌طور کامل تست شده و توسط صدها دولوپر مورد استفاده قرار می‌گیرند و این درحالی است که به غیر از این‌ که کد کار می‌کند، در مورد مسائل فنی‌تر همچون پرفورمنس، معماری ساخت، الگوهای طراحی، توسعه‌پذیری و بسیار مسائل دیگر هم روی آن‌ها فکر شده است. + +وقتی دولوپری قصد دارد دست به اختراع مجدد چرخ بزند و این درحالی است که در مورد مسائل پیچیدهٔ توسعه‌ٔ نرم‌افزار -همچون مواردی که در بالا بدان‌ها اشاره شد- آگاهی ندارد، نتیجه این شده که نرم‌افزاری تولید می‌شود که کار می‌کند و نیازهای خود دولوپر یا مشتری‌اش را مرتفع می‌سازد اما به احتمال زیاد در آینده زمانی‌که بار زیادی روی نرم‌افزار بیاید، نیاز به توسعه یا ریفکتورینگ آن باشد یا قرار باشد با دیگر نرم‌افزارها ادغام شده و دیگر مسائلی از این دست، به مشکل خواهد خورد. diff --git a/fa/thing_73/README.md b/fa/thing_73/README.md new file mode 100644 index 00000000..c00ae8bf --- /dev/null +++ b/fa/thing_73/README.md @@ -0,0 +1,11 @@ +# تا حد ممکن از Singleton Pattern استفاده نکنید + +نیاز به توضیح نیست که Singleton Pattern مشکل‌گشای بسیاری از مشکلات شما در حین کدنویسی است؛ درواقع، زمانی که شما مطمئن باشید که فقط و فقط یک آبجکت از روی کلاس مدنظرتان نیاز خواهید داشت، می‌بایست از این الگو استفاده کنید اما این در حالی است که این تضمین باید وجود داشته باشد تا قبل از آنکه آن آبجکت مورد استفاده قرار گیرد، اصطلاحاً Initialize شده باشد. + +اما تجربه نشان داده است که این نوع دیزاین پترن (الگوی طراحی) بیش از آنکه مفید واقع گردد، باعث دردسر خواهد شد چراکه توسعهٔ کد در آینده را دچار مشکل می‌کند! + +یکی از دلایلی که دولوپرها به سمت استفاده از این الگوی طراحی می‌روند این است که در ابتدا فکر می‌کنند که مثلاً به کلاس X در کل پروژه صرفاً یک بار نیاز خواهند داشت اما این در حالی است که معمولاً پروژه‌های بزرگ نرم‌افزاری در طول زمان دستخوش تغییرات بسیاری شده و به مرور زمان نیازها دچار تغییر و تحول می‌گردند و چنانچه دولوپری بیش از حد روی این الگو حساب کرده باشد، ممکن است در آینده با مشکلات عدیده‌ای مواجه گردد. + +نکتهٔ دیگری که در ارتباط با الگوی طراحی سینگلتون وجود دارد این است که این الگو دیپندنسی‌هایی (Dependency یا وابستگی) میان ماژول‌های مختلف پروژه‌ٔ شما به صورت انتزاعی ایجاد می‌کند و همین مسأله مشکل‌زا خواهد شد چرا که از یک سو این وابستگی‌ها خیلی به‌وضوح قابل مشاهده نیستند و از سوی دیگر بخش‌های مختلف سورس‌کد را به یکدیگر وابسته می‌سازند و همین مسأله منجر به این خواهد گشت که در آینده به‌سادگی نتوانیم از سورس‌کد خود در سایر پروژه‌ها استفاده کنیم. + +چنین وابستگی‌هایی همچنین منجر به این خواهند شد که تست کردن نرم‌افزار با Unit Test که نیازمند وابستگی حداقلی مابین اجزای مختلف سورس‌کد است هم با مشکل مواجه شود. diff --git a/fa/thing_74/README.md b/fa/thing_74/README.md new file mode 100644 index 00000000..2233d18a --- /dev/null +++ b/fa/thing_74/README.md @@ -0,0 +1,7 @@ +# وابستگی‌های زیاد دشمن ریفکتورینگ هستند! + +در اغلب موارد، به‌ منظور دستیابی به پرفورمنس بیشتر، افزودن فیچرهای جدید و یا دیباگ کردن بخشی از نرم‌افزار بایستی کدها را دستکاری (ریفکتور) کرد اما این در حالی است که بخش‌هایی از کد که دارای Dependency (وابستگی‌) زیادی به دیگر بخش‌ها هستند تمام تلاش‌های ما را نقش بر آب خواهند کرد و هرچه این میزان وابستگی گسترده‌تر و ناواضح‌تر باشد، احتمال پی بردن به آن هم به‌ مراتب دشوارتر خواهد شد! + +به خاطر داشته باشیم که کدهای کثیف،‌ نامنظم و اسپاگتی هم اوضاع را بیش از پیش وخیم خواهند کرد به‌ طوری که وابستگی‌های زیاد در سورس‌کد به علاوهٔ کدهای اسپاگتی، یک تغییر کوچک که به نظر ۲ الی ۳ ساعت بیشتر زمان نمی‌برد، به یک فرایند دشوار، خسته‌کننده و گاهی‌اوقات غیرممکن چند هفته‌ای مبدل می‌سازد. + +برای جلوگیری از مشکلاتی این چنین، می‌بایست در حین طراحی معماری نرم‌افزار تا حد ممکن میزان وابستگی‌ها را به حداقل رساند. گرچه به صفر رساندن میزان وابستگی عملاً غیرممکن است، اما هرچه میزان وابستگی مابین بخش‌های مختلف سورس‌کد کمتر باشد، و یا این وابستگی‌ها حداقل در حوزهٔ یک ماژول باشند و نه بیشتر، ریفکتورینگ کد به مراتب راحت‌تر خواهد شد. diff --git a/fa/thing_75/README.md b/fa/thing_75/README.md new file mode 100644 index 00000000..c37f2707 --- /dev/null +++ b/fa/thing_75/README.md @@ -0,0 +1,7 @@ +# هرچه تعداد خطوط کد کمتر، بهتر! + +یکی از خصیصه‌های دولوپرهای تازه‌کار این است که به محض مواجه با یک مشکل و یا نیاز به افزودن یک فیچر جدید و دیگر کارهایی از این دست، سریعاً شروع به کدنویسی و افزودن بخش‌های جدیدی من‌جمله متغیرهای جدید، فانکشن‌های جدید و در یک کلام خطوط بیشتری به سورس‌کد می‌کنند که چنین خصیصه‌ای در نهایت منجر به حجیم شدن سورس‌کد و بالتبع پیچیدگی بیشتر آن می‌شود! + +چنین رویکردی در نهایت منجر به ایجاد سورسی می‌شود که بسیار پیچیده بوده و ریفکتور کردن آن در آینده، خواه توسط خود دولوپر و خواه توسط دیگر دولوپرها، کاری بس طاقت‌فرسا خواهد شد و کسی‌ که از خارج به چنین سورس‌کدی نگاه کند، به سادگی متوجه خواهد شد که توسط دولوپری غیرحرفه‌ای نوشته شده است. + +لذا در حین کدنویسی می‌بایست تمام تلاش خود را به کار بست تا حداقل تعداد متغیر، کلاس، فانکشن و در یک کلام، حداقل تعداد خطوط کد را داشت. diff --git a/fa/thing_76/README.md b/fa/thing_76/README.md new file mode 100644 index 00000000..19fc521c --- /dev/null +++ b/fa/thing_76/README.md @@ -0,0 +1,40 @@ +# آشنایی با قانون Single Responsibility + +یکی از خصیصه‌های معماری نرم‌افزاری خوب این است که «چیزهایی که ماهیت مشابهی داشته، به دلایل یکسانی دستخوش تغییر می‌شوند و در یک کلام، به یک خانواده تعلق دارند را باید در کنار یکدیگر قرار داد و الباقی را مجزا ساخت.» + +از دید فنی، به چنین قابلیتی Single Responsibility Principle (اصل تک وظیفه‌ای) یا به طور خلاصه SRP گفته می‌شود. به عبارت دیگر، این اصل حاکی از آن است که یک ماژول، کلاس، فانکشن یا هر چیزی می‌بایست وظیفه‌ای واحد داشته، متمرکز بر یک تسک بوده و صرفاً به یک دلیل تغییر یابند نه اینکه به محض مواجه با یک نیاز در هر بخشی از نرم‌افزار، نیاز داشته باشیم تا آن را دستخوش تغییر سازیم. برای روشن‌تر شدن این مسأله، کلاسی فرضی تحت عنوان Employee که دارای ۳ فانکش مختلف است را در نظر می‌گیریم: +``` C# +public class Employee +{ + public function calculatePayment(); + public function reportHours(); + public function save(); +} +``` +برخی برنامه‌نویسان بر این باورند از آنجا که این ۳ فانکشن به نوعی مرتبط با یکدیگر هستند، می‌بایست در قالب یک کلاس تعریف شوند اما این در حالی است که طبق قانون SRP، این ۳ فانکشن بنا به دلایلی کاملاً متفاوت ممکن است نیاز به تغییر کردن داشته باشند. برای مثال، فانکشن ()calculatePayment زمانی می‌بایست تغییر یابد که حقوق و مزیا کم‌ و زیاد شوند، فانکشن ()reportHours هم زمانی تغییر خواهد یافت که نحوهٔ گزارش‌دهی به مدیران تغییر کند و فانکشن ()save هم هر موقع که دیتابیس یا اسکمای برخی جداول تغییر یابد باید ریفکتور شود. + +می‌بینیم که ۳ دلیل مختلف برای تغییر یافتن فانکشن‌ها پیش‌ روی ما است و این باعث می‌گردد که کلاس Employee بنا به هر دلیلی و به خاطر تغییر در سیاست‌های مرتبط با هر یک از ۳ فانکشن زیرشاخه‌اش دستخوش تغییر قرار گیرد و نکتهٔ مهم‌تر اینکه اگر در دیگر بخش‌های کد وابستگی به این کلاس وجود داشته باشد و کلاس‌های دیگری از این کلاس ارث‌بری کرده باشند، آنها هم دستخوش تغییر خواهند شد! + +یک معماری نرم‌افزاری خوب آن است که ما سورس‌کد را به بخش‌های مجزایی تقسیم‌بندی کنیم که بتوان هر یک از آن‌ها را به‌ طور مجزا و بدون وابستگی به سایر بخش‌ها مورد استفاده قرار داد. به عبارت دیگر، اگر ما بخشی را تغییر دادیم، دیگر بخش‌ها نیاز به هیچ‌گونه تغییری نداشته باشند. + +اگر بخواهیم مجدد به مثال فوق بازگردیم، چنانچه کلاس Employee توسط دیگر کلاس‌های ماژول‌های مختلف پروژه استفاده شده باشد، بنابراین اعمال هرگونه تغییر در این کلاس، کلاس‌های دیگر را تحت‌الشعاع خود قرار خواهد داد که در بسیاری از مواقع منجر به ایجاد باگ می‌شود. حال اگر بخواهیم کلاس فوق را بر اساس قانون SRP ریفکتور کنیم، خواهیم داشت: +```C# +public class Employee +{ + public function calculatePayment(); +} + +public class EmployeeReporter +{ + public function reportHours(); +} + +public class EmployeeRepository +{ + public function save(); +} +``` +می‌بینیم که در کد فوق دارای ۳ کلاس مجزا از یکدیگر هستیم که هر کدام از آن‌ها متمرکز بر تسکی اختصاصی هستند. به عبارت دیگر، تمامی فانکشن‌های مرتبط با گزارش‌دهی را می‌توان در کلاس EmployeeReporter قرار داد، تمامی فانکشن‌های مرتبط با دیتابیس را در کلاس EmployeeRepository نوشت و هر آنچه که مرتبط با Business Rules (قوانین کاری) است را در کلاس Employee. + +پیاده‌سازی اصولی SRP می‌تواند ضامن معماری‌های نرم‌افزاری خوبی باشد که در آن‌ها میزان Dependency (وابستگی) به صورت حداقلی بوده و اعمال یک تغییر در کد، منجر به ایجاد باگ در سایر بخش‌ها نخواهد شد. + diff --git a/fa/thing_77/README.md b/fa/thing_77/README.md new file mode 100644 index 00000000..791de60e --- /dev/null +++ b/fa/thing_77/README.md @@ -0,0 +1,15 @@ +# همه‌ چیز با یک آری شروع می‌شود! + +از یک دید کلی می‌توان پرسنل فروشگاه‌های را به ۲ گروه مختلف تقسیم‌بندی کرد: گروهی از فروشندگان که نیمهٔ پر لیوان را می‌بینند و گروه مقابل که صرفاً روی نیمهٔ خالی متمرکز هستند! به نظر می‌رسد که برای روشن‌تر شدن این مسأله، باید از یک مثال روزمره کمک گرفت. + +وقتی که به یک فروشگاه زنجیره‌ای برای خرید می‌رویم، برخی فروشندگان هستند که وقتی سؤالی عجیب و غریب از ایشان می‌پرسیم، مثلاً نوعی شربت که بسیار کم‌مصرف است و فقط تعدادی فروشگاه خاص آن را عرضه می‌کنند، درخواست ما به عنوان یک مشتری را هرگز رد نکرده و فوراً با گفتن جمله‌ای همچون «خیر. متأسفانه ما این محصول را نداریم!» به قضیه فیصله نمی‌‌دهند بلکه این درخواست در ظاهر عجیب و غریب ما را به عنوان یک فرصت نگاه کرده،‌ اگر هم خودشان در این رابطه اطلاعی نداشته باشند از سایر همکارانشان کمک گرفته تا بلکه ایشان بتوانند راهنمایی کنند و در نهایت هم اگر کمکی از دست هیچ‌کس برنیاید، نام و مشخصات محصول مد نظرتان را گرفته تا برایتان تهیه کنند. + +در نقطهٔ مقابل این دست فروشندگان، گروهی دیگر قرار دارند که اصلاً مشتری‌مدار نیستند و صرفاً با گفتن جمله‌ای همچون «خیر. نداریم!» خود را خلاص می‌کنند. + +پس از این مقایسه، حال قصد داریم نگاهی به رویکرد دولوپرها در تعامل با دیگر همکارانشان بیندازیم. در واقع، از یک دید کلی هم می‌توان دولوپرها را به گروه‌بندی مشابهی همانند آنچه در فروشگاه‌های زنجیره‌ای وجود دارد تقسیم کرد. برخی دولوپرها هرگونه پیشنهاد، اعمال ویژگی جدید و به طور کلی هر درخواستی را به عنوان دردسر می‌بینند و تمام تلاش خود را به کار می‌بندند تا آن را در نطفه خفه کنند! + +در مقابل، برخی دولوپرها رویکردی به مراتب حرفه‌ای‌تر اتخاذ کرده و هرگونه پیشنهاد و درخواستی را به منزلهٔ فرصتی برای بهینه‌تر کردن نرم‌افزار یا اپلیکیشن و بهبود تجربه‌ٔ کاربری‌اش می‌بینند و این همان ویژگی‌ای است که یک دولوپر تمام عیار می‌بایست داشته باشد. + +خیلی از اوقات با بله گفتن به درخواست‌هایی که از طرف مدیرعامل، مدیر محصول، مدیر پروژه، مشتری و یا حتی کاربران می‌آیند، اصلاً نیازی به کدزنی قابل‌توجهی نیست بلکه با چند تغییر کوچک، می‌توان به درخواست ارسال شده جامعهٔ عمل پوشید. + +حال گاهی‌اوقات ممکن است با درخواست‌هایی مواجه شویم که در تضاد با استراتژی‌های توسعهٔ نرم‌افزار موجود است. اگر شما جزو آن دسته از دولوپرهایی هستید که ابتدا به ساکن کلمهٔ نه از زبانتان بیرون می‌آید، در چنین مواقعی سعی کنید سریع پاسخ ندادن را تمرین کنید و در صورت امکان، در حین فرایند تصمیم‌گیری به غیر از خودتان از دیگر اعضای تیم توسعهٔ نرم‌افزار هم بخواهید تا حضور داشته باشند تا بلکه بتوانند موضع‌گیری شما را تا حدی خنثی کنند و یا پاسخی منطقی در ارتباط با عدم امکان پیاده‌سازی قابلیت‌ مد نظر به طرف مقابل ارائه گردد. diff --git a/fa/thing_78/README.md b/fa/thing_78/README.md new file mode 100644 index 00000000..ada3d5ef --- /dev/null +++ b/fa/thing_78/README.md @@ -0,0 +1,13 @@ +# تا حد ممکن همه‌ چیز را خودکار کنید +اگرچه امروزه ابزارهای اتوماسیون توسعهٔ نرم‌افزار بسیار زیادی در اختیار دولوپرها قرار دارد، اما برخی از ایشان ترجیح می‌دهند که به جای استفاده از این ابزارها، کارها را به صورت دستی انجام دهند که شاید دلیل چنین مقاوتی، یکسری باورهای نادرست در مورد اتوماسیون باشد که مهم‌ترین آنها عبارتند از: + +باور نادرست ۱: اتوماسیون صرفاً برای تست است +گرچه Automation (اتوماسیون) بیش از هر جای دیگری در فرایند تست نرم‌افزار صورت می‌گیرد اما این در حالی است که اگر اسکریپتی بنویسیم که بسیاری از کارهای روزمهٔ ما همچون گزارش‌گیری، مستندسازی، کامپایل، دیپلویمنت و … را انجام دهد، به مراتب از کلیک‌های ماوس قابل‌اعتمادتر است. + +باور نادرست ۲: اگر از IDE استفاده کنیم، نیاز به اتوماسیون نداریم +IDEها دارای تنظیمات بسیار پیشرفته‌ای هستند که بسیاری از کارهای تکراری دولوپرها را انجام می‌دهند اما این در حالی است که به سختی می‌توان این تضمین را ایجاد کرد که در یک تیم توسعهٔ نرم‌افزار، تک‌تک دولوپرها از تنظیمات (Settings) یکسانی برخوردار باشند اما سیستم‌های اتوماسیون بیلدی همچون Ant (برای زبان برنامه‌نویسی جاوا)، iMacros و یا Selenium، به سادگی چنین امکانی را در اختیار ما قرار می‌دهند. + +باور نادرست ۳: برای این کار، باید کار با ابزارهای زیادی را یاد گرفت +شما با استفاده از زبان‌های اسکریپت‌نویسی شل همچون بش یا پاورشل به سادگی می‌توانید دست به نوشتن اسکریپت‌هایی بزنید که کلیهٔ کارهای شما را خیلی سریع انجام دهند. + +علاوه بر این، برای اسکریپت‌نویسی شما اصلاً نیازی به یادگیری زیر و بم زبانی همچون Bash و یا ابزارهایی که پیش از این معرفی شدند ندارید. در چنین مواقعی، به محض نیاز به انجام کاری، تکنیک‌های مرتبط با همان کار را با سرچ در وب و مطالعهٔ منابع مختلف یاد بگیرید و اصلاً زمان خود را روی یادگیری از ۰ تا ۱۰۰ ابزار مد نظر نگذارید! diff --git a/fa/thing_79/README.md b/fa/thing_79/README.md new file mode 100644 index 00000000..c6aa1420 --- /dev/null +++ b/fa/thing_79/README.md @@ -0,0 +1,9 @@ +# شنایی با مزایای ابزارهای تحلیل سورس‌کد + +در سال‌های اخیر شاهد آن بوده‌ایم که تست نرم‌افزار به بخشی لاینفک از فرایند توسعه مبدل شده است اما در عین حال، تست صرفاً یکی از ابزارهایی است که از آن طریق می‌توان کیفت کد را بهبود بخشید! + +از زمانی که زبان برنامه‌نویسی C یک پدیدهٔ تازه بود تا امروز که زبان‌های سطح‌بالای بسیاری وارد صنعت توسعهٔ نرم‌افزار شده‌اند، ابزارهای تحلیل کد روز به روز پیشرفت بیشتری کرده به طوری که امروزه این دست ابزارها قدرت تحلیل به مراتب بیشتری نسبت به نمونه‌های اولیهٔ‌شان دارند. + +مثلاً ابزاری همچون Pylint که برای تحلیل کدهای Python به کار می‌رود یا ابزار Splint برای زبان C، این امکان را به دولوپر می‌دهند که تنظیم کند چه نوع هشدارها، ارورها و خطاهایی در معرض دیدش قرار گیرند. + +به طور کلی، امروزه در کنار تست نرم‌افزار نیاز به فاز دیگری تحت عنوان تحلیل هم داریم تا این اطمینان را حاصل کنیم که کدها بهینه هستند، مقدار استفاده از منابع سیستمی در بهترین حالت ممکن قرار دارند و در نهایت کدی که نوشته شده است، بهترین کدی است که می‌توانست وجود داشته باشد! diff --git a/fa/thing_80/README.md b/fa/thing_80/README.md new file mode 100644 index 00000000..abc9de39 --- /dev/null +++ b/fa/thing_80/README.md @@ -0,0 +1,9 @@ +# در تست نرم‌افزار فقط رفتار مورد انتظار را بسنجید + +یکی از دام‌هایی که دولوپرها در حین تست نرم‌افزار در آن گرفتار می‌شوند این است که بر این باورند آنچه نرم‌افزار انجام می‌دهد دقیقاً همان تسکی است که قصد تست آن را دارند. گرچه در ظاهر چنین چیزی اصلاً دام تلقی نمی‌شود اما اگر کمی بیشتر این موضوع را بشکافیم، منظور واضح‌تر بیان گردد: یک اشتباه رایج در فرایند تست نرم‌افزار این است که تست را برای خصوصیات جانبی نسخهٔ مد نظر نرم‌افزار نوشت و این در حالی است چنین خصوصیاتی جانبی بوده و خیلی سنخیتی با رفتاری از نرم‌افزار که قصد سنجش آن را داریم ندارند! + +در چنین شرایطی، یعنی زمانی‌ که تست‌ها به گونه‌ای نوشته می‌شوند که با برخی خصوصیات جانبی نرم‌افزار هماهنگ شده باشند، اعمال تغییرات روی بخش‌هایی از نرم‌افزار که مرتبط با رفتاری است که قرار آن را تست کنیم، منجر به شکست تست می‌شود. در چنین شرایطی، دولوپرها معمولاً یا دست به ریفکتورینگ کد می‌زنند و یا تست را مجدد می‌نویسند که چنین کاری اوضاع را خراب‌تر می‌کند بلکه توصیه می‌شود مشکل ریشه‌ای حل گردد. + +برای روشن‌تر شدن این مسأله مثالی می‌زنیم. اگر تستی بنویسیم که علاوه بر سنجش رفتار نرم‌افزار، مثلاً جایگاه قرارگیری اِلِمان‌های روی صفحه را نیز بسنجد، اگر به هر دلیلی تغییری در رابط کاربری بدهیم و سپس نرم‌افزار را تست کنیم، تست ما با شکست مواجه می‌شود و این در حالی است که مد نظر قرار دادن چنین مسائل جانبی و به نوعی حاشیه‌ای، صرفاً به پیچیده‌تر کردن تست‌ها منجر شده و احتمال بروز شکست آنها را بیشتر خواهد کرد. + +با این تفاسیر، توصیه می‌شود که در حین نوشتن Unit Test، صرفاً رفتاری که از نرم‌افزار یا اپلیکیشن انتظار داریم را تست کنیم نه مسائل حاشیه‌ای که عملاً تغییری در رفتار اپلیکیشن ایجاد نمی‌کنند. diff --git a/fa/thing_81/README.md b/fa/thing_81/README.md new file mode 100644 index 00000000..bde6e762 --- /dev/null +++ b/fa/thing_81/README.md @@ -0,0 +1,22 @@ +# تست‌ها علاوه بر صحیح بودن، می‌بایست دقیق هم باشند +در آموزش قبل گفتیم که در حین فرایند تست نرم‌افزار، ضروری است که عملکرد مورد انتظار از نرم‌افزار را تست کرد تا اینکه خصوصیات جانبی و حاشیه‌ای نرم‌افزار که ربطی هم به عملکردش ندارند مورد ارزیابی قرار گیرند اما این در حالی است که این سوء‌تفاهم نمی‌بایست پیش بیاید که تست‌های نرم‌افزاری می‌توانند کلی و دقیق نباشند! به‌ عنوان یک قانون کلی، یک تست خوب می‌بایست دقت و درستی عملکرد کد را بسنجد. + +برای روشن‌تر شدن این مسأله، مثالی از دنیای واقعی برنامه‌نویسی می‌زنیم. الگوریتم سورت کردن یکسری داده (مثلاً از بزرگ به کوچک یا به ترتیب حروف الفبا) چیزی است که معمولاً دولوپرها با آن سروکار دارند. وقتی از دولوپری این سؤال پرسیده شود که هدف از تست چنین الگوریتمی چیست، پاسخی که معمولاً با آن مواجه می‌شویم این است که «داده‌ها باید به درستی یا از بزرگ به کوچک و با بالعکس سورت شوند». + +گرچه چنین پاسخی کاملاً درست است، اما تمام ماجرا نیست! در واقع، یک تست دقیق برای سنجش چنین الگوریتمی این‌گونه عمل می‌کند که پس از سورت شدن، طول عناصر آرایهٔ مد نظر می‌بایست با طول آرایه قبل از سورت شدن یکسان باشد. گرچه چنین دیدگاهی درست است،‌ اما باز هم کافی نیست! به عنوان نمونه داریم: +``` +3 1 4 1 5 9 +``` +خروجی زیر مجموعه اعدادی را نشان می‌دهد که هم از نظر طول با آرایهٔ اورجینال برابری می‌کند و هم اعداد از کوچک به بزرگ سورت شده‌اند: +``` +3 3 3 3 3 3 +``` +اما می‌بینیم که تک‌تک المان‌های آرایه در خروجی وجود ندارند. این مثال برگرفته از کدی واقعی است که خوشبختانه پیش از ریلیس، باگ آن رفع شد؛ در واقع،‌ مشکل از اینجا ناشی می‌شد که کل خروجی با اولین عضو آرایه (عدد ۳) پر می‌شد. + +پس ما می‌بایست تستی می‌نوشتیم که بسنجد کلیهٔ اعضای آرایه سورت شده، طول آن‌ها برابر با آرایهٔ اصلی باشد و از همه مهم‌تر، اعضا دقیقاً همان اعضای اورجینال باشند. + +اگر بخواهیم تستی به معنای واقعی کلمه حرفه‌ای بنویسیم، باز هم شرایط توصیف شدهٔ بالا کفایت نمی‌کنند! در حقیقت، یک تست خوب باید خوانا، قابل‌فهم و در عین حال ساده باشد تا یک تستر به سادگی بتواند متوجه شود که آیا نتیجهٔ آن درست است یا غلط به طوری که یک دولوپر صاحب‌نام به اسم Hoare در این باره می‌گوید: + +به‌طورکلی ۲ راه برای طراحی معماری یک نرم‌افزار وجود داره؛ راه اول این‌که آن‌قدر آن‌را ساده طراحی کنی که هیچ نقصی در آن وجود نداشته باشه و راه دوم این‌که آن‌قدر آن‌را پیچیده طراحی کنی که هیچ نقصی آشکارا در آن دیده نشه! + +با این تفاسیر، به این نتیجه می‌رسیم که تست نرم‌افزاری در صنعت برنامه‌نویسی که روز به روز شاهد اپلیکیشن‌های پیچیده‌‌تری در آن هستیم الزامی است اما این در حالی است که تست‌ها علاوه بر سنجش صحت نرم‌افزار یا اپلیکیشن، می‌بایست دقیق هم باشند. diff --git a/fa/thing_82/README.md b/fa/thing_82/README.md new file mode 100644 index 00000000..0bde86eb --- /dev/null +++ b/fa/thing_82/README.md @@ -0,0 +1,7 @@ +# تست نرم‌افزار و سورس‌کد را آخر شب‌ها و آخر هفته‌ها انجام دهید! + +یکی از مسائلی که باعث می‌گردد دولوپرها پیش از تست کردن تغییرات خود، اقدام به کامیت آنها روی یک سیستم ورژن کنترل همچون گیت کنند این است که معمولاً تست‌ها زمان قابل‌توجهی برای تکمیل شدن به خود اختصاص می‌دهند. به همین دلیل، توصیه می‌شود که از زمان‌هایی که کار نمی‌کنید، مثل شب‌ها و آخر هفته‌ها، برای کارهای اتوماسیون همچون تست‌های طولانی و زمان‌بر استفاده نمایید و به سادگی صبح روز بعد خواهید توانست نتایج، لاگ‌ها و غیره را مشاهده کنید. + +نکته‌ای که در ارتباط با تست نرم‌افزار در زمان‌های فوق‌الذکر وجود دارد این است که شبکه و همچنین سرورها در چنین زمان‌هایی بار و فشار زیادی رویشان نبوده و بالتبع با سرعت‌ بیشتری می‌توانند تسک‌های در نظر گرفته شده را تکمیل کنند. + +با انجام کمی محاسبات و برخورداری از دانشی نسبی در مورد اسکریپت‌نویسی، می‌توان به سادگی تعدادی کرون جاب ایجاد کرد تا تست‌های مدنظرمان را در شب‌ها، آخر هفته‌ها و دیگر روزهای تعطیل رسمی تکمیل کنند. diff --git a/fa/thing_83/README.md b/fa/thing_83/README.md new file mode 100644 index 00000000..261ac4bb --- /dev/null +++ b/fa/thing_83/README.md @@ -0,0 +1,7 @@ +# مقایسه‌ای مابین مهندسین نرم‌افزار و دیگر مهندسان + +مهندسانی همچون متخصصین راه و ساختمان، مکانیک‌ها و غیره در طول صدها سال بر اساس قوانین ریاضیات و فیزیک، به یکسری اصول و اصطلاحاً Best Practice دست یافته‌اند که می‌تواند ساخته‌‌های ایشان را ایمن سازد. به طور مثال، وقتی که یک مهندس راه و ساختمان پلی می‌سازد، تست آن پل بدین گونه خواهد بود که ماشینی با بار سنگین از روی آن عبور می‌دهند و چناچه پل بدون هیچ‌گونه لغزش و سستی پابرجا باقی بماند، این بدان معنا است که مهندسی به درستی کارش را انجام داده است. + +خوشبختانه یا متأسفانه در مهندسی نرم‌افزار تست محصول بدین گونه نخواهد بود چرا که ماهیت مهندسی نرم‌افزار با گونه‌های دیگر مهندسی کاملاً متفاوت است. وقتی پای اطمینان حاصل کردن از خروجی کار به میان می‌آید، هیچ‌وقت از یک مدیر پروژهٔ راه و ساختمان جمله‌ای همچون «ما زمان کافی برای تست این پل نداریم» نخواهیم شنید اما متأسفانه بسیاری از مدیران پروژه در صنعت توسعهٔ نرم‌افزار به خاطر وجود ددلاین‌های فشرده و گاهی‌اوقات غیرواقعی، اهمیت تست‌ نهایی نرم‌افزار را نادیده گرفته و تمام تمرکزشان روی این موضوع است که پروژه هرچه سریع‌تر به دست مشتری برسد. + +در چنین شرایطی، این وظیفهٔ دولوپرها است که تحت هیچ شرایطی زیر بار ریلیس کردن نرم‌افزار بدون تست کامل و جامع آن نروند. در واقع، تست نرم‌افزار نه تنها کافی نیست، بلکه ضروری هم هست و دولوپرهای حرفه‌ای می‌توانند با ابزارهای تستی که امروزه به بازار عرضه شده‌اند و بسیاری از کارهای دولوپرها را به صورت خودکار انجام می‌دهند خود را از دیگر دولوپرهای غیرحرفه‌ای متمایز سازند. diff --git a/fa/thing_84/README.md b/fa/thing_84/README.md new file mode 100644 index 00000000..89101b2b --- /dev/null +++ b/fa/thing_84/README.md @@ -0,0 +1,24 @@ +# از نوشتن کدهای اضافی پرهیز کنید + +فرض کنیم که در حال طراحی یک فروشگاه آنلاین بوده و درصدد هستیم تا بخش سبد خرید را کدنویسی کنیم. برای این منظور، کلاسی داریم تحت عنوان Order که حاوی متدهای مختلفی است من‌جمله ()isComplete که حاوی کدهای زیر است: +```C +function boolean isComplete() +{ + return isPaid() && hasShipped(); +} +``` +منطقاً یک سفارش قبل از اینکه پرداخت شود نمی‌تواند به دست مشتری برسد؛ لذا ()hasShipped نمی‌توان True باشد مگر اینکه ()isPaid برابر با True باشد و به خاطر همین مسأله است که بخشی از کد اضافی بوده و کد بالا را می‌توان به صورت زیر تغییر داد: +```C +function boolean isComplete() +{ + return hasShipped(); +} +``` +در تفسیر کدهای فوق بایستی گفت که به طور کلی، وقتی که در حال کار روی یک Order (سفارش) هستیم، ۳ وضعیت مختلف می‌تواند وجود داشته باشد: +- در جریان: مشتری می‌تواند آیتم‌هایی را به سبد خرید خود اضافه کرده و یا برخی موارد را حذف کند. +- پرداخت شده: مشتری دیگر نمی‌تواند آیتمی را حذف کند. +- ارسال شده: کار به اتمام رسیده است و هیچ‌گونه تغییری رخ نخواهد داد. + +در فرایند توسعهٔ نرم‌افزار، بسیاری مواقع پیش می‌آید که شاهد کدهای اضافی هستیم که این مسأله به خاطر عدم توجه به State (وضعیت) قرار گرفته در آن صورت می‌گیرد. به عبارت دیگر، ما می‌بایست ببینیم که در چه وضعیتی قرار داریم، سپس بسته به شرایطی که پیش روی ما است، فرایندها را تعریف کنیم. + +یکی از راه‌های خوب برای توجه به این مسأله، استفاده از متدهایی بامعنی، همچون چیزی که در بالا مشاهده کردیم، برای پیاده‌سازی دستوراتی است که مد نظر داریم. در یک کلام، به خاطر داشته باشیم که اگر فرایندی را روی تسکی در State (وضعیت) نادرستی انجام دهیم، کدهای ما منجر به ایجاد باگ‌ خواهد شد. diff --git a/fa/thing_85/README.md b/fa/thing_85/README.md new file mode 100644 index 00000000..dd463db2 --- /dev/null +++ b/fa/thing_85/README.md @@ -0,0 +1,18 @@ +# اهمیت برنامه‌نویسی دونفره در کدنویسی را هرگز نادیده نگیرید + +نیاز به توضیح نیست که کدنویسی نیاز به تفکر عمیقی دارد و تفکر عمیق هم در محیط‌های شلوغ امکان‌پذیر نبوده و نیازمند محیطی آرام و تنها است اما آنچه مسلم است اینکه در دنیای امروز فقط و فقط با تکیه بر داشته‌های خود نمی‌توان در حوزهٔ توسعهٔ نرم‌افزار به موفقیت‌های چندانی دست یافت و آشنایی با مهارت Team Work (کار گروهی) چیزی است که از دولوپرها، خواه فریلنسر باشند و خواه در تیم کد بزنند، انتظار می‌رود. + +اما به خاطر داشته باشیم که منظور از کار گروهی این نیست که به سؤالات دیگر دولوپرها پاسخ دهیم، در جلسات شرکت کنیم، ایده بدهیم و کارهایی از این دست بلکه منظور کلی این است که به شکلی کاملاً پویا و فعال به همکاری با دیگر اعضای تیم بپردازیم. + +در همین راستا، یکی از راه‌های پیاده‌سازی کار گروهی چیزی است تحت‌ عنوان Pair Programming (برنامه‌نویسی دونفره) که مزایای بسیاری برای هر دو دولوپر دارا است. اگر فرض را بر این بگذاریم که شما از همکارتان حرفه‌ای‌تر باشید، مسلماً با انتقال دانش خود منجر به ارتقاء مهارت‌های تیم توسعه خواهید شد و همچنین به توانایی‌های خود بیشتر واقف می‌گردید؛ اگر هم همکارتان از شما حرفه‌ای‌تر باشد، دیگر نیاز به توضیح نیست که این نوع کدنویسی می‌تواند در بالا بردن سطح مهارت‌های شما مفید واقع گردد. + +آنچه مسلم است اینکه نگاه هیچ ۲ دولوپری در حین فرایند توسعهٔ نرم‌افزار ۱۰۰٪ شبیه به یکدیگر نیست و همین مسأله اهمیت برنامه‌نویسی دونفره را دوچندان می‌سازد چرا که دولوپرها می‌توانند از زوایای مختلفی به مسألهٔ پیش‌رویشان نگاه کرده و بهترین راه‌کار را برایش اتخاذ کنند. + +حال بایستی از نقطه‌نظر مدیران شرکت‌های نرم‌افزاری هم به این قضیه نگاه کنیم؛ این دست مدیران که عموماً طرفدار مدیریت پروژه به سبک اجایل هستند بر این باورند که گماشتن ۲ دولوپر روی پروژه‌ای که ۱ دولوپر هم به خوبی از عهدهٔ آن برمی‌آید، کاری غیرمنطقی است! + +چنین دیدگاهی کاملاً درست و به‌جا است و ما هرگز نمی‌گوییم که «باید» همواره کلیهٔ پروژه‌ها را با گماشتن ۲ دولوپر پیاده‌سازی کرد اما در اینجا بحث بالا بردن کیفیت کار از یک سو و انتقال دانش و ارتقاء مهارت‌های تک‌تک اعضای تیم توسعهٔ نرم‌افزار از سوی دیگر است. + +نیاز به توضیح نیست که بازار کار همواره به دنبال بهترین دولوپرها است و اگر شرکت‌های نرم‌افزاری این شانس را داشته باشند که دولوپرهایی از این دست را به استخدام خود درآورده باشند، همواره بایستی این نگرانی را داشته باشند که روزی دولوپرهای درجه ۱ خود را از دست بدهند و این در حالی است که پیروی کردن از سیاست برنامه‌نویسی دونفره می‌تواند دانش، مهارت و تجربیات دولوپرهای حرفه‌ای تیم را تا حد امکان به دولوپرهای مبتدی‌تر انتقال دهد و چنانچه روزی برسد که دولوپر یا دولوپرهای حرفه‌ای تیم بخواهند شرکت را ترک کنند، می‌توان این اطمینان را داشت که بخش قابل‌توجهی از دانش ایشان با سایرین به اشتراک گذاشته شده است. + +چه نوع دولوپرهایی می‌بایست با یکدیگر در یک تیم قرار بگیرند؟ +اگر به طور مثال شما دولوپری مبتدی هستید، خیلی مهم است که در صورت داشتن امکان برنامه‌نویسی دونفره در شرکت به جای دولوپری مبتدی همچون خودتان، با فردی ماهرتر هم‌ گروه شوید اما بایستی به خاطر داشته باشیم که مهارت‌های فنی برای هم گروه شده صرفاً کافی نیستند بلکه فردی که قرار است هم گروه ما شود، می‌بایست از مهارت‌های برقراری ارتباط با دیگران و مربی‌گری نیز برخوردار باشد که در این صورت بهترین نتیجهٔ ممکن را خواهیم گرفت. diff --git a/fa/thing_86/README.md b/fa/thing_86/README.md new file mode 100644 index 00000000..f3bb48a7 --- /dev/null +++ b/fa/thing_86/README.md @@ -0,0 +1,12 @@ +# منفی در مفنی می‌شود مثبت! +دولوپرها به خوبی می‌دانند که سورس‌کد هیچ وقت دروغ نمی‌گوید اما این در حالی است که همین سورس‌کد گاهی اوقات تضادهایی دارا است و برخی از همین تضادها است که منجر به این سؤال می‌گردد «چه‌طور ممکنه با این شرایط نرم‌افزار کار کنه؟» + +یکی از دولوپرهای نرم‌افزار آپولو ۱۱ به نام Allan Klumpp در مصاحبه‌ای گفت که در این نرم‌افزار باگی وجود داشت که فرود آپولو را با مشکل مواجه می‌کرد اما این در حالی بود که باگی دیگری منجر به این شد که باگ اول خنثی گشته و این نرم‌افزار بدون هیچ مشکلی کار خود را انجام می‌داد و قبل از اینکه کشف گردد، در نرم‌افزار کنترل کنندهٔ موتورهای آپولو ۱۱ و آپولو ۱۲ مورد استفاده قرار می‌گرفت. + +برای روشن‌تر شدن این مسأله، فانکشنی را در نظر بگیرید که این وظیفه را دارا است تا استاتوس (وضعیت) چیزی را برگرداند. گرچه این فانکشن می‌بایست در شرایط خاصی مقدار True را باز گرداند، اما خروجی همواره False است. علاوه بر این، فانکشنی که این فانکشن را صدا زده، هرگز مقداری بازگشتی را چک نمی‌کند! در چنین شرایطی، همه چیز به خوبی کار می‌کند تا اینکه دولوپری به این قضیه پی‌ببرد. + +زمانی‌ که در سورس‌کدی ۲ باگ وجود داشته باشد که با همکاری یکدیگر منجر به این خواهند گشت تا نرم‌افزار در ظاهر بدون مشکل کار کند، وقتی یکی از باگ‌ها مرتفع گردد و باگ دیگر بابرجا باقی بماند، نرم‌افزار به مشکل برخواهد خورد. به عبارت دیگر، دولوپری که مسئولیت نگهداری کد را بر عهده دارد، ریپورتی دریافت می‌کند مبنی بر وجود باگی در سیستم؛ وی باگ را یافته و آن را رفع می‌کند اما مشاهده می‌شود که مشکل کماکان پابرجا است چرا که باگ دوم هنوز به قوت خود باقی است. در چنین شرایطی، وی باگ اول را به حالت اولیهٔ خود بازگردانده و کد را بررسی می‌کند تا به باگ دوم دست یابد و آن را فیکس می‌کند اما مشاهده می‌شود که مجدد مشکل نرم‌افزار پابرجا است. بنابراین مشکل دوم نرم‌افزار که ریفکتور شده بود را به حالت قبل بازمی‌گرداند و در چنین شرایطی دولوپر به دنبال یک باگ سومی می‌گردد که چیزی بیش از یک دور باطل نخواهد بود چرا که اصلاً باگ سومی در کار نیست! + +در چنین شرایطی، تعامل مابین ۲ باگ که منجر به ایجاد نتایج منتظره‌ای می‌شوند باعث می‌شود تا فرایند دیباگینگ نرم‌افزار بسیار دشوار گردد (جالب است بدانیم که چنین مسأله‌ای ممکن است در مستندات پروژه هم ایجاد گردد به طوری که اروری در کد با همکاری مشکلی در نوشتن مستندات پروژه دست به دست یکدیگر داده تا دولوپرها سردرگم شوند). + +در یک کلام، بایستی گفت که هیچ راه‌کار عملی برای موقعیت‌هایی اینچنین وجود ندارد و چنانچه دولوپری در موقعیت‌هایی از این دست قرار گیرد، می‌توان این انتظار را داشت که روزها و شاید هفته‌ها یا ماه‌ها درگیر فرایند دیباگینگ گردد. diff --git a/fa/thing_87/README.md b/fa/thing_87/README.md new file mode 100644 index 00000000..778c99df --- /dev/null +++ b/fa/thing_87/README.md @@ -0,0 +1,9 @@ +# کدنویسی تمیز و اصولی یک باید است + +وقتی دولوپری به تنهایی کد می‌زند، وی تفسیری شخصی از مسألهٔ پیش‌رو خواهد داشت و بالتبع هم راه‌کاری که اتخاذ می‌کند کاملاً شخصی خواهد بود. جالب است بدانیم گرچه برخی دیگر دولوپرها در یک تیم کار می‌کنند، اما باز هم ممکن است راه‌کارهایی که به کار می‌گیرند تکی و کاملاً شخصی باشند غافل از اینکه کدی که می‌نویسند، روزی می‌بایست توسط دیگر دولوپرها دیباگ شود، توسعه داده شود و یا نگهداری گردد. + +آنچه در مورد توسعهٔ نرم‌افزار امروزه خیلی مورد توجه نمی‌گیرد این است که برخی کدنویسی را صرفاً یک مهارت فنی تلقی می‌کنند اما این در حالی است که توسعهٔ نرم‌افزار ترکیبی از مهارت‌های فنی + مهارت‌های اجتماعی و ارتباطی است! + +زمانی که ما در یک تیم نرم‌افزاری کد می‌زنیم، بایستی توجه داشته باشیم که کیفیت کد ما می‌تواند کیفیت کد سایر دولوپرها را نیز تحت تأثیر خود قرار دهد. به عبارت دیگر، اگر یکی از اعضای تیم توسعه به کار با کیفیت اعتقاد نداشته باشد و یا آن‌طور که باید و شاید حرفه‌ای نباشد، این عدم مهارت وی می‌تواند سطح کدنویسی دیگر اعضای تیم را هم پایین بکشاند و این در حالی است که تأثیرات منفی این قضیه کل تیم را تحت‌الشعاع خود قرار خواهد داد. + +در واقع، وقتی که ما تمیز کدنویسی کنیم، سورس‌کدی که از ما به دیگر همکارانمان به ارث می‌رسد منجر به این خواهد گشت که ایشان هم با همان فرمان پروژه را ادامه دهند و این بدان معنا است که اگر ما خشت اول را درست بنا نهیم، این فرهنگ در میان تک‌تک اعضای تیم شکل خواهد گرفت که به کار باکیفیت، کدنویسی تمیز و اصولی پایبند باشند (البته عکس این موضوع هم کاملاً صادق است). diff --git a/fa/thing_88/README.md b/fa/thing_88/README.md new file mode 100644 index 00000000..03279d86 --- /dev/null +++ b/fa/thing_88/README.md @@ -0,0 +1,18 @@ +# ابزارهای یونیکسی دوست دولوپرها هستند! + +فارغ از اینکه با چه زبانی کد بزنیم، در چه حوزه‌ای به توسعهٔ اپلیکیشن بپردازیم و از چه ابزارهایی برای کدنویسی استفاده کنیم، برای دولوپرها استفاده از ابزارهایی که برای UNIX به بازار عرضه شده‌اند یک باید است. + +اگر بخواهیم به عمده‌ترین دلایل استفاده از ابزارهای یونیکسی اشاره کنیم، بایستی بگوییم که به طور مثال IDEها برای زبان‌های برنامه‌نویسی به‌خصوصی طراحی شده‌اند اما این در حالی است که ابزارهای یونیکسی برای هر چیزی کاربرد خواهند داشت. در عصری که سال به سال زبان‌های برنامه‌نویسی جدیدی به بازار عرضه می‌شوند، سرمایه‌گذاری روی ابزارهای جهان‌شمولی همچون «اپلیکیشن‌های یونیکسی» به منزلهٔ سرمایه‌گذاری در صرفه‌جویی زمان و انرژی دولوپر است. + +نکتهٔ دیگری که در ارتباط با تفاوت‌های یک IDE با یک UNIX Tool وجود دارد این است که معمولاً محیط‌های توسعهٔ یکپارچه (IDE) از یکسری کامندهای از پیش‌ تعریف شده برخوردارند که دولوپرها با استفاده از آنها به کدنویسی می‌پردازند،؛ اما دولوپرها با استفاده از ابزارهای یونیکسی می‌توانند محیط‌های توسعهٔ نرم‌افزار کاستومایز شدهٔ خود را ایجاد کنند و بسته به تمایلات شخصی خود، دست به ساخت محیطی بزنند که سرعت توسعهٔ ایشان را چند برابر کند. + +علاوه بر این، وقتی که ما به عنوان یک دولوپر کار با یک IDE را فرا می‌گیریم، کلیدهای میانبر، کامندها و غیره همگی اختصاصی همان نرم‌افزار هستند و این در حالی است که اگر روزی بخواهیم به نرم‌افزار دیگری مهاجرت کنیم، می‌بایست با یکسری کلید میانبر جدید آشنا شویم اما وقتی که ما با ابزارهای یونیکسی همچون کامندهای cat ،sed ،grep و غیره آشنا شویم، این ابزارها جهان‌شمول بوده و در هر جایی و هر سیستم‌عامل قابل استفاده می‌باشند. + +نکته البته به خاطر داشته باشیم که در IDEها به سادگی می‌توان کلیدهای میانبر را شخصی‌سازی کرد و همین مسأله منجر به این خواهد گشت که مهاجرت از یک نرم‌افزار به نرم‌افزاری دیگر خیلی چالش‌برانگیز نباشد. +جالب است بدانیم که ابزارهای UNIX در عصری ابداع شدند که یک سیستم چندکاربره (Multiuser) حافظهٔ رَمی برابر با ۱۲۸ کیلوبایت داشت و طراحان چنین ابزارهایی می‌بایست به بهینه‌ترین شکل ممکن به کدنویسی ابزارهای مد نظرشان می‌پرداختند تا با استفاده از کمترین منابع سیستمی، کار چنین کاربر را راه بیندازند. + +علاوه بر این، اگر کامندی را خیلی مفید یافتیم و یا کارمان به شکلی است که بارها و بارها می‌بایست از آن در حین فرایند کاری خود استفاده نماییم، به سادگی می‌توان کامند مد نظر را در قالب یک فایل بَش پکیج نموده و به عنوان یک نرم‌افزار کامندلاینی کوچک از آن استفاده نماییم. + +نکتهٔ دیگری که در ارتباط با ابزارهای یونیکسی که در سیستم‌عامل‌های مبتنی بر UNIX همچون لینوکس و مکینتاش وجود دارند این است که اکثر این ابزارها اپن‌سورس و رایگان هستند و همین مسأله میزان محبوبیت آنها را در میان دولوپرها دوچندان کرده است. + +در پایان هم بایستی گفت اگر هیچ‌کدام از ابزارهای یونیکسی عرضه شده به بازار نیازهای شما را مرتفع نمی‌سازند، با یادگیری Shell Scripting به سادگی قادر خواهید بود دست به کدنویسی ابزارهای اختصاصی خود بزنید. diff --git a/fa/thing_89/README.md b/fa/thing_89/README.md new file mode 100644 index 00000000..662c1c76 --- /dev/null +++ b/fa/thing_89/README.md @@ -0,0 +1,24 @@ +# استفادهٔ درست از الگوریتم‌ها و دیتا استراکچرها + +زمانی که استفاده از کامپیوترهای تجاری تازه فراگیر شده بودند، بانکی معروف با شعب مختلف که به تازگی استفاده از سیستم‌های کامپیوتری را در دستور کار قرار داده بود، از پرفورمنس سیستم‌هایش به شرکت نرم‌افزار شکایت کرده و تهدید کرده بود که اگر سرعت نرم‌افزاری که منجر به ایجاد صف‌های طولانی مشتریان می‌شد را بهبود نبخشند، قرارداد را فسخ خواهد کرد. + +شرکت‌ نرم‌افزاری هم چند متخصص و تحلیلگر به شعبه‌ٔ مرکزی بانک مذکور فرستاد تا ریشهٔ مشکل را بیابند و چیزی نگذشت که دریافتند کدی توسط مدیر آی‌تی خود بانک روی سیستم نوشته شده بود که در بک‌گراند به صورت کامندلاینی اجرا می‌شد و تقریباً می‌شود گفت تمام پتانسیل CPU را استفاده می‌کرد: +```C +for (i=0; i < strlen(s); ++i) { +if (... s[i] ...) ... +} +``` +در واقع، در تحلیل کد فوق بایستی گفت که استرینگ s به طور میانگین حاوی هزاران کاراکتر بود و با ایجاد یکسری تغییر در کد، مشکل بانک به سادگی حل شد! به عبارت دیگر، فراخوانی متد ()strlen تک‌تک هزاران کاراکتر موجود در s را شامل می‌شد و این در حالی بود که اگر دولوپر این کد از قبل طول این استرینگ را مشخص می‌کرد، می‌توانست هزاران فراخوانی متد ()strlen و بالتبع میلیون‌ها اجرای لوپ را از سیستم حذف کند. کد فوق به صورت زیر به سادگی بهینه شد: +```C +n = strlen(s); +for (i=0; i < n; ++i) { +if (... s[i] ...) ... +} +``` +برخی دولوپرها بر این باورند که استراتژی «اول کدی بنویس که کار کند، سپس آن را بهینه کن» خیلی عالی است اما می‌بینیم که گاهی‌اوقات -همچون مثال فوق- چنین ایده‌ای اصلاً کار نمی‌کند و سیستم را با مشکل مواجه می‌سازد. اینجا است که اهمیت استفاده از یک الگوریتم مناسب دوچندان می‌گردد. + +علاوه بر به‌کارگیری الگوریتم درست، دیتا استراکچر مناسب نیز می‌تواند پرفورمنس سیستم را به طرز قابل‌توجهی افزایش دهد. برای روشن‌تر شدن این مسأله مثالی می‌زنیم. فرض کنیم که قصد داریم اطلاعات کاربران خود شامل نام و نام خانوادگی، سن، جنسیت، شهر محل سکونت، تحصیلات و غیره را ذخیره ساخته تا در مواقع مختلف بر اساس معیارهای خاصی همچون سن، جنسیت، محل سکونت و غیره نوتیفیکیشن‌هایی را برای ایشان ارسال کنیم. + +مسلماً در چنین شرایطی استفاده از دیتا استراکچر مناسب نتیجهٔ بسیار مطلوبی برایمان در بر خواهد شد. به عبارت دیگر، استفاده از جدولی که در آن داده‌های مرتبط با کاربران به صورت اصطلاحاً Serialized شده ذخیره گردد اصلاً بهینه نبوده بلکه در عوض نیاز به جدولی خواهیم داشت که ستون‌های مورد نیاز به خوبی در آن ایندکس شده باشند. + +برخی بر این باروند که مهم‌ترین استراتژی در کدنویسی استفاده از کدهایی است که قبلاً نوشته شده است اما نکتهٔ مهم اینجا است که ما به عنوان یک دولوپر حرفه‌ای می‌بایست بدانیم که چه چیزی را چگونه و در چه زمانی استفاده کنیم (شاید مدیر آی‌تی بانک مذکور کد فوق را از داخل پروژه‌ای دیگر برداشته باشد که قرار بوده صرفاً تعداد کاراکتر معدودی به فانکشن ()strlen پاس داده شود که مسلماً در چنین شرایطی کد به خوبی کار می‌کرده است). diff --git a/fa/thing_90/README.md b/fa/thing_90/README.md new file mode 100644 index 00000000..0d09de53 --- /dev/null +++ b/fa/thing_90/README.md @@ -0,0 +1,9 @@ +# با لاگ‌گیری Verbose دچار دردسر خواهید شد! +لاگ گیری (Logging) به منزلهٔ بخشی مهم در فرایند توسعهٔ نرم‌افزار است. در واقع، این لاگ‌ها هستند که وقتی چیزی به درستی کار نمی‌کند، در فرایند مانیتورینگ نرم‌افزار چراغ راه دولوپر خواهند شد و تا حد ممکن وی را به سرچشمهٔ مشکل راهنمایی می‌کنند. در عین حال، در نظر داشته باشیم که همان‌قدر که نبود لاگ‌ها می‌توانند دولوپرها را فرایند دیباگینگ به دردسر بیاندازد، لاگ‌های غیرضروری و زیادی -اصطلاحاً Verbose- هم‌ می‌توانند آزاردهنده باشند! + +نکته به طور کلی، منظور از Verbose Loggin نوعی از لاگ‌گیری است که در آن اطلاعاتی بیش از آنچه لازم است ذخیره خواهیم ساخت (Verbose در لغت به معنای «استفاده از واژگان بیش از حد» است). در واقع، Verbose Loggin زمان به کار می‌آید که نیاز به موشکافی دقیق یک سیستم نرم‌افزاری داشته باشیم و بخواهیم آن را دیباگ کنیم و در حالت عادی غیرفعال می‌گردد چرا که منجر به ایجاد لاگ فایل‌های بسیار حجیم خواهد شد. +برای درک بهتر این مسأله، بایستی فرایند لاگ‌گیری نرم‌افزار را به علائم بیماری تشبیه کنیم. در حقیقت، ورم زیاد در ناحیهٔ شکم یک نوع علامت است و سرفه کردن هم‌ نوع دیگری از علائم بیماری. مسلماً کمتر کسی را می‌توان یافت که ورم ناحیهٔ شکم را جدی نگیرد و به آن بی‌توجهی کند چرا که از یک مشکل ساده در معده تا خدای ناکرده وجود یک غدهٔ سرطانی را می‌تواند شامل گردد اما این در حالی است که در بسیاری از مواقع، سرفه کردن صرفاً نشان از یک سرماخوردگی ساده دارد (البته همواره استثناء‌هایی وجود دارد). + +البته در نظر داشته باشیم که فرایند لاگ‌گیری به همین سادگی‌ها نیست. به طور مثال، سرویس‌هایی که در آنها از چندین زبان‌ برنامه‌نویسی مختلف،‌ لایبرری و فریمورک استفاده شده است،‌ فرایند لاگ‌گیری بسیار پیچیده و دشوار خواهد بود و در چنین شرایطی حتماً می‌بایست این نکته را هم مد نظر داشته باشیم که گاهی‌اوقات ارور ایجاد شده کاملاً خارج از حیطهٔ اختیارات ما است (مثلاً زمانی که از API یک وب‌سایت دیگر استفاده می‌کنیم،‌ در صورت بروز مشکل در سرورهای آن وب‌سایت، مسلماً سرویس ما هم تحت‌الشعاع قرار خواهد گرفت). + +برای این منظور، می‌توان ستونی تحت‌عنوان مثلاًً log_level در جدول مخصوص ذخیره‌سازی لاگ‌ها در نظر گرفته که سطح و نوع ارورهایی که سیستم با آنها دست و پنجه نرم‌ می‌کند را مشخص سازیم. به عبارت دیگر، سطوح پایین‌تر مثل سطح یک یا دو را به ارورهای قابل چشم‌پوشی و سطوح بالاتر از دو را به ارورهای جدی اختصاص داد و اینجا است که به سادگی فردی که مسئول مانیتور کردن سیستم است خواهد توانست مشکلات را در اسرع وقت رصد کند. diff --git a/fa/thing_91/README.md b/fa/thing_91/README.md new file mode 100644 index 00000000..e0279aad --- /dev/null +++ b/fa/thing_91/README.md @@ -0,0 +1,13 @@ +# درک تفاوت مفاهیم DRY و WET در کدنویسی بهینه + +در کدنویسی مفهومی داریم تحت عنوان DRY که مخفف واژگان Don't Repeat Yourself و به طور خلاصه این مفهوم حاکی از آن است که در کدنویسی هیچ‌گاه نمی‌بایست فانکشنی -یا به طور کلی کدی- که کار یکسانی انجام می‌دهد را دو بار بنویسیم. به عبارت دیگر،‌ در کدنویسی سیستم مد نظر، دوباره‌کاری ممنوع است. + +نقطهٔ مقابل DRY،‌ مفهوم دیگری است تحت عنوان WET که مخفف واژگان Write Every Time است. به عبارت دیگر، وقتی برای کار واحد یا یکسانی بیش از یک بار فانکشنی -یا به طور کلی کدی- را بنویسیم، سورس‌کد ما اصطلاحاً WET شده است. + +وقتی پای پرفورمنس (عملکرد) به میان می‌آید، تفاوت فاحشی مابین سورس‌کدهای به اصطلاح DRY و WET به میان می‌آید. برای روشن‌تر شدن این مسأله، مثالی می‌زنیم. + +فرض کنیم در سیستم خود فیچری داریم تحت عنوان X که مصرف CPU زیادی را به خود اختصاص می‌دهد و چیزی بیش از ۳۰٪ توان هستهٔ سیستم را مصرف می‌کند. حال مجدد فرض کنیم که این فیچر بیش از ۱۰ بار در جای‌جای نرم‌افزار به کار گرفته شده است که به طور میانگین، هر بار فراخوانی این فیچر ۳٪ از توان CPU را استفاده می‌کند. اینجا است که دولوپری که قصد دیباگ کردن چنین سیستمی را داشته باشد گمراه خواهد شد چرا که در نگاه اول ۳٪ کاملاً قابل‌ چشم‌پوشی است. + +اما اگر فرض کنیم که متوجه شدیم که مشکل از همین X می‌باشد، اینجا است که اگر از رویکرد WET استفاده کرده باشیم، از این پس بایستی به دنبال هر ده جایی که X در آن استفاده شده گشته و مشکل آنها تک به تک رفع کنیم اما این در حالی است که اگر از رویکرد DRY در کدنویسی پروژه استفاده کرده باشیم، صرفاً در یک جا کد را می‌بایست ریفکتور کرده و به یک‌باره ۳۰٪ بهبود پرفورمنس را مشاهده خواهیم کرد. + +به طور کلی، مزیت DRY نسبت به WET علاوه بر پرفورمنس بالاتر و سورس‌کد تمیزتر، امکان دیباگ کردن سریع‌تر سورس‌کد خواهد بود که این مسأله در پروژه‌های بزرگ بسیار حیاتی است. diff --git a/fa/thing_92/README.md b/fa/thing_92/README.md new file mode 100644 index 00000000..c6f0d937 --- /dev/null +++ b/fa/thing_92/README.md @@ -0,0 +1,9 @@ +# تعامل مابین دولوپرها و تسترها + +اگر بتوان در تیم‌های توسعهٔ نرم‌افزار فضایی ایجاد کرد که دولوپرها و تسترها به تعامل سازنده‌ای با یکدیگر بپردازند، این کار مزایای بسیاری در بر خواهد داشت که از جملهٔ مهم‌ترین آن‌ها می‌توان به این نکته اشاره کرد که به راحتی تفاوت مابین یک باگ و فیچر در ذهن دولوپرها و تسترها مشخص می‌شود، نیازی به استفاده از نرم‌افزارهای پیشرفتهٔ دیباگینگ وجود نخواهد داشت چرا که یک تستر واقعی نرم‌افزار را تست کرده است و مهم‌تر از همه اینکه محصول نهایی که به دست مشتریان می‌رسد، اصطلاحاً Bug Free (بدون باگ) خواهد بود. + +گاهی‌اوقات می‌شود پا را از این هم فراتر گذاشت و به عنوان یک تستر، حتی قبل از شروع کدنویسی یک فیچر جدید توسط دولوپرها، اقدام ارائهٔ روش‌های تست نرم‌افزار کرد به ایشان کرد (مثلاً اینکه نرم‌افزار به چه شکلی تست می‌شود) تا بر آن اساس، دولوپرها شروع به کدنویسی کنند و دغدغه‌های تسترها را در حین کدنویسی مد نظر داشته باشند. + +آنچه مسلم است اینکه دولوپرها و تسترها هرگز نباید یکدیگر را «دشمن» تلقی کنند بدین صورت که مثلاً تسترها تمام تلاش خود را به کار بندند تا اپلیکیشنی که توسط همکارانشان کدنویسی شده را هک کنند تا به ایشان ثابت کنند که کار خود را بلد نیستند؛ بلکه هدف ارتقاء کیفیت کار است. + +در واقع، از آنجا که هدف اصلی چیزی نیست جز ارائهٔ یک اپلیکیشن باکیفیت به مشتری، این تعامل مابین تک‌تک اعضای تیم به هرچه عملی‌تر شدن این پروسه کمک بیشتری خواهد کرد. diff --git a/fa/thing_93/README.md b/fa/thing_93/README.md new file mode 100644 index 00000000..79247117 --- /dev/null +++ b/fa/thing_93/README.md @@ -0,0 +1,13 @@ +# طوری کد بزنید که گویی قرار است تا آخر عمر سورس‌کدتان را ساپورت کنید! + +۹۶ چیزی که در این دورهٔ آموزشی مطرح شده یک طرف، پیاده‌سازی آنچه در ادامه می‌بینید طرف دیگر: + +طوری کد بزنید که گویی قرار است تا آخر عمر سورس‌کدتان را ساپورت کنید! + +در واقع، اگر بتوانیم در حین کد زدن چنین چیزی را رعایت کنیم، اتفاقات بسیار خوبی در انتظار ما خواهد بود. برای روشن‌تر شدن اهمیت این مسأله، اجازه دهید شرایط زیر را مد نظر قرار دهیم. + +فرض کنیم وقتی که با یک شرکت نرم‌افزاری به عنوان دولوپر قرارداد می‌بندیم، کارفرمای ما این اجازه را خواهد داشت که تا ۱۰ سال آینده، در هر ساعت از شبانه‌روز -مثلاً ۳ نیمه‌شب- با ما تماس گرفته و پشتیبانی طلب کند. + +صرفاً در چنین شرایطی است که ما در انتخاب نام کلاس‌ها، متدها و متغیرها تمام دقت را به خرج خواهیم داد تا نام‌هایی بامسمی انتخاب کنیم، فانکشن‌هایی نخواهیم نوشت که طول آنها صدها خط باشد، از دیزاین پترن‌ها به بهترین شکل ممکن استفاده خواهیم کرد،‌ کامنت‌گذاری اصولی خواهیم داشت و چیزهایی از این دست. + +به خاطر داشته باشیم کدی که ما به عنوان دولوپر می‌نویسیم، به نوعی جزو رزومهٔ ما محسوب می‌گردد و دیگر دولوپرهایی که با کدهای ما کار خواهند کرد، از روی نحوهٔ کدنویسی ما به میزان حرفه‌ای بودن ما نیز پی خواهند برد و در دراز مدت ایماژی مثبت یا منفی نسبت به ما شکل خواهد گرفت. diff --git a/fa/thing_94/README.md b/fa/thing_94/README.md new file mode 100644 index 00000000..04c4f995 --- /dev/null +++ b/fa/thing_94/README.md @@ -0,0 +1,7 @@ +# تا حد ممکن فانکشن‌های کوچک بنویسید + +وقتی که صحبت از اندازهٔ (Size) یک فانکشن یا تابع به میان می‌آید، منظور هم می‌تواند تعداد خطوطی که داخل فانکشن مد نظر نوشته شده باشد و هم تعداد تَسک‌هایی که آن فانکشن قرار است انجام دهد. + +گرچه هر دو موضوع از اهمیت بسزایی برخوردارند، اما تخصصی بودن فانکشن از اهمیت به مراتب بیشتری برخوردار است. در واقع، هرچه ما فانکشن‌هایی که می‌نویسیم تخصصی‌تر باشند، مدیریت سورس‌کد در آینده، خواندن کدها توسط دیگر دولوپرها و به حداقل رساندن وابستگی‌ها در سورس‌کد پروژه‌ٔ خود بیشتر و بیشتر می‌شود. + +به عبارت دیگر، هر فانکشن نباید بیش از یک تَسک (کار) را انجام دهد که در چنین حالتی می‌گوییم فانکشن مد نظر دارای قابلیت Single Responsibility است. diff --git a/fa/thing_95/README.md b/fa/thing_95/README.md new file mode 100644 index 00000000..f84f8530 --- /dev/null +++ b/fa/thing_95/README.md @@ -0,0 +1,18 @@ +# برای دولوپرها تست بنویسید نه برای ماشین‌ها! +اگر شما جزو دولوپرهایی هستید که در حین پیاده‌سازی پروژه‌های نرم‌افزاری اقدام به نوشتن Automated Test می‌کنید،‌ بایستی بدانید که این کار بسیار روند توسعهٔ نرم‌افزار شما را اثربخش می‌سازد و اگر هم جزو آن دسته از دولوپرهایی هستید که قبل از نوشتن کدهای اصلی، ابتدا به ساکن اقدام به نوشتن تست می‌کنید، بایستی به شما تبریک گفت؛ اما در عین حال سؤال اینجا است که آیا تست‌هایی که می‌نویسید خوب هستند؟ + +برای یافتن پاسخ به این سؤال، بایستی از خود بپرسید که «تست‌های نرم‌افزاری برای چه کسی نوشته می‌شوند؟» و چنانچه پاسخ به این سؤال چیزهایی همچون «برای خود دولوپر» یا «برای کامپایلر» باشد، این حاکی از آن است که تست‌های خوبی ننوشته‌اید! + +در حقیقت، یک تست نرم‌افزاری خوب تستی است که به منزلهٔ مستندات پروژه تلقی می‌گردد و حاکی از آنند که سورس‌کد چگونه کار می‌کند. در واقع تست‌ها: +- نقطهٔ شروع اپلیکیشن را به هر دولوپری نشان می‌دهند. +- کاربرد نرم‌افزار را برای هر دولوپری تشریح می‌کنند. +- نتایج قابل انتظار را به هر دولوپری نشان می‌دهند. + +بسته به نوع کاربرد، ما نیاز داریم تا تست‌های مختلفی بنویسیم. همچنین دولوپر دیگری که قرار است روی سورس‌کد ما کار کند، بایستی با مد نظر داشتن سه نکتهٔ فوق،‌ بتواند دقیقاً پی به نوع عملکرد نرم‌افزار ببرد. از سوی دیگر، هر تست نرم‌افزاری باید به وضوح رابطهٔ علت-معلولی مابین این سه بخش را شرح دهد. + +در حین طراحی تست‌های نرم‌افزاری، حتماً اسم‌هایی بامسمی‌ برای آنها در نظر بگیرید؛ از سوی دیگر، کاربرد هر تستی بایستی کاملاً مشخص باشد تا دیگر دولوپرها به منظور درک ماهیت تست، مجبور به مهندسی معکوس کردن نباشند. + +تست کردن تست‌ها +یک راه‌کار خوب برای اطمینان حاصل کردن از این که هم سورس‌کد اصلی و هم تست‌ها به خوبی کار می‌کنند، تست کردن تست‌ها است بدین صورت که از عمد باگ‌هایی در سورس‌کد اصلی پروژه ایجاد کرده و تست‌ها را اجرا کنید تا اطمینان حاصل کنید که باگ‌ها خیلی سریع توسط تست‌ها یافت می‌شوند. + +همچنین اطمینان حاصل کنید که اکسپشن‌ها و ارورهای معناداری در معرض دید دولوپر قرار می‌گیرد و دولوپر به سادگی با نگاه کردن به ارور، متوجهٔ ریشهٔ باگ خواهد شد. diff --git a/fa/thing_96/README.md b/fa/thing_96/README.md new file mode 100644 index 00000000..0d62202a --- /dev/null +++ b/fa/thing_96/README.md @@ -0,0 +1,17 @@ +# مراقب سورس‌کد باشید! + +بعید به نظر می‌رسد دولوپری را بتوان یافت که دوست نداشته باشد برچسب حرفه‌ای رویش بخورد. به طور کلی، به دولوپری می‌توان لقب حرفه‌ای داد که کدهای حرفه‌ای هم بنویسید؛ اگر هم بخواهیم کدی حرفه‌ای به نظر برسد، باید به نحوهٔ نوشتن آن توجه قابل‌توجهی کرد. + +کدنویسی حرفه‌ای و اصولی اصلاً ربطی به دانش فنی دولوپر ندارد. بسیار کسانی هستند که می‌توانند الگوریتم‌های بسیار پیچیده‌ای طراحی کنند اما زمانی که پای کدنویسی به میان می‌آید، کدهای بسیار زشتی می‌نویسند. به عبارت دیگر، درک، استفاده و ریفکتور کردن کدهای ایشان بسیار دشوار است. در مقابل، دولوپرهای تازه‌کار و حد متوسطی را هم می‌توان یافت که دانش فنی ایشان اصلاً به پای گروه فوق‌الذکر نمی‌رسد، اما کدهای ایشان در یک کلام عالی است. + +به نوعی می‌توان گفت که یکی از وجوه تمایز دولوپرهای عالی با سایر دولوپرها،‌ نگرش ایشان به کار است. این گروه از دولوپرها به خوبی با ضرب‌العجل (ددلاین) تحویل پروژه، محدودیت‌های فنی و غیره آشنایی دارند، اما در عین حال تمام تلاش خود را می‌کنند تا بهترین کدی که می‌شود را بنویسند. به طور کلی، اگر قصد دارید حرفه‌ای به نظر برسید، بایستی کدهای حرفه‌ای بنویسید و برای نوشتن کدهای حرفه‌ای هم می‌توانید استراتژی‌های زیر را مد نظر قرار دهید: + +- تحت هر شرایطی، صرفاً به کار کردن کد تحت شرایط عادی رضایت ندهید؛ بلکه تمام تلاش خود را به کار گیرید تا تمامی جوانب کار را بسنجید. در واقع، از سالم بودن کد (قابل اجرا بودن کد تحت هر شرایطی) اطمینان حاصل کنید. + +- کدی بنویسید که از یک سو هر دولوپر دیگری بتواند از آن سر در بیاورد و از سوی دیگر، قابل پشتیبانی و گسترش باشد. + +- امروزه کمتر دولوپر موفقی را می‌توان یافت که به تنهایی کار کند؛‌ اکثراً یا در شرکت‌های نرم‌افزاری مشغول به کار هستند و یا اگر هم در منزل روی پروژه‌های اپن‌سورس کار می‌کند، با دیگر دولوپرهای سراسر دنیا در تعامل هستند. در همین راستا، روی مهارت‌های ارتباطی خود با دیگر همکاران فنی/غیرفنی نیز کار کنید. + +- هر موقعی که با کدی برخورد کردید، تمام تلاش خود را به کار گیرید تا حتی اگر شده اندکی آن را بهبود بخشید (اگر توانستید که ساختار را بهبود بخشید و اگر امکان‌پذیر نبود، حداقل با کامنت‌گذاری درک آن را بهبود بخشید). + +- گرچه دولوپرها همواره در معرض تکنولوژی‌های جدیدی هستند اما این هرگز بدان معنا نیست که در هر پروژه‌ای باید از جدیدترین تکنولوژی‌ها استفاده کنید بلکه بایستی نیاز پروژه را درک کرده و بسته به ماهیت، نیازها و زیرساخت پروژه اقدام به استفاده از زبان‌ برنامه‌نویسی، لایبرری، فریمورک و یا ابزار مناسب کنید. diff --git a/fa/thing_97/README.md b/fa/thing_97/README.md new file mode 100644 index 00000000..946002d2 --- /dev/null +++ b/fa/thing_97/README.md @@ -0,0 +1,21 @@ +# منظور مشتریان شما چیزی نیست که می گویند! + +تجربه نشان داده است که مشتریان پروژه‌های نرم‌افزاری هرگز نمی‌دانند که چه می‌خواهند! گرچه گاهی‌اوقات ایشان اصلاً نمی‌دانند که چه می‌خواهند، اما در بیشتر مواقع ایشان می‌دانند که چه چیزی مد نظرشان است اما نمی‌توانند آن را به زبانی که برای دولوپر جماعت قابل‌فهم باشد بیان کنند. + +در واقع، همین که مشتریان جزئیات قابل‌توجهی را در حین مذاکرات با تیم توسعهٔ نرم‌افزار از قلم می‌اندازند، صدمات جبران‌ناپذیری به روند اجرای پروژه می‌زند. به طور مثال، ایشان فرض را بر این می‌گذارند که دولوپر/دولوپرها با ماهیت کاری ایشان، شرکت، نیازها، مخاطبین و چیزهایی از این دست آشنایی دارند. + +نکتهٔ دیگری که در این رابطه وجود دارد این است که اکثر مشتریان پروژه‌های نرم‌افزاری ابتدا به ساکن نمی‌دانند که چه کاربردهایی از نرم‌افزار مد نظرشان انتظار دارند و به مرور زمان ایده‌های جدیدی به ذهن ایشان می‌رسد. به عبارت دیگر، ایشان به خوبی Big Picture (تصویر کلی) از اپلیکیشنی که می‌خواهند را مد نظر دارند اما وقتی که پای جزئیات به میان می‌آید، هرگز دید روشنی از آنچه می‌خواهند ندارند. + +در نقطهٔ مقابل این دست مشتریان، گروهی دیگر از کارفرمایان هستند که می‌دانند چه چیزی نمی‌خواهند! در چنین شرایطی، یک دولوپر چگونه می‌تواند پی به واقعیت ماجرا ببرد تا در نهایت هم مشتری از چگونگی پیاده‌سازی پروژه راضی باشد و هم دولوپر احساس موفقیت پیدا کند؟ + +در یک کلام، بایستی گفت که تعامل بیشتر با یکدیگر منجر به این خواهد شد تا جزئیات بیشتری مابین کارفرما (مشتری) و مجری (دولوپر) رد و بدل گردد. + +وقتی پای مذاکره با مشتریان به میان می‌آید، همواره این نکته را مد نظر داشته باشید که ممکن است برخی از ایشان اصطلاحاً Technophobia (ترس از تکنولوژی) داشته باشند؛ لذا هرگز از Jargon (اصلاحات فنی) در مکالمه با ایشان استفاده نکنید و سعی کنید به ساده‌ترین شکل ممکن به صحبت با ایشان بپردازید. + +علاوه بر این، همواره این نکته را مد نظر داشته باشید که آنچه مشتری بر زبان می‌آورد، هرگز بدان معنا نیست که دقیقاً همان چیزی است که مد نظرش است! در همین راستا، هرآنچه بر زبان مشتری می‌آید را یک بار با استفاده از واژگان متفاوتی برایش بازگو کنید تا عکس‌العمل وی را جویا شوید. + +همچنین در صورت امکان و چنانچه قرار است برای مجموعه‌ای نرم‌افزار تولید کنید که بزرگ است، سعی کنید مسئله و نیاز آنها را از زبان چند شخص مختلف بشنوید تا از یکسان بودن دیدگاه‌ها و بالتبع پیدا کردن درک صحیحی از نیازهای ایشان اطمینان حاصل کنید (چنانچه چیزی که از زبان چند نفر می‌شنوید با یکدیگر در تضاد بود، شانس این را خواهید داشت تا ایشان را به قول معروف به جان یکدیگر بیندازید تا در نهایت مشخص شود که منظور کدام یک صحیح است). + +علاوه بر این، همواره مد نظر داشته باشید که برای برقراری ارتباطی مؤثر، می‌توانید در طول نشست از وایت‌بورد، نمودار، چارپ و غیره برای نشان دادن بهتر خروجی طرح استفاده کنید. + +تمامی این موارد به کنار، پس از عقد قرارداد دائماً مشتریان را در جریان روند پیشرفت پروژه قرار داده و در صورت امکان خروجی کار را در معرض دید ایشان قرار دهید تا چناچه علیرغم در نظر گرفتن نکات فوق کماکان سوء‌تفاهمی در انتقال نیازها صورت گرفته بود، بتوان قبل از این که خیلی دیر شود، تغییرات مد نظر را اعمال کرد. diff --git a/pt_br/thing_01/README.md b/pt_br/thing_01/README.md index af06397c..19854e37 100644 --- a/pt_br/thing_01/README.md +++ b/pt_br/thing_01/README.md @@ -2,14 +2,14 @@ > *"O que quer que você empreenda, aja com prudência e considere as consequências" Anon* -Não importa o queão confortável um cronograma parece no início de uma iteração, você não pode evitar estar sob pressão algumas vezes.Se vpcê se encontrar tendo que escolher entre "fazer certo" e "fazer rápido" geralmente é mais atraente "fazer rápido" sob o entendimento de que você vai voltar e consertar mais tarde. Quando você faz essa promessa para você mesmo, seu time, e seu cliente, é isso mesmo que você quer dizer. Mas muitas vezes a próxima iteração trás novos problemas e você acaba focando neles. Esse tipo de trabalho adiado é conhecido como débito técnico e não é seu amigo. Especificamente, Martin Fowler chama isso de débito técnico deliberado em sua [taxonomia de débito técnico](http://martinfowler.com/bliki/TechnicalDebtQuadrant.html), que não deve ser confundida com débito técnico inadvertido. +Não importa o quão confortável um cronograma pareça no início de uma iteração, você não pode evitar estar sob pressão algumas vezes. Se você se encontrar tendo que escolher entre "fazer certo" e "fazer rápido" geralmente é mais atraente "fazer rápido" sob o entendimento de que você vai voltar e consertar mais tarde. Quando você faz essa promessa para você mesmo, seu time, e seu cliente, é isso mesmo que você quer dizer. Mas muitas vezes a próxima iteração trás novos problemas e você acaba focando neles. Esse tipo de trabalho adiado é conhecido como débito técnico e não é seu amigo. Especificamente, Martin Fowler chama isso de débito técnico deliberado em sua [taxonomia de débito técnico](http://martinfowler.com/bliki/TechnicalDebtQuadrant.html), que não deve ser confundido com débito técnico inadvertido. -Débito técnico é como um empréstime: Você se beneficia disso no curto prazo, mas você tem que pagar juros sobre ele até que esteja totalmente pago. Atalhos no código tornam difícil de adicionar _features_ ou refatorar seu código. Eles são criadouros para defeitos e testes de caso que quebram fácil. Quanto mais você o mantiver, pior fica. No momento que você começa a realizar a correção original pode haver uma pilha inteira de "não muito corretas" decisões de design em camadas sobre o problema original, tornando o código muito mais difícil de refatorar e corrigir. De fato, muitas vezes apenas quando as coisas ficão tão ruins que você deve consertá-las, é que você realmente volta para consertar. E então muitas vezes é tão difícil corrigir que você realmente não pode pagar pelo tempo ou pelo risco. +Débito técnico é como um empréstimo: Você se beneficia disso no curto prazo, mas você tem que pagar juros sobre ele até que esteja totalmente pago. Atalhos no código tornam difícil de adicionar _features_ ou refatorar seu código. Eles são criadouros para defeitos e testes que falham com frequência. Quanto mais tempo você o mantiver, pior fica. No momento que você começa a realizar a correção original pode haver uma pilha inteira de decisões de design "não muito corretas" em camadas sobre o problema original, tornando o código muito mais difícil de refatorar e corrigir. De fato, muitas vezes apenas quando as coisas ficam tão ruins que você deve consertá-las, é que você realmente volta para consertar. E, então, muitas vezes é tão difícil corrigir que você realmente não pode pagar pelo tempo ou pelo risco. -Existem momentos que você deve incorrer ao débito técnico para cumprir um prazo ou implementar parte de uma _feature_. Tente não estar nessa posição, mas se a situação absolutamente demandar isso, vá em frente. Mas (e isso deve ser um grande MAS) você deve mapear o débito técnico e pagá-lo rapidamente ou as coisas irão rapidamente ladeira a baixo. Assim que você decidir se comprometer, escreva um cartão de tarefa ou registre isso no seu sistema de mapeamento de _issues_ para garantir que não seja esquecido. +Existem momentos que você deve criar débito técnico para cumprir um prazo ou implementar parte de uma _feature_. Tente não estar nessa posição, mas se a situação absolutamente demandar isso, vá em frente. Mas (e isso deve ser um grande MAS) você deve mapear o débito técnico e pagá-lo rapidamente ou as coisas irão rapidamente ladeira abaixo. Assim que você decidir se comprometer, escreva um cartão de tarefa ou registre isso no seu sistema de mapeamento de _issues_ para garantir que não seja esquecido. -Se vpcê programar o pagamento do débito na próxima iteração, o custo será mínimo. Não resolver o débito vai gerar um acúmulo de juros e esses juros devem ser mapeados para tornar o custo visível. Isso enfatizará o efeito sobre o valor de negócio do débito técnico do projeto and permitirá a priorização adequada do pagamento. A escolha de como calcular e mapear os juros vai depender do projeto em particular, mas você deve mapeá-lo. +Se você programar o pagamento do débito na próxima iteração, o custo será mínimo. Não resolver o débito vai gerar um acúmulo de juros e esses juros devem ser mapeados para tornar o custo visível. Isso enfatizará o efeito sobre o valor de negócio do débito técnico do projeto e permitirá a priorização adequada do pagamento. A escolha de como calcular e mapear os juros vai depender do projeto em particular, mas você deve mapeá-lo. Resolva o débito técnico assim que possível. Seria imprudente fazer o contrário. -Por [Seb Rose](http://programmer.97things.oreilly.com/wiki/index.php/Seb_Rose) +Por [Seb Rose's GitHub profile](https://github.com/sebrose) / [Seb Rose's LinkedIn Profile](https://www.linkedin.com/in/sebrose) diff --git a/ru/thing_02/README.md b/ru/thing_02/README.md index d2257822..56a8f64e 100644 --- a/ru/thing_02/README.md +++ b/ru/thing_02/README.md @@ -13,4 +13,4 @@ Оплачивайте технический долг как можно быстрее. Действовать по-другому было бы неосмотрительно. -Автор оригинала - [Seb Rose](http://programmer.97things.oreilly.com/wiki/index.php/Seb_Rose) \ No newline at end of file +Автор оригинала - [Seb Rose's GitHub profile](https://github.com/sebrose) / [Seb Rose's LinkedIn Profile](https://www.linkedin.com/in/sebrose) \ No newline at end of file diff --git a/ru/thing_03/README.md b/ru/thing_03/README.md index 233b597b..197766b9 100644 --- a/ru/thing_03/README.md +++ b/ru/thing_03/README.md @@ -4,13 +4,13 @@ Удручающе часто (в последний раз – буквально перед написанием этой статьи) программисты представляют процесс преобразования исходного кода в исполняемый файл как-то вот так: 1. Написать (или исправить) исходный код -- Скомпилировать исходный код в объектные файлы -- Происходит какое-то чудо -- Появляется исполняемый файл +2. Скомпилировать исходный код в объектные файлы +3. Происходит какое-то чудо +4. Появляется исполняемый файл На шаге 3, конечно же, происходит линковка. Что же меня в этом так раздражает? Я работал в техподдержке десятилетиями, и постоянно получаю вопросы вроде: -1. Линкер сообщает что переменная определена более одного раза +- Линкер сообщает что переменная определена более одного раза - Линкер сообщает что переменная является неразрешимым символом - Почему исполняемый файл такой большой. diff --git a/ru/thing_25/README.md b/ru/thing_25/README.md index cc03ae41..52334569 100644 --- a/ru/thing_25/README.md +++ b/ru/thing_25/README.md @@ -1,7 +1,7 @@ # Комментируйте лишь то, что не ясно из кода (В оригинале - Comment Only What the Code Cannot Say) -Различий между теорией и практикой гораздо больше на практике, чем в терории – это как нельзя более актуально применительно к комментариям. В теории идея комментариев заключается в том, чтобы «объяснить то, что происходит, дать больше деталей». Чем же желание объяснить может быть плохим? Однако на практике комментарии часто начинают приносить вред, а не пользу. Как и в любом другом деле, написание хороших комментариев – это умение. И значительная часть умения состоит в том, чтобы знать, когда их вообще писать не надо. +Различий между теорией и практикой гораздо больше на практике, чем в теории – это как нельзя более актуально применительно к комментариям. В теории идея комментариев заключается в том, чтобы «объяснить то, что происходит, дать больше деталей». Чем же желание объяснить может быть плохим? Однако на практике комментарии часто начинают приносить вред, а не пользу. Как и в любом другом деле, написание хороших комментариев – это умение. И значительная часть умения состоит в том, чтобы знать, когда их вообще писать не надо. Если в коде есть ошибки, то компилятор, интерпретатор или другой подобный инструмент это сразу же обнаружат. Если ошибки есть на функциональном уровне, то ревью, статический анализ, тестирование и эксплуатация рано или поздно будут приводить к их обнаружению и устранению. А комментарии? В книге *“The Elements of Programming Style”* Kernighan и Plauger заметили, что «комментарий имеет нулевую или отрицательную ценность, если он неправильный». И такие комментарии часто сильно засоряют исходный код, оставаясь там долгое время, в отличие от ошибок в самом коде. При этом такие комментарии постоянно приводят к отвлечению внимания или даже к дезориентации того, кто этот код сопровождает. @@ -13,4 +13,4 @@ Комментируйте лишь то, что код не может сообщить в принципе, а не то, что он не сообщает сейчас. -Автор оригинала - [Kevlin Henney](http://programmer.97things.oreilly.com/wiki/index.php/Kevlin_Henney) \ No newline at end of file +Автор оригинала - [Kevlin Henney](http://programmer.97things.oreilly.com/wiki/index.php/Kevlin_Henney) diff --git a/ru/thing_30/README.md b/ru/thing_30/README.md index b4fe915b..6e91fa04 100644 --- a/ru/thing_30/README.md +++ b/ru/thing_30/README.md @@ -15,7 +15,7 @@ } ``` -Выглядит логично, не так ли? Однако если даже выражение красиво завернуто в метод вмето того, чтобы быть множество раз скопипасченым по всему коду, этого выражения не должно было вообще быть. То, что оно существует, показывает наличие проблемы. Почему? Потому что заказ не может быть доставлен, пока он не будет оплачен. Поэтому `hasShipped` не может стать true до того, как `isPaid` станет true, что делает выражение избыточным. Возможно, вы все равно захотите оставить метод `isComplete` для ясности кода, но он должен при этом выглядеть вот так: +Выглядит логично, не так ли? Однако если даже выражение красиво завернуто в метод вмеcто того, чтобы быть множество раз скопипасченым по всему коду, этого выражения не должно было вообще быть. То, что оно существует, показывает наличие проблемы. Почему? Потому что заказ не может быть доставлен, пока он не будет оплачен. Поэтому `hasShipped` не может стать true до того, как `isPaid` станет true, что делает выражение избыточным. Возможно, вы все равно захотите оставить метод `isComplete` для ясности кода, но он должен при этом выглядеть вот так: ``` public boolean isComplete() { @@ -23,9 +23,9 @@ } ``` -Я много раз сталкивался как с пропущенными проверками, так и с избыточными. Этот пример крошечный, но если вы добавите отмену и повторную оплату, все станет гораздо сложнее, и необходимость правильной обработки состояний повысится. В данном случае, аказ может быть лишь в трех состояниях: +Я много раз сталкивался как с пропущенными проверками, так и с избыточными. Этот пример крошечный, но если вы добавите отмену и повторную оплату, все станет гораздо сложнее, и необходимость правильной обработки состояний повысится. В данном случае, заказ может быть лишь в трех состояниях: -1. *Формируется:* можно добавлять или удалять покупки, нельзя доставлять; +- *Формируется:* можно добавлять или удалять покупки, нельзя доставлять; - *Оплачен:* нельзя добавлять или удалять покупки, можно доставлять; - *Доставлено:* заключительное состояние, никаких изменений. @@ -35,4 +35,4 @@ Если вы обнаружили, что находитесь в неразрешенном состоянии, значит, произошла ошибка и вы рискуете потерять все данные, если не остановите выполнение. Если постоянные проверки состояния будет вносить слишком много шума, изучите возможность использования автоматической генерации кода или аспектного программирования (weaving), чтобы скрыть их. И независимо от того, какой механизм вы выберете, мышление категориями состояний поможет вам сделать ваш код более простым и надежным. -Автор оригинала - [Niclas Nilsson](http://programmer.97things.oreilly.com/wiki/index.php/Niclas_Nilsson) \ No newline at end of file +Автор оригинала - [Niclas Nilsson](http://programmer.97things.oreilly.com/wiki/index.php/Niclas_Nilsson) diff --git a/ru/thing_31/README.md b/ru/thing_31/README.md index 4fd8ddf1..30447f97 100644 --- a/ru/thing_31/README.md +++ b/ru/thing_31/README.md @@ -7,7 +7,7 @@ Лучший способ выяснить, как именно действуют пользователи, это понаблюдать за одним из них. Попросите пользователя выполнить какую-нибудь задачу при помощи ПО, похожего на разрабатываемое вами. Задача должна быть реальной. «Добавьте колонку с цифрами» - нормально. «Посчитайте свои расходы за прошлый месяц» - гораздо лучше. Избегайте слишком конкретных задач вроде «Вы можете выделить эти ячейки в ввести формулу суммы внизу?». Пусть пользователь говорит во время выполнения, не прерывайте его и не пытайтесь помочь. Спрашивайте себя «почему он делает так» и «почему он не делает так». -Первая вещь, которую вы заметите – это то, что пользователи делают большинство вещей одинаково. Они пробуют выполнить различные задачи одним и тем же способом, при этом делая одни и те же ошибки в одних и тех же местах. И вы должны проектировать вокруг их этого основного поведения. Это отличается от совещаний, на которых люди обсуждают вопросы из серии «А что если пользователь захочет сделать вот так?», и которые приводят к решениям, вызывающим замешательство пользователей. Наблюдение за пользователями устраняет это замешательство. +Первая вещь, которую вы заметите – это то, что пользователи делают большинство вещей одинаково. Они пробуют выполнить различные задачи одним и тем же способом, при этом делая одни и те же ошибки в одних и тех же местах. Вы должны проектировать ПО с учетом этого основного поведения. Это отличается от совещаний, на которых люди обсуждают вопросы из серии «А что если пользователь захочет сделать вот так?», и которые приводят к решениям, вызывающим замешательство пользователей. Наблюдение за пользователями устраняет это замешательство. Вы можете увидеть, как пользователь зайдет в тупик. Когда вы в тупике, вы смотрите по сторонам. Когда пользователь в тупике, их фокус внимания сужается. Для них становится сложным найти решение где-то на экране. И это одна из причин, почему стандартный хелп – не самое лучшее решение. Если вам необходима текстовая помощь или инструкции, постарайтесь разместить их непосредственно вблизи зоны концентрации вашей задачи. Сужение фокуса внимания пользователя – одна из причин, почему всплывающие подсказки намного лучше, чем помощь в меню. @@ -15,4 +15,4 @@ Вы также обнаружите, что между тем, что пользователи говорят и тем, что они на самом деле делают, есть разница. И это проблема, поскольку обычно пользовательские требования формируются путем опроса. Поэтому лучший способ составить требования – это понаблюдать за пользователями. Потратить час на наблюдения будет гораздо более информативно, чем потратить день на распросы. -Автор оригинала - [Giles Colborne](http://programmer.97things.oreilly.com/wiki/index.php/Giles_Colborne) \ No newline at end of file +Автор оригинала - [Giles Colborne](http://programmer.97things.oreilly.com/wiki/index.php/Giles_Colborne) diff --git a/ru/thing_38/README.md b/ru/thing_38/README.md index d8a9bdea..d1765fc8 100644 --- a/ru/thing_38/README.md +++ b/ru/thing_38/README.md @@ -3,7 +3,7 @@ Если посмотреть на любую активность, процесс или дисциплину с достаточного расстояния, то все будет выглядеть просто. Менеджеры без опыта программирования считают программирование простой задачей, а программисты без опыта руководства думают то же самое о работе менеджеров. -Самая сложная часть процесса программирования – мышление – одновременно и самая незаметная часть, а также наименее ценимая непосвященными. В течении десятилетий было много попыток устранить из процесса необходимость наличия мышления. Одна из самых ранних и наиболее запомнившихся попыток – это усилия Грейс Хоппер по созданию более понятного языка программирования, что по мнению некоторых должно было вообще снять потребность в специальности «Программист». Результат (язык COBOL) внес существенный вклад в привлечение в отрасль новых программистов в последующие десятилетия. +Самая сложная часть процесса программирования – мышление – одновременно и самая незаметная часть, а также наименее ценимая непосвященными. В течение десятилетий было много попыток устранить из процесса необходимость наличия мышления. Одна из самых ранних и наиболее запомнившихся попыток – это усилия Грейс Хоппер по созданию более понятного языка программирования, что по мнению некоторых должно было вообще снять потребность в специальности «Программист». Результат (язык COBOL) внес существенный вклад в привлечение в отрасль новых программистов в последующие десятилетия. Настойчивые попытки упростить разработку ПО так, чтобы вообще сделать программистов ненужными, для тех программистов, кто понимает, что из себя представляет процесс на самом деле, кажутся весьма наивными. Однако ментальный процесс, ведущий к такой ошибке, является частью человеческой натуры, и программисты столь же склонны к нему, как и все остальные. diff --git a/ru/thing_71/README.md b/ru/thing_71/README.md index c34f9f57..075be5ba 100644 --- a/ru/thing_71/README.md +++ b/ru/thing_71/README.md @@ -9,7 +9,7 @@ Большинство широко известных «хороших» практик программирования (хотя им не так часто следуют) облегчают построение аргументации. Уже даже от того, что вы задумаетесь об аргументации правильности вашего кода, вы начнете думать в направлении лучшего стиля и структуры кода. И конечно же, соблюдение большинства этих практик можно проверить при помощи статических анализаторов кода: -1. Избегайте операторов goto, поскольку они делают удаленные друг от друга секции сильно связанными. +- Избегайте операторов goto, поскольку они делают удаленные друг от друга секции сильно связанными. - Избегайте изменяемых глобальных переменных, поскольку они делают секции, их использующие, зависимыми. - Каждая переменная должна иметь минимально возможную область видимости. Например, локальный объект может создаваться непосредственно перед его использованием. - Делайте объекты неизменяемыми там, где только это возможно. @@ -23,4 +23,4 @@ Кроме доказательства правильности кода, его обсуждение даст вам лучшее его понимание. Развитие проницательности выгодно для всех. -Автор оригинала - [Yechiel Kimchi](http://programmer.97things.oreilly.com/wiki/index.php/Yechiel_Kimchi) \ No newline at end of file +Автор оригинала - [Yechiel Kimchi](http://programmer.97things.oreilly.com/wiki/index.php/Yechiel_Kimchi) diff --git a/ru/thing_89/README.md b/ru/thing_89/README.md index 0772328b..ea211c29 100644 --- a/ru/thing_89/README.md +++ b/ru/thing_89/README.md @@ -19,7 +19,7 @@ Упс, а что, у вас нет tutorial-a? На том языке, который я понимаю? -И если в toturial-e будут упомянуты мои проблемы, я сдамся. Я начну читать о том, что я могу сделать при помощи вашей программы, и делать это с удовольствием. Я наконец-то выдохну, откинусь на спинку стула и сделаю глоток чая (я ведь сказал, что я из Великобритании?), а потом поиграю с вашими примерами, чтобы понять, как работать с вашим приложением. И если я решу свои проблемы с его помощью, я пошлю вам благодарственный е-мейл. Я отправлю отчет об ошибке, если таковая случится, а также напишу о желаемых дополнениях. И я расскажу всем своим друзьям о том, что ваше ПО лушчее, хотя я даже не попробовал аналогичное ПО ваших конкурентов. И все это лишь потому, что вы потрудились облегчить мои первые шаги. +И если в toturial-e будут упомянуты мои проблемы, я сдамся. Я начну читать о том, что я могу сделать при помощи вашей программы, и делать это с удовольствием. Я наконец-то выдохну, откинусь на спинку стула и сделаю глоток чая (я ведь сказал, что я из Великобритании?), а потом поиграю с вашими примерами, чтобы понять, как работать с вашим приложением. И если я решу свои проблемы с его помощью, я пошлю вам благодарственный е-мейл. Я отправлю отчет об ошибке, если таковая случится, а также напишу о желаемых дополнениях. И я расскажу всем своим друзьям о том, что ваше ПО лучшее, хотя я даже не попробовал аналогичное ПО ваших конкурентов. И все это лишь потому, что вы потрудились облегчить мои первые шаги. Я все еще вас не убедил? diff --git a/tr/README.md b/tr/README.md new file mode 100644 index 00000000..4b61d05b --- /dev/null +++ b/tr/README.md @@ -0,0 +1,10 @@ +Her Yazılımcının Bilmesi Gereken 97 Şey +====== + +*Önde gelen uygulayıcılardan toplanan yazılımcılar için bilgelik incileri.* + +Bu [GitBook](https://www.gitbook.io) ['Her Yazılımcının Bilmesi Gereken 97 Şey' projesinin versiyondur](http://programmer.97things.oreilly.com/wiki/index.php/97_Things_Every_Programmer_Should_Know). + +Tüm içerik [Creative Commons Attribution-NonCommercial-ShareAlike 3.0 lisansı](http://creativecommons.org/licenses/by-nc-sa/3.0/) kapsamında lisanslanmıştır. Kitabın basılı sürümleri [Amazon.com](http://www.amazon.com/Things-Every-Programmer-Should-Know/dp/0596809484) adresinde mevcuttur. + +Herhangi bir hata bulursanız veya herhangi bir öneriniz varsa, bir [konu oluşturabilir](https://github.com/97-things/97-things-every-programmer-should-know/issues) veya [depoya](https://github.com/97-things/97-things-every-programmer-should-know) bir [çekme isteği](https://github.com/97-things/97-things-every-programmer-should-know/pulls) gönderebilirsiniz. \ No newline at end of file diff --git a/tr/SUMMARY.md b/tr/SUMMARY.md new file mode 100644 index 00000000..6c83319c --- /dev/null +++ b/tr/SUMMARY.md @@ -0,0 +1,100 @@ +# Summary + +* [Tanıtım](README.md) +1. [Sağduyulu hareket edin](thing_01/README.md) +1. [Fonksiyonel Programlama İlkelerini Uygulayın](thing_02/README.md) +1. ["Kullanıcı Ne Yapar?" Diye Sor (Kullanıcı Siz değilsiniz)](thing_03/README.md) +1. [Kodlama Standardınızı Otomatikleştirin](thing_04/README.md) +1. [Güzellik Sadelikte](thing_05/README.md) +1. [Yeniden Düzenlemeden Önce](thing_06/README.md) +1. [Paylaşıma Dikkat Edin](thing_07/README.md) +1. [İzci Kuralı](thing_08/README.md) +1. [Başkalarını Suçlamadan Önce Kodunuzu Kontrol Edin](thing_09/README.md) +1. [Araçlarınızı Özenle Seçin](thing_10/README.md) +1. [Domain Dilindeki Kod](thing_11/README.md) +1. [Kod Tasarımdır](thing_12/README.md) +1. [Kod Düzeni Önemlidir](thing_13/README.md) +1. [Kod İncelemeleri](thing_14/README.md) +1. [Akıllı Kodlama](thing_15/README.md) +1. [Yorumlar Üzerine Bir Yorum](thing_16/README.md) +1. [Yalnızca Kodun Söyleyemediklerini Yorumlayın](thing_17/README.md) +1. [Devamlı öğrenme](thing_18/README.md) +1. [Kolaylık bir yetenek değildir](thing_19/README.md) +1. [Erken ve Sıkça Dağıtın](thing_20/README.md) +1. [İş İstisnalarını Tekniklerden Ayırın](thing_21/README.md) +1. [Bol Bol Kasıtlı Uygulama Yapın](thing_22/README.md) +1. [Etki Alanına Özgü Diller](thing_23/README.md) +1. [Bir Şeyleri Kırmaktan Korkma](thing_24/README.md) +1. [Test Verilerinizle Sevimli Olmayın](thing_25/README.md) +1. [Hatayı Görmezden Gelmeyin!](thing_26/README.md) +1. [Sadece Dili Öğrenmeyin, Kültürünü Anlayın](thing_27/README.md) +1. [Programınızı Dik Konumda Çivilemeyin](thing_28/README.md) +1. ["Burada Sihir Olur"a Güvenmeyin](thing_29/README.md) +1. [Kendinizi Tekrar Etmeyin (Don't Repeat Yourself - DRY)](thing_30/README.md) +1. [O Koda Dokunma!](thing_31/README.md) +1. [Sadece Durumu Değil, Davranışı Kapsülleyin](thing_32/README.md) +1. [Kayan Noktalı Sayılar Gerçek Değil](thing_33/README.md) +1. [Açık Kaynak ile Hedeflerinizi Gerçekleştirin](thing_34/README.md) +1. [API Tasarımının Altın Kuralı](thing_35/README.md) +1. [Guru Efsanesi](thing_36/README.md) +1. [Sıkı Çalışmanın Getirisi Yok](thing_37/README.md) +1. [Hata İzleyici Nasıl Kullanılır](thing_38/README.md) +1. [Kodu Kaldırarak İyileştirin](thing_39/README.md) +1. [Beni Kur](thing_40/README.md) +1. [Süreçler Arası İletişim Uygulama Yanıt Süresini Etkiler](thing_41/README.md) +1. [Yapıyı Temiz Tutun](thing_42/README.md) +1. [Komut Satırı Araçlarını Nasıl Kullanacağınızı Bilin](thing_43/README.md) +1. [İkiden Fazla Programlama Dilini İyi Bilin](thing_44/README.md) +1. [IDE'nizi Bilin](thing_45/README.md) +1. [Sınırlarınızı Bilin](thing_46/README.md) +1. [Bir Sonraki İşleminizi(Commit) Bilin](thing_47/README.md) +1. [Büyük Birbirine Bağlı Veriler Bir Veritabanına Aittir](thing_48/README.md) +1. [Yabancı Diller Öğrenin](thing_49/README.md) +1. [Tahmin Etmeyi Öğrenin](thing_50/README.md) +1. ["Merhaba Dünya" Demeyi Öğrenin](thing_51/README.md) +1. [Bırakın Projeniz Kendi Adına Konuşsun](thing_52/README.md) +1. [Bağlayıcı Sihirli Bir Program Değildir](thing_53/README.md) +1. [Geçici Çözümlerin Uzun Ömrü](thing_54/README.md) +1. [Arayüzlerin Doğru Kullanımını Kolay ve Yanlış Kullanımını Zorlaştırın](thing_55/README.md) +1. [Görünmezi Daha Görünür Hale Getirin](thing_56/README.md) +1. [Mesaj Geçişi, Paralel Sistemlerde Daha İyi Ölçeklenebilirlik Sağlar](thing_57/README.md) +1. [Geleceğe Mesaj](thing_58/README.md) +1. [Polimorfizm için Kaçırılan Fırsatlar](thing_59/README.md) +1. [Tuhaf Haber: Testçiler Arkadaşlarınızdır](thing_60/README.md) +1. [Tek İkili](thing_61/README.md) +1. [Sadece Kod Gerçeği Söyler](thing_62/README.md) +1. [Yapıya Sahip Olun (ve Yeniden Düzenleyin)](thing_63/README.md) +1. [Programı Eşleştirin ve Akışı Hissedin](thing_64/README.md) +1. [Domain Alanına Özgü Türleri İlkel Türlere Tercih Edin](thing_65/README.md) +1. [Hataları Önle](thing_66/README.md) +1. [Profesyonel Yazılımcı](thing_67/README.md) +1. [Her Şeyi Sürüm Kontrolü Altına Alın](thing_68/README.md) +1. [Fareyi Yere Bırakın ve Klavyeden Uzaklaşın](thing_69/README.md) +1. [Kodu Okuyun](thing_70/README.md) +1. [Beşeri Bilimleri Okuyun](thing_71/README.md) +1. [Tekerleği Sıklıkla Yeniden İcat Edin](thing_72/README.md) +1. [Singleton Modelin Cazibesine Kapılma](thing_73/README.md) +1. [Performansa Giden Yol Kirli Kod Bombalarıyla Dolu](thing_74/README.md) +1. [Sadelik Azaltmadan Gelir](thing_75/README.md) +1. [Tek Sorumluluk İlkesi(The Single Responsibility)](thing_76/README.md) +1. [Evet'ten Başlayın](thing_77/README.md) +1. [Geri Adım Atın ve Otomatikleştirin, Otomatikleştirin, Otomatikleştirin](thing_78/README.md) +1. [Kod Analiz Araçlarından Yararlanın](thing_79/README.md) +1. [Tesadüfi Davranış Değil, Gerekli Davranış Testi](thing_80/README.md) +1. [Kesin ve Somut Test Edin](thing_81/README.md) +1. [Uyurken (ve Hafta Sonları) Test Edin](thing_82/README.md) +1. [Test, Yazılım Geliştirmenin Mühendislik Zorluğudur](thing_83/README.md) +1. [Durumlarda Düşünmek](thing_84/README.md) +1. [İki Kafa Çoğu Zaman Bir Kafadan Daha İyidir](thing_85/README.md) +1. [İki Yanlış Bir Doğru Yapabilir (ve Düzeltilmesi Zordur)](thing_86/README.md) +1. [Arkadaşlarınız İçin Ubuntu Kodlama](thing_87/README.md) +1. [Unix Araçları Arkadaşlarınızdır](thing_88/README.md) +1. [Doğru Algoritmayı ve Veri Yapısını Kullanın](thing_89/README.md) +1. [Ayrıntılı Log Kaydı Uykunuzu Bozacak](thing_90/README.md) +1. [WET Performans Darboğazlarını Azaltıyor](thing_91/README.md) +1. [Programcılar ve Test Uzmanları İşbirliği Yaptığında](thing_92/README.md) +1. [Hayatınız Boyunca Desteklemek Zorundaymışsınız Gibi Kod Yazın](thing_93/README.md) +1. [Örnekleri Kullanarak Küçük Fonksiyonlar Yazın](thing_94/README.md) +1. [İnsanlar için Testler Yaz](thing_95/README.md) +1. [Kodu Önemsemelisiniz](thing_96/README.md) +1. [Müşterileriniz Ne Dediklerini Kastetmez](thing_97/README.md) diff --git a/tr/thing_01/README.md b/tr/thing_01/README.md new file mode 100644 index 00000000..ecb145fb --- /dev/null +++ b/tr/thing_01/README.md @@ -0,0 +1,15 @@ +# Sağduyulu hareket edin + +> *"Ne yaparsan yap, sağduyulu davran ve sonuçlarını düşün" Anonim* + +Bir yinelemenin başlangıcında bir program ne kadar rahat görünürse görünsün, bazen baskı altında olmaktan kaçınamazsınız. Kendinizi "doğru yapmak" ile "hızlı yapmak" arasında seçim yapmak zorunda bulursanız, daha sonra geri dönüp düzelteceğinizi düşünerek "hızlı yapmak" genellikle çekici gelir. Kendinize, ekibinize ve müşterinize bu sözü verdiğinizde, bunu kastediyorsunuz demektir. Ancak çoğu zaman bir sonraki yineleme yeni sorunlar getirir ve siz onlara odaklanırsınız. Bu tür ertelenmiş işler teknik borç olarak bilinir ve sizin arkadaşınız değildir. Martin Fowler, özellikle [teknik borç taksonomisi](http://martinfowler.com/bliki/TechnicalDebtQuadrant.html) bu kasıtlı teknik borcu, yanlışlıkla teknik borçla karıştırılmaması gerektiğini söylüyor. + +Teknik borç bir kredi gibidir: Kısa vadede ondan faydalanırsınız, ancak tamamen ödenene kadar faiz ödemeniz gerekir. Koddaki kısayollar, özellik eklemeyi veya kodunuzu yeniden düzenlemeyi zorlaştırır. Kusurlar ve kırılgan test durumları için üreme alanlarıdır. Ne kadar uzun bırakırsan, o kadar kötü olur. Orijinal düzeltmeyi üstlenmeye başladığınızda, orijinal sorunun üzerine yerleştirilmiş, kodu yeniden düzenlemeyi ve düzeltmeyi çok daha zor hale getiren, pek de doğru olmayan tasarım seçenekleri yığını olabilir. Doğrusu, çoğu zaman sadece işler o kadar kötüye gittiğinde onu düzeltmeniz gerekir, aslında onu düzeltmek için geri dönersiniz. Ve o zamana kadar düzeltmek genellikle o kadar zordur ki, gerçekten zaman veya riski göze alamazsınız. + +Son teslim tarihini karşılamak veya bir özelliğin ince bir dilimini uygulamak için teknik borç ödemeniz gereken zamanlar vardır. Bu durumda olmamaya çalışın, ancak durum kesinlikle bunu gerektiriyorsa, devam edin. Ama (ve bu büyük bir AMA) teknik borcu takip etmeli ve hızlı bir şekilde geri ödemelisin yoksa işler hızla yokuş aşağı gider. Uzlaşmaya karar verir vermez, unutulmaması için bir görev kartı yazın veya sorun takip sisteminize kaydedin. + +Bir sonraki yinelemede borcun geri ödemesini planlarsanız, maliyet minimum olacaktır. Borcun ödenmeden bırakılması faiz tahakkuk ettirir ve maliyetin görünür olması için bu faizin takip edilmesi gerekir. Bu, projenin teknik borcunun işletme değeri üzerindeki etkisini vurgulayacak ve geri ödemenin uygun şekilde önceliklendirilmesini sağlayacaktır. İlginin nasıl hesaplanacağı ve izleneceğine ilişkin seçim, belirli projeye bağlı olacaktır, ancak onu izlemelisiniz. + +Teknik borcu mümkün olan en kısa sürede ödeyin. Aksini yapmak tedbirsizlik olur. + +[Seb Rose's GitHub profile](https://github.com/sebrose) / [Seb Rose's LinkedIn Profile](https://www.linkedin.com/in/sebrose) Tarafından \ No newline at end of file diff --git a/tr/thing_02/README.md b/tr/thing_02/README.md new file mode 100644 index 00000000..fd8e892f --- /dev/null +++ b/tr/thing_02/README.md @@ -0,0 +1,19 @@ +# Fonksiyonel Programlama İlkelerini Uygulayın + +Fonksiyonel programlama, son zamanlarda ana akım programlama topluluğunun yeniden ilgisini çekti. Bunun bir nedeni, fonksiyonel paradigmanın *ortaya çıkan özelliklerinin*, sektörümüzün çoklu çekirdeğe geçişinin getirdiği zorlukların üstesinden gelmek için iyi bir konumda olmasıdır. Ancak, bu kesinlikle önemli bir uygulama olsa da, bu parçanın size *fonksiyonel programlamanızı bilmenizi* tavsiye etmesinin nedeni bu değildir. + +Fonksiyonel programlama paradigmasına hakim olmak, diğer bağlamlarda yazdığınız kodun kalitesini büyük ölçüde artırabilir. Fonksiyonel paradigmayı derinlemesine anlar ve uygularsanız, tasarımlarınız çok daha yüksek derecede *referans şeffaflığı* sergileyecektir. + +Referans şeffaflığı çok istenen bir özelliktir: Fonksiyonların, nerede ve ne zaman çağrıldıklarına bakılmaksızın, aynı girdi verildiğinde tutarlı bir şekilde aynı sonuçları verdiğini ifade eder. Yani, fonksiyon değerlendirmesi değişken durumun yan etkilerine daha az bağlıdır - ideal olarak, hiç değil. + +Zorunlu koddaki hataların önde gelen bir nedeni de değiştirilebilir değişkenlere bağlanabilir. Bunu okuyan herkes, belirli bir durumda bazı değerlerin neden beklendiği gibi olmadığını araştırmış olacaktır. Görünürlük semantiği, bu sinsi kusurları hafifletmeye veya en azından konumlarını büyük ölçüde daraltmaya yardımcı olabilir, ancak bunların asıl suçlusu aslında aşırı değişkenlik kullanan tasarımların tutumu olabilir. + +Ve bu konuda kesinlikle sektörden pek bir yardım alamıyoruz. Nesne yönelimine girişler, bu tür tasarımı kısmen destekler, çünkü genellikle, birbirleri üzerinde mutlu bir şekilde mutatör yöntemlerini çağıran ve tehlikeli olabilen, nispeten uzun ömürlü nesnelerin grafiklerinden oluşan örnekler gösterirler. Ancak, zekice teste dayalı tasarımla, özellikle de ["Mock Roles, not Objects"](http://www.jmock.org/oopsla2004.pdf) yapıldığından emin olunduğunda, gereksiz değişkenlik ortadan kaldırılabilir. + +Net sonuç, değiştirilebilir üye değişkenlere başvurmak bulunmak yerine, kendilerine iletilen argümanlar üzerinde hareket eden daha çok sayıda, daha küçük işlevlerle tipik olarak daha iyi sorumluluk dağılımına sahip bir tasarımdır. Daha az kusur olacak ve ayrıca hata ayıklamak genellikle daha kolay olacak, çünkü bu tasarımlarda sahte bir değerin nerede ortaya çıktığını bulmak, aksi takdirde hatalı bir atamayla sonuçlanan belirli bağlamı çıkarmaktan daha kolaydır. Bu, çok daha yüksek derecede bir referans şeffaflığı ekler ve pozitif olarak hiçbir şey bu fikirleri, bu hesaplama modelinin norm olduğu fonksiyonel bir programlama dili öğrenmek kadar derine inemez. + +Tabii ki, bu yaklaşım her durumda optimal değildir. Örneğin, nesne yönelimli sistemlerde bu tarz, genellikle etki alanı modeli geliştirmede (yani işbirliklerinin iş kurallarının karmaşıklığını yıkmaya hizmet ettiği yerlerde) kullanıcı arayüzü geliştirmeye göre daha iyi sonuçlar verir. + +Öğrenilen dersleri diğer alanlara mantıklı bir şekilde uygulayabilmek için fonksiyonel programlama paradigmasında ustalaşın. Nesne sistemleriniz (biri için) referans şeffaflığı iyiliği ile yankılanacak ve işlevsel benzerlerine pek çok kişinin inandığından çok daha yakın olacaktır. Hatta bazıları, fonksiyonel programlama ve nesne yöneliminin zirvesinin *yalnızca birbirinin bir yansıması*, bir hesaplamalı yin ve yang biçimi olduğunu bile iddia edebilir. + +[Edward Garson](http://programmer.97things.oreilly.com/wiki/index.php/Edward_Garson) Tarafından \ No newline at end of file diff --git a/tr/thing_03/README.md b/tr/thing_03/README.md new file mode 100644 index 00000000..61c6cd15 --- /dev/null +++ b/tr/thing_03/README.md @@ -0,0 +1,15 @@ +# "Kullanıcı Ne Yapar?" Diye Sor (Kullanıcı Siz değilsiniz) + +Hepimiz başkalarının bizim gibi düşündüğünü varsayma eğilimindeyiz ama yapmazlar. Psikologlar buna yanlış fikir birliği yanlılığı diyor. İnsanlar bizden farklı düşündüklerinde veya davrandıklarında, onları (bilinçaltında) bir şekilde kusurlu olarak etiketlememiz oldukça olasıdır. + +Bu önyargı, yazılımcıların kendilerini kullanıcıların yerine koymakta neden bu kadar zorlandıklarını açıklıyor. Kullanıcılar yazılımcılar gibi düşünmezler. Başlangıç olarak, bilgisayarları kullanarak çok daha az zaman harcarlar. Bir bilgisayarın nasıl çalıştığını ne bilirler ne de umursarlar. Bu, yazılımcıların çok aşina olduğu problem çözme tekniklerinden hiçbirinden yararlanamayacakları anlamına gelir. Yazılımcıların bir arayüzle, arayüz üzerinden ve çevresinde çalışmak için kullandıkları kalıpları ve ipuçlarını tanımıyorlar. + +Kullanıcıların nasıl düşündüklerini öğrenmenin en iyi yolu bir tanesini izlemektir. Bir kullanıcıdan, geliştirmekte olduğunuz şeye benzer bir yazılım parçası kullanarak bir görevi tamamlamasını isteyin. Görevin gerçek olduğundan emin olun: "Bir sayı sütunu ekleyin" tamam; "Geçen ay için harcamalarınızı hesaplayın" daha iyidir. "Bu elektronik tablo hücrelerini seçip aşağıya bir *SUM* formülü girebilir misiniz?" gibi çok özel görevlerden kaçının. — bu soruda büyük bir ipucu var. Kullanıcının ilerlemesini konuşmasını sağlayın. Kesmeyin. Yardım etmeye çalışmayın. Kendine "Neden bunu yapıyor?" ve "Neden bunu yapmıyor?" diye sormaya devam et. + +Fark edeceğiniz ilk şey, kullanıcıların temel şeyleri benzer şekilde yaptıklarıdır. Görevleri aynı sırayla tamamlamaya çalışırlar ve aynı yerlerde aynı hataları yaparlar. Bu temel davranış etrafında tasarlamanız gerekir. Bu, insanların "Ya kullanıcı isterse...?" dedikleri için dinlenmeye meyilli olduğu tasarım toplantılarından farklıdır. Bu, ayrıntılı özelliklere ve kullanıcıların ne istediği konusunda kafa karışıklığına yol açar. Kullanıcıları izlemek bu karışıklığı ortadan kaldırır. + +Kullanıcıların takıldığını göreceksiniz. Sıkışınca etrafına bakarsın. Kullanıcılar sıkışıp kaldıklarında odaklarını daraltırlar. Ekranın başka yerlerinde çözümleri görmeleri onlar için zorlaşıyor. Yardım metninin zayıf kullanıcı arayüzü tasarımına zayıf bir çözüm olmasının bir nedeni budur. Talimatlarınız veya yardım metniniz olması gerekiyorsa, onu sorunlu alanlarınızın hemen yanına yerleştirdiğinizden emin olun. Araç ipuçlarının yardım menülerinden daha yararlı olmasının nedeni, kullanıcının dar ilgi odağıdır. + +Kullanıcılar kafa karıştırmaya eğilimlidir. İşe yarayan bir yol bulacaklar ve ne kadar karmaşık olursa olsun ona sadık kalacaklar. İki veya üç kısayoldan ziyade, işleri yapmanın gerçekten bariz bir yolunu sağlamak daha iyidir. Ayrıca, kullanıcıların istediklerini söyledikleri ile gerçekte yaptıkları arasında bir boşluk olduğunu da göreceksiniz. Kullanıcı gereksinimlerini toplamanın normal yolu onlara sormak olduğundan bu endişe verici. Bu nedenle gereksinimleri yakalamanın en iyi yolu kullanıcıları izlemektir. Kullanıcıları izleyerek bir saat harcamak, bir günü ne istediklerini tahmin ederek geçirmekten daha bilgilendiricidir. + +[Giles Colborne](http://programmer.97things.oreilly.com/wiki/index.php/Giles_Colborne) Tarafından \ No newline at end of file diff --git a/tr/thing_04/README.md b/tr/thing_04/README.md new file mode 100644 index 00000000..e1104788 --- /dev/null +++ b/tr/thing_04/README.md @@ -0,0 +1,20 @@ +# Kodlama Standardınızı Otomatikleştirin + +Muhtemelen sen de orada bulunmuşsundur. Bir projenin başlangıcında herkesin birçok iyi niyeti vardır - bunlara "yeni projenin kararları" diyebiliriz. Oldukça sık olarak, bu kararların çoğu belgelere yazılır. Kodla ilgili olanlar projenin kodlama standardında yer alır. Başlangıç toplantısında, baş geliştirici belgeyi gözden geçirir ve en iyi durumda, herkes onları takip etmeye çalışacaklarını kabul eder. Ancak proje başladığında, bu iyi niyetler birer birer terk edilir. Proje sonunda teslim edildiğinde, kod bir karmaşa gibi görünüyor ve kimse bu hale nasıl geldiğini bilmiyor. + +İşler ne zaman ters gitti? Muhtemelen başlangıç toplantısında. Bazı proje üyeleri dikkat etmedi. Diğerleri konuyu anlamadı. Daha da kötüsü, bazıları aynı fikirde değildi ve zaten kodlama standart isyanını planlıyorlardı. Sonunda bazıları konuyu anladı ve kabul etti, ancak projedeki baskı çok arttığında bir şeyleri bırakmak zorunda kaldılar. İyi biçimlendirilmiş kod, daha fazla işlevsellik isteyen bir müşteriyle size puan kazandırmaz. Ayrıca, bir kodlama standardını takip etmek, otomatikleştirilmemişse oldukça sıkıcı bir görev olabilir. Kendiniz bulmak için sadece dağınık bir sınıfı elle girintilemeye çalışın. + +Ama eğer böyle bir problemse, neden ilk etapta bir kodlama standardına sahip olmak istiyoruz? Kodu tek tip bir şekilde biçimlendirmenin bir nedeni, hiç kimsenin bir kod parçasına yalnızca kendi özel yöntemiyle biçim vererek "sahip olmaması"dır. Bazı yaygın hatalardan kaçınmak için geliştiricilerin belirli anti-kalıpları kullanmasını önlemek isteyebiliriz. Toplamda, bir kodlama standardı projede çalışmayı kolaylaştırmalı ve baştan sona geliştirme hızını korumalıdır. Bundan sonra herkesin kodlama standardı üzerinde hemfikir olması gerekir - bir geliştiricinin kodu girintilemek için üç boşluk kullanması ve diğerinin dört boşluk kullanması yardımcı olmaz. + +Kod kalitesi raporları oluşturmak ve kodlama standardını belgelemek ve sürdürmek için kullanılabilecek çok sayıda araç vardır, ancak tüm çözüm bu değildir. Mümkünse otomatikleştirilmeli ve uygulanmalıdır. İşte birkaç örnek: + +- Kod biçimlendirmenin derleme sürecinin bir parçası olduğundan emin olun, böylece herkes kodu her derlediğinde bunu otomatik olarak çalıştırır. +- İstenmeyen anti-kalıplara karşı kodu taramak için statik kod analiz araçlarını kullanın. Herhangi biri bulunursa, yapıyı bozun. +- Kendi, projeye özgü anti-kalıplarınızı tarayabilmeniz için bu araçları yapılandırmayı öğrenin. +- Yalnızca test kapsamını ölçmekle kalmayın, sonuçları da otomatik olarak kontrol edin. Yine, test kapsamı çok düşükse yapıyı bozun. + +Bunu önemli olduğunu düşündüğünüz her şey için yapmaya çalışın. Gerçekten önemsediğiniz her şeyi otomatikleştiremezsiniz. Otomatik olarak işaretleyemeyeceğiniz veya düzeltemeyeceğiniz şeylere gelince, bunları otomatikleştirilmiş kodlama standardına tamamlayıcı bir dizi yönerge olarak düşünün, ancak sizin ve iş arkadaşlarınızın bunları özenle takip edemeyeceğinizi kabul edin. + +Son olarak, kodlama standardı statik değil dinamik olmalıdır. Proje geliştikçe, projenin ihtiyaçları değişir ve başlangıçta akıllıca görünen şey, birkaç ay sonra mutlaka akıllı olmak zorunda değildir. + +[Filip van Laenen](http://programmer.97things.oreilly.com/wiki/index.php/Filip_van_Laenen) Tarafından \ No newline at end of file diff --git a/tr/thing_05/README.md b/tr/thing_05/README.md new file mode 100644 index 00000000..75cf95d2 --- /dev/null +++ b/tr/thing_05/README.md @@ -0,0 +1,28 @@ +# Güzellik Sadelikte + +Tüm yazılım geliştiricilerin bilmesi ve kalplerine yakın tutması için özellikle iyi olduğunu düşündüğüm bir alıntı var: + +> *Tarzın, uyumun, zarafetin ve iyi ritmin güzelliği sadeliğe bağlıdır.* - Platon + +Bence bu, yazılım geliştiriciler olarak bizim talip olmamız gereken değerleri bir cümleyle özetliyor. + +Kodumuzda ulaşmaya çalıştığımız birkaç şey var: + +- Okunabilirlik +- Bakım kolaylığı +- Geliştirme hızı +- Güzelliğin anlaşılması zor kalitesi + +Platon bize, tüm bu nitelikleri sağlayan etkenin basitlik olduğunu söylüyor. + +Güzel kod nedir? Bu potansiyel olarak çok öznel bir sorudur. Güzellik algısı büyük ölçüde bireysel geçmişe bağlıdır, tıpkı herhangi bir şey hakkındaki algımızın çoğunun geçmişimize bağlı olması gibi. Sanatta eğitim almış insanlar, bilimlerde eğitim görmüş insanlardan farklı bir güzellik algısına (veya en azından yaklaşımlarına) sahiptir. Sanat dalları, yazılımı sanat eserleriyle karşılaştırarak yazılımdaki güzelliğe yaklaşma eğilimindeyken, bilim dalları simetri ve altın oran hakkında konuşma ve her şeyi formüle indirmeye çalışma eğilimindedir. Tecrübelerime göre, her iki taraftaki argümanların çoğunun temeli basitliktir. + +Çalıştığınız kaynak kodu düşünün. Başkalarının kodlarını incelemek için zaman harcamadıysanız, şu anda bunu okumayı bırakın ve çalışmak için açık kaynak kodu bulun. Ciddi anlamda! İçtenlikle söyledim! Web'de, tanınmış, tanınmış bir uzman tarafından yazılmış, seçtiğiniz dilde bazı kodlar arayın. + +Geri döndün mü? İyi. Neredeydik? Ah evet... Bana hitap eden ve güzel olduğunu düşündüğüm kodun birçok ortak özelliği olduğunu buldum. Bunların başında sadelik gelir. Toplam uygulama veya sistem ne kadar karmaşık olursa olsun, tek tek parçaların basit tutulması gerektiğini düşünüyorum. Açıklayıcı adlara sahip benzer şekilde basit, odaklanmış yöntemler içeren tek bir sorumluluğa sahip basit nesneler. Bazı insanlar, beş ila on satırlık kısa kod yöntemlerine sahip olma fikrinin aşırı olduğunu düşünüyor ve bazı diller bunu yapmayı çok zorlaştırıyor, ancak böyle bir kısalığın yine de arzu edilen bir hedef olduğunu düşünüyorum. + +Sonuç olarak, güzel kod basit koddur. Her bir parça, basit sorumluluklarla ve sistemin diğer parçalarıyla basit ilişkilerle basit tutulur. Bu şekilde, sistem ömrü boyunca geliştirme hızını yüksek tutarak, temiz, basit, test edilebilir kodla sistemlerimizi zaman içinde bakımlı tutabiliriz. + +Güzellik basitlikten doğar ve sadelikte bulunur. + +Jørn Ølmheim Tarafından \ No newline at end of file diff --git a/tr/thing_06/README.md b/tr/thing_06/README.md new file mode 100644 index 00000000..c9ec8755 --- /dev/null +++ b/tr/thing_06/README.md @@ -0,0 +1,19 @@ +# Yeniden Düzenlemeden Önce + +Bir noktada her yazılımcının mevcut kodu yeniden düzenlemesi gerekecek. Ancak bunu yapmadan önce lütfen aşağıdakileri düşünün, çünkü bu sizi ve diğerlerini büyük ölçüde zamandan (ve acıdan) kurtarabilir: + +- *Yeniden yapılandırma için en iyi yaklaşım, mevcut kod tabanını ve bu koda karşı yazılan testleri değerlendirmekle başlar.* Bu, kodun mevcut haliyle güçlü ve zayıf yönlerini anlamanıza yardımcı olacaktır, böylece hatalardan kaçınırken güçlü noktaları korumanızı sağlayabilirsiniz. Hepimiz mevcut sistemden daha iyisini yapabileceğimizi düşünüyoruz... ta ki mevcut sistem hatalarından ders çıkaramadığımız için önceki üründen daha iyi olmayan - hatta daha kötü olmayan - bir şeyle sonuçlanıncaya kadar. + +- *Her şeyi yeniden yazmanın cazibesinden kaçının.* Mümkün olduğu kadar çok kodu yeniden kullanmak en iyisidir. Kod ne kadar çirkin olursa olsun, zaten test edilmiş, gözden geçirilmiş vb. Eski kodu - özellikle de üretimdeyse - atmak, farkında olmadığınız belirli geçici çözümlere ve hata düzeltmelerine sahip olabilecek, aylarca (veya yıllarca) test edilmiş, savaşta sertleştirilmiş kodu attığınız anlamına gelir. Bunu hesaba katmazsanız, yazdığınız yeni kod, eski kodda düzeltilen aynı gizemli hataları gösterebilir. Bu, yıllar içinde kazanılan çok fazla zaman, çaba ve bilgi israfına neden olacaktır. + +- *Birçok artımlı değişiklik, tek bir büyük değişiklikten daha iyidir.* Artımlı değişiklikler, geri bildirim yoluyla sistem üzerindeki etkiyi daha kolay ölçmenizi sağlar, örneğin testlerden. Bir değişiklik yaptıktan sonra yüzlerce test hatası görmek eğlenceli değil. Bu, kötü kararlarla sonuçlanabilecek hayal kırıklığına ve baskıya yol açabilir. Birkaç test hatasının üstesinden gelmek kolaydır ve daha yönetilebilir bir yaklaşım sağlar. + +- *Her yinelemeden sonra mevcut testlerin geçmesini sağlamak önemlidir.* Mevcut testler yaptığınız değişiklikleri karşılamaya yetmiyorsa yeni testler ekleyin. Eski koddaki testleri, gerekli özeni göstermeden atmayın. İlk bakışta, bu testlerden bazıları yeni tasarımınıza uygulanabilir görünmeyebilir, ancak bu özel testin neden eklendiğini derinlemesine araştırmak çabaya değer. + +- *Kişisel tercihler ve ego araya girmemeli.* Bir şey bozuk değilse, neden düzeltelim? Kodun stilinin veya yapısının kişisel tercihinizi karşılamaması, yeniden yapılandırma için geçerli bir neden değildir. Önceki yazılımcıdan daha iyi bir iş yapabileceğinizi düşünmek de geçerli bir sebep değil. + +- *Yeni teknoloji, yeniden düzenleme yapmak için yetersiz bir nedendir.* Yeniden düzenleme yapmanın en kötü nedenlerinden biri, mevcut kodun bugün sahip olduğumuz tüm harika teknolojinin çok gerisinde olması ve yeni bir dil veya çerçevenin işleri çok daha zarif bir şekilde yapabileceğine inanıyoruz. Maliyet-fayda analizi, yeni bir dilin veya çerçevenin işlevsellik, sürdürülebilirlik veya üretkenlikte önemli gelişmelerle sonuçlanacağını göstermediği sürece, onu olduğu gibi bırakmak en iyisidir. + +- *İnsanların hata yaptığını unutmayın.* Yeniden yapılandırma, her zaman yeni kodun daha iyi - hatta önceki deneme kadar iyi - olacağını garanti etmez. Birkaç başarısız yeniden yapılandırma girişimi gördüm ve bir parçası oldum. Güzel değildi ama insandı. + +[Rajith Attapattu](http://programmer.97things.oreilly.com/wiki/index.php/Rajith_Attapattu) Tarafından \ No newline at end of file diff --git a/tr/thing_07/README.md b/tr/thing_07/README.md new file mode 100644 index 00000000..4aacd268 --- /dev/null +++ b/tr/thing_07/README.md @@ -0,0 +1,21 @@ +# Paylaşıma Dikkat Edin + +Şirketteki ilk projemdi. Derecemi yeni bitirmiştim ve her gün geç saatlere kadar mevcut kodu inceleyerek kendimi kanıtlamak için can atıyordum. İlk değişiklik üzerinde çalışırken, öğrendiğim her şeyi - yorum yapmak, günlüğe kaydetmek, mümkünse ortak kodu kütüphanelere çekmek işlerini - uygulamaya koymak için ekstra özen gösterdim. Kendimi çok hazır hissettiğim kod incelemesi kaba bir uyanış olarak geldi - yeniden kullanım hoş karşılanmadı! + +Bu nasıl olabilir? Üniversite boyunca yeniden kullanım, kaliteli yazılım mühendisliğinin özü olarak kabul edildi. Okuduğum tüm makaleler, ders kitapları, bana öğreten deneyimli yazılım uzmanları. Hepsi yanlış mıydı? + +Kritik bir şeyi kaçırdığım ortaya çıktı. + +Bağlam. + +Sistemin çılgınca farklı iki parçasının aynı şekilde bazı mantık yürütmeleri, düşündüğümden daha az şey ifade ediyordu. Bu paylaşılan kod kitaplıklarını çıkarana kadar, bu parçalar birbirine bağımlı değildi. Her biri bağımsız olarak gelişebilir. Her biri, sistemin değişen iş ortamının ihtiyaçlarına göre mantığını değiştirebilir. Bu dört satırlık benzer kod tesadüfiydi - zamansal bir anormallik, bir tesadüf. Yani ben gelene kadar. + +Oluşturduğum ortak kod kitaplıkları her ayağın bağcıklarını birbirine bağladı. Bir iş etki alanına göre adımlar, önce diğeriyle senkronize edilmeden yapılamaz. Bu bağımsız işlevlerdeki bakım maliyetleri ihmal edilebilir düzeydeydi, ancak ortak kitaplık, çok daha fazla test gerektiriyordu. + +Sistemdeki mutlak kod satırı sayısını azaltırken, bağımlılık sayısını artırdım. Bu bağımlılıkların bağlamı kritiktir - yerelleştirilmiş olsalardı, haklı olabilirdi ve bazı olumlu değerlere sahip olabilirdi. Bu bağımlılıklar kontrol altında tutulmadığında, kodun kendisi gayet iyi görünse bile, eğilimleri sistemi daha büyük endişelere bulaştırır. + +Bu hatalar sinsidir, özünde iyi bir fikir gibi görünürler. Doğru bağlamda uygulandığında bu teknikler değerlidir. Yanlış bağlamda, değerden çok maliyeti artırırlar. Çeşitli bölümlerin kullanılacağı bağlam hakkında hiçbir bilgim olmadan mevcut bir kod tabanına geldiğimde, bugünlerde nelerin paylaşıldığı konusunda çok daha dikkatli oluyorum. + +Paylaşıma dikkat edin. Bağlamınızı kontrol edin. Ancak o zaman devam edin. + +[Udi Dahan](http://programmer.97things.oreilly.com/wiki/index.php/Udi_Dahan) Tarafından \ No newline at end of file diff --git a/tr/thing_08/README.md b/tr/thing_08/README.md new file mode 100644 index 00000000..775f2538 --- /dev/null +++ b/tr/thing_08/README.md @@ -0,0 +1,15 @@ +# İzci Kuralı + +İzcilerin bir kuralı vardır: "Kamp alanını her zaman bulduğunuzdan daha temiz bırakın." Yerde bir pislik bulursanız, pisliği kimin yapmış olabileceğine bakmaksızın onu temizlersiniz. Bir sonraki kampçı grubu için kasıtlı olarak çevreyi iyileştirirsiniz. Aslında bu kuralın orijinal şekli, izciliğin babası Robert Stephenson Smyth Baden-Powell tarafından yazılmış, "Bu dünyayı bulduğunuzdan biraz daha iyi bir şekilde terk etmeye çalışın" idi. + +Kodumuzdaki benzer bir kuralı izlesek ne olur: "Bir modülü her zaman teslim aldığınızdan daha temiz bir şekilde kontrol edin." Orijinal yazarın kim olduğu önemli değil, ya ne kadar küçük olursa olsun, modülü geliştirmek için her zaman biraz çaba gösterseydik. Sonuç ne olurdu? + +Sanırım hepimiz bu basit kuralı izleseydik, yazılım sistemlerimizdeki amansız bozulmanın sonunu görürdük. Bunun yerine, sistemlerimiz geliştikçe yavaş yavaş daha iyi hale gelecekti. Ayrıca, sadece kendi küçük parçalarıyla ilgilenen bireylerden ziyade, sistemi bir bütün olarak önemseyen *ekipler* görürdük. + +Bu kuralın çok fazla sorulacağını sanmıyorum. Kontrol etmeden önce her modülü mükemmel hale getirmek zorunda değilsiniz. Kontrol ettiğiniz zamandan *biraz daha iyi* hale getirmeniz yeterlidir. Elbette bu, bir modüle *eklediğiniz* herhangi bir kodun temiz olması gerektiği anlamına gelir. Ayrıca, modülü tekrar kontrol etmeden önce en az bir şeyi daha temizlediğiniz anlamına gelir. Basitçe bir değişkenin adını iyileştirebilir veya uzun bir işlevi iki küçük işleve bölebilirsiniz. Döngüsel bir bağımlılığı kırabilir veya ilkeyi ayrıntıdan ayırmak için bir arabirim ekleyebilirsiniz. + +Açıkçası, bu bana sıradan bir nezaket gibi geliyor - tuvaleti kullandıktan sonra ellerinizi yıkamak veya çöpü yere atmak yerine çöp kutusuna atmak gibi. Gerçekten de, kodda bir karışıklık bırakma eylemi, *çöp atmak* kadar sosyal olarak kabul edilemez olmalıdır. *Yapılmamış* bir şey olmalı. + +Ama bundan daha fazlası. Kendi kodumuzu önemsemek bir şeydir. Takımın kodunu önemsemek oldukça başka bir şey. Takımlar birbirlerine yardım eder ve birbirlerini temizlerler. İzci kuralına uyuyorlar çünkü bu sadece kendileri için değil herkes için iyi. + +[Uncle Bob](http://programmer.97things.oreilly.com/wiki/index.php/Uncle_Bob) Tarafından \ No newline at end of file diff --git a/tr/thing_09/README.md b/tr/thing_09/README.md new file mode 100644 index 00000000..c74727db --- /dev/null +++ b/tr/thing_09/README.md @@ -0,0 +1,21 @@ +# Başkalarını Suçlamadan Önce Kodunuzu Kontrol Edin + +Geliştiriciler — hepimiz! — genellikle kendi kodumuzun bozulduğuna inanmakta güçlük çekeriz. O kadar ihtimal dışı ki, bir kez olsun, bozuk olan derleyici olmalı. + +Ancak gerçekte kodun derleyici, yorumlayıcı, işletim sistemi, uygulama sunucusu, veritabanı, bellek yöneticisi veya başka herhangi bir sistem yazılımı parçasındaki bir hata tarafından kırılması çok (çok) olağandışıdır. Evet, bu hatalar var, ancak inanmak isteyebileceğimizden çok daha az yaygınlar. + +Bir zamanlar bir döngü değişkenini optimize eden bir derleyici hatasıyla ilgili gerçek bir sorunum vardı, ancak derleyicimde veya işletim sistemimde birçok kez bir hata olduğunu hayal ettim. Her seferinde benim hatam olduğu ortaya çıktığında kendimi biraz aptal hissetmek için süreçte çok zamanımı, destek zamanımı ve yönetim zamanımı harcadım. + +Araçların yaygın olarak kullanıldığını, olgunlaştığını ve çeşitli teknoloji yığınlarında kullanıldığını varsayarsak, kaliteden şüphe etmek için çok az neden vardır. Tabii ki, araç erken bir sürümse veya dünya çapında yalnızca birkaç kişi tarafından kullanılıyorsa veya nadiren indirilen bir sürüm (0.1), Açık Kaynaklı Yazılım parçasıysa, yazılımdan şüphelenmek için iyi bir neden olabilir. (Aynı şekilde, ticari yazılımın alfa sürümü de şüpheli olabilir.) + +Derleyici hatalarının ne kadar nadir olduğu göz önüne alındığında, derleyicinin yanlış olduğunu kanıtlamaktansa, zamanınızı ve enerjinizi kodunuzdaki hatayı bulmaya harcamanız çok daha iyidir. Tüm olağan hata ayıklama tavsiyeleri geçerlidir, bu nedenle sorunu yalıtın, aramaları devre dışı bırakın, testlerle çevreleyin; arama kurallarını, paylaşılan kitaplıkları ve sürüm numaralarını kontrol edin; başkasına açıkla; yığın bozulmasına ve değişken tür uyumsuzluklarına dikkat edin; kodu farklı makinelerde ve hata ayıklama ve yayınlama gibi farklı yapı yapılandırmalarında deneyin. + +Kendi varsayımlarınızı ve başkalarının varsayımlarını sorgulayın. Farklı satıcılara ait araçlarda farklı varsayımlar yerleşik olabilir - aynı satıcıdan farklı araçlar da olabilir. Başka biri tekrarlayamayacağınız bir sorunu bildirdiğinde, gidin ve ne yaptıklarına bakın. Belki de hiç düşünmediğiniz bir şeyi yapıyorlar ya da farklı bir sırayla bir şeyler yapıyorlar. + +Kişisel bir kural olarak, sabitleyemediğim bir hatam varsa ve bunun derleyici olduğunu düşünmeye başlıyorum, o zaman yığın bozulması aramanın zamanı geldi. Bu, özellikle izleme kodunun eklenmesi sorunu hareket ettiriyorsa geçerlidir. + +Çok iş parçacıklı sorunlar, saçları griye çeviren ve makinede çığlık atmaya neden olan başka bir hata kaynağıdır. Basit kodu destekleyen tüm öneriler, bir sistem çok iş parçacıklı olduğunda çoğalır. Hata ayıklama ve birim testleri, bu tür hataları herhangi bir tutarlılıkla bulmak için güvenilemez, bu nedenle tasarımın basitliği çok önemlidir. + +Derleyiciyi suçlamak için acele etmeden önce, Sherlock Holmes'un tavsiyesini hatırlayın, "Bir kez imkansızı ortadan kaldırdığınızda, geriye kalan ne kadar imkansız olursa olsun, gerçek olmalı" ve bunu Dirk Gently'nin "Olası olmayanı bir kez ortadan kaldırdığınızda, geriye ne kaldıysa, ne kadar imkansız olursa olsun, gerçek olmalı." + +[Allan Kelly](http://programmer.97things.oreilly.com/wiki/index.php/Allan_Kelly) Tarafından \ No newline at end of file diff --git a/tr/thing_10/README.md b/tr/thing_10/README.md new file mode 100644 index 00000000..6309e322 --- /dev/null +++ b/tr/thing_10/README.md @@ -0,0 +1,29 @@ +# Araçlarınızı Özenle Seçin + +Modern uygulamalar çok nadiren sıfırdan oluşturulur. Birkaç iyi nedenden dolayı mevcut araçlar (bileşenler, kitaplıklar ve çerçeveler) kullanılarak birleştirilirler: + +- Uygulamaların boyutu, karmaşıklığı ve karmaşıklığı artarken bunları geliştirmek için mevcut süre kısalır. Daha fazla iş alanı kodu ve daha az altyapı kodu yazmaya odaklanabilirlerse, geliştiricilerin zamanını ve zekasını daha iyi kullanır. + +- Yaygın olarak kullanılan bileşenler ve çerçevelerin, şirket içinde geliştirilenlerden daha az hata içermesi muhtemeldir. + +- Web'de ücretsiz olarak sunulan çok sayıda yüksek kaliteli yazılım vardır, bu da daha düşük geliştirme maliyetleri ve gerekli ilgi ve uzmanlığa sahip geliştiricileri bulma olasılığının artması anlamına gelir. + +- Yazılım üretimi ve bakımı yoğun bir iştir, bu nedenle satın almak inşa etmekten daha ucuz olabilir. + +Ancak, uygulamanız için doğru araç karışımını seçmek, biraz düşünmeyi gerektiren zor bir iş olabilir. Aslında bir seçim yaparken aklınızda bulundurmanız gereken birkaç şey var: + +- Farklı araçlar, bağlamları hakkında farklı varsayımlara dayanabilir (ör. çevreleyen altyapı, kontrol modeli, veri modeli, iletişim protokolleri vb.), bu da uygulama ile araçlar arasında mimari uyumsuzluğa yol açabilir. Böyle bir uyumsuzluk, kodu gereğinden fazla karmaşık hale getirecek saldırılara ve geçici çözümlere yol açar. + +- Farklı araçların farklı yaşam döngüleri vardır ve yeni işlevler, tasarım değişiklikleri ve hatta hata düzeltmeleri diğer araçlarla uyumsuzluklara neden olabileceğinden, bunlardan birini yükseltmek son derece zor ve zaman alıcı bir görev haline gelebilir. Araç sayısı arttıkça sorun daha da kötüleşebilir. + +- Bazı araçlar, genellikle çok hızlı bir şekilde kontrolden çıkabilen bir veya daha fazla XML dosyası aracılığıyla oldukça fazla yapılandırma gerektirir. Uygulama, tamamı XML'de ve bazı programlama dillerinde birkaç garip kod satırında yazılmış gibi görünebilir. Konfigürasyonel karmaşıklık, uygulamanın bakımını ve genişletilmesini zorlaştıracaktır. + +- Satıcı kilitlenmesi, büyük ölçüde belirli satıcı ürünlerine bağlı olan kodlar, onlar tarafından birkaç açıdan kısıtlandığında ortaya çıkar: sürdürülebilirlik, performans, gelişme yeteneği, fiyat, vb. + +- Özgür yazılım kullanmayı planlıyorsanız, bunun o kadar da özgür olmadığını keşfedebilirsiniz. Mutlaka ucuz olmayacak olan ticari destek satın almanız gerekebilir. + +- Lisans koşulları, özgür yazılım için bile önemlidir. Örneğin, bazı şirketlerde viral doğası nedeniyle GNU lisans koşulları kapsamında lisanslanan yazılımların kullanılması kabul edilemez - yani, onunla geliştirilen yazılım kaynak koduyla birlikte dağıtılmalıdır. + +Bu sorunları azaltmak için kişisel stratejim, yalnızca kesinlikle gerekli araçları kullanarak küçük bir başlangıç yapmaktır. Genellikle ilk odak noktası, örneğin dağıtılmış uygulamalar için hassas soketler kullanmak yerine bazı ara katman yazılımları kullanarak, düşük seviyeli altyapı programlaması (ve sorunları) ile meşgul olma ihtiyacını ortadan kaldırmaktır. Ve sonra gerekirse daha fazlasını ekleyin. Arayüzler ve katmanlama yoluyla harici araçları iş alanı nesnelerimden ayırma eğilimindeyim, böylece aracımı biraz zahmetle değiştirmem gerekirse değiştirebilirim. Bu yaklaşımın olumlu bir yan etkisi, genellikle başlangıçta tahmin edilenden daha az harici araç kullanan daha küçük bir uygulama ile sonuçlanmasıdır. + +[Giovanni Asproni](http://programmer.97things.oreilly.com/wiki/index.php/Giovanni_Asproni) Tarafından \ No newline at end of file diff --git a/tr/thing_11/README.md b/tr/thing_11/README.md new file mode 100644 index 00000000..7997ac1a --- /dev/null +++ b/tr/thing_11/README.md @@ -0,0 +1,40 @@ +# Domain Dilindeki Kod + +İki kod tabanını hayal edin. Karşılaştığınız birinde: + +``` +if (portfolioIdsByTraderId.get(trader.getId()) + .containsKey(portfolio.getId())) {...} +``` + +Bu kodun ne işe yaradığını merak ederek kafanı kaşıyorsun. Bir tüccar nesnesinden bir kimlik alıyor gibi görünüyor, bunu görünüşte bir haritadan harita çıkarmak için kullanıyor ve ardından iç haritada bir portföy nesnesinden başka bir kimliğin olup olmadığını görüyor. Kafanı biraz daha kaşıyorsun. portfolioIdsByTraderId tanımına baktığınızda şunu keşfedersiniz: + +``` +Map> portfolioIdsByTraderId; +``` + +Yavaş yavaş, bunun bir tüccarın belirli bir portföye erişimi olup olmadığıyla ilgili olabileceğini anlayacaksınız. Ve elbette, bir yatırımcının belirli bir portföye erişimi olup olmadığını umursayan bir şey olduğunda, aynı arama parçasını veya daha büyük olasılıkla benzer ama çok farklı bir kod parçasını bulacaksınız. + +Diğer kod tabanında bununla karşılaşırsınız: + +``` +if (trader.canView(portfolio)) {...} +``` + +Kafa kaşımak yok. Bir tüccarın nasıl bildiğini bilmenize gerek yok. Belki de bu haritalardan biri içeride bir yere gizlenmiştir. Ama bu tüccarın işi, senin değil. + +Şimdi bu kod tabanlarından hangisinde çalışmayı tercih ederdiniz? + +Bir zamanlar sadece çok temel veri yapılarımız vardı: bitler, baytlar ve karakterler (gerçekten sadece baytlar ama biz bunları harfler ve noktalama işaretleriymiş gibi yapardık). Ondalık sayılar biraz zordu çünkü 10 tabanlı sayılarımız ikili sistemde pek iyi çalışmıyor, bu yüzden birkaç boyutta kayan nokta tipimiz vardı. Ardından diziler ve dizeler geldi (gerçekten sadece farklı diziler). Sonra yığınlar, kuyruklar, karmalar ve bağlantılı listeler, atlama listeleri ve *gerçek dünyada olmayan* pek çok başka heyecan verici veri yapısı vardı. "Bilgisayar bilimi", gerçek dünyayı kısıtlayıcı veri yapılarımızla eşleştirmek için çok çaba harcamakla ilgiliydi. Gerçek gurular bunu nasıl yaptıklarını bile hatırlayabiliyorlardı. + +Sonra kullanıcı tanımlı türlerimiz var! Tamam, bu haber değil ama oyunu biraz değiştiriyor. Alan adınız tüccarlar ve portföyler gibi kavramlar içeriyorsa, bunları örneğin Tüccar ve Portföy adı verilen türlerle modelleyebilirsiniz. Ancak bundan daha da önemlisi, etki alanı terimlerini kullanarak *aralarındaki ilişkileri* modelleyebilirsiniz. + +Etki alanı terimlerini kullanarak kodlama yapmazsanız, buradaki *this* int'nin bir yatırımcıyı tanımlamanın yolu anlamına geldiğini, oysa oradaki *that* int'nin bir portföy tanımlamanın yolu anlamına geldiğini anlayan bir gizli okuma oluşturursunuz. (Karıştırmamak en iyisi!) Ve algoritmik bir snippet ile bir iş konseptini ("Bazı yatırımcıların bazı portföyleri görüntülemesine izin verilmez - bu yasa dışıdır") temsil ediyorsanız, diyelim ki bir anahtar haritasında bir varlık ilişkisi var, denetim ve uyumluluk adamlarına herhangi bir iyilik yapmıyorsunuz demektir. . + +Sıradaki yazılımcı sırrın içinde olmayabilir, o halde neden bunu açıklığa kavuşturmuyorsunuz? Bir anahtarın varlık kontrolü yapan başka bir anahtarı aramak için kullanılması çok açık değildir. Çıkar çatışmasını önleyen iş kurallarının burada uygulandığını birisi nasıl sezebilir? + +Etki alanı kavramlarını kodunuzda açık hale getirmek, diğer yazılımcıların, bir etki alanı hakkında anladıklarına bir algoritmayı güçlendirmeye çalışmaktan çok daha kolay bir şekilde kodun *niyetini* elde edebilecekleri anlamına gelir. Bu aynı zamanda, etki alanı modeli geliştiğinde ki bu, etki alanına ilişkin anlayışınız arttıkça artacaktır, kodu geliştirmek için iyi bir konumdasınız demektir. İyi bir kapsülleme ile birleştiğinde, kuralın yalnızca bir yerde var olma ve bağımlı kodlardan herhangi biri daha akıllıca olmadan değiştirebilme şansınız yüksektir. + +Birkaç ay sonra kod üzerinde çalışmak için gelen yazılımcı size teşekkür edecek. Birkaç ay sonra gelen yazılımcı siz olabilirsiniz. + +[Dan North](http://programmer.97things.oreilly.com/wiki/index.php/Dan_North) Tarafından \ No newline at end of file diff --git a/tr/thing_12/README.md b/tr/thing_12/README.md new file mode 100644 index 00000000..4c668f2d --- /dev/null +++ b/tr/thing_12/README.md @@ -0,0 +1,17 @@ +# Kod Tasarımdır + +Yarın uyandığınızı ve inşaat sektörünün yüzyılın atılımını yaptığını öğrendiğinizi hayal edin. Milyonlarca ucuz, inanılmaz hızlı robot, malzemeleri hiç yoktan üretebilir, sıfıra yakın bir güç maliyetine sahip olabilir ve kendilerini onarabilir. Ve daha da iyi hale geliyor: Bir inşaat projesi için net bir plan verildiğinde, robotlar onu insan müdahalesi olmadan ihmal edilebilir bir maliyetle inşa edebilirler. + +İnşaat sektörü üzerindeki etkisi tahmin edilebilir, ancak yukarı yönde ne olur? İnşaat maliyetleri ihmal edilebilir olsaydı, mimarların ve tasarımcıların davranışları nasıl değişirdi? Günümüzde fiziksel modeller ve bilgisayar modelleri inşa edilmekte ve inşaata yatırım yapmadan önce titizlikle test edilmektedir. İnşaat aslında ücretsiz olsaydı rahatsız olur muyduk? Başka çıkarımlar da var. Modası geçmiş modellerle birlikte, bitmemiş tasarımlar, nihai hedefe bir yaklaşım üzerine tekrar tekrar inşa edilerek ve geliştirilerek gelişir. Sıradan bir gözlemci, bitmemiş bir tasarımı bitmiş bir üründen ayırt etmekte zorlanabilir. + +Zaman çizgilerini tahmin etme yeteneğimiz kaybolacak. İnşaat maliyetleri, tasarım maliyetlerinden daha kolay hesaplanır, bir kiriş kurmanın yaklaşık maliyetini ve kaç tane kirişe ihtiyacımız olduğunu biliyoruz. Öngörülebilir görevler sıfıra doğru küçüldükçe, daha az öngörülebilir tasarım süresi baskın olmaya başlar. Sonuçlar daha hızlı üretilir, ancak güvenilir zaman çizgileri kayıp gider. + +Tabii ki, rekabetçi bir ekonominin baskıları hala geçerli. İnşaat maliyetleri ortadan kaldırıldığında, bir tasarımı hızla tamamlayabilen bir şirket pazarda avantaj elde eder. Tasarımın hızlı yapılması, mühendislik firmalarının temel itici gücü haline gelir. Kaçınılmaz olarak, tasarıma derinden aşina olmayan biri, doğrulanmamış bir sürüm görecek, erken piyasaya sürmenin pazar avantajını görecek ve "Bu yeterince iyi görünüyor" diyecektir. + +Bazı ölüm kalım projeleri daha gayretli olacak, ancak çoğu durumda tüketiciler eksik tasarım yüzünden acı çekmeyi öğreniyor. Şirketler, sattıkları kırık binaları ve araçları 'düzeltmek' için her zaman sihirli robotlarımızı gönderebilirler. Tüm bunlar, şaşırtıcı bir şekilde mantık dışı bir sonuca işaret ediyor: Tek öncülümüz, inşaat maliyetlerinde önemli bir düşüş oldu ve bunun sonucunda *kalite daha da kötüleşti*. + +Yukarıdaki hikayenin yazılımda ortaya çıkması bizi şaşırtmamalı. Kodun tasarım olduğunu kabul edersek mekanik yerine daha çok yaratıcı bir süreç *yazılım krizi* olarak açıklanır. Artık bir *tasarım krizimiz var*: Kaliteli, onaylanmış tasarımlara olan talep, onları yaratma kapasitemizi aşıyor. Eksik tasarımı kullanma baskısı güçlüdür. + +Neyse ki bu model nasıl daha iyi olabileceğimize dair ipuçları da sunuyor. Fiziksel simülasyonlar otomatik teste eşittir; yazılım tasarımı, acımasız bir dizi testle doğrulanana kadar tamamlanmış sayılmaz. Bu tür testleri daha etkili kılmak için, büyük sistemlerin devasa durum uzayını dizginlemenin yollarını buluyoruz. İyileştirilmiş diller ve tasarım uygulamaları bize umut veriyor. Son olarak, kaçınılmaz bir gerçek var: Harika tasarımlar, kendilerini zanaatlarında ustalaşmaya adayan büyük tasarımcılar tarafından üretilir. Kodun da bundan bir farkı yok. + +[Ryan Brush](http://programmer.97things.oreilly.com/wiki/index.php/Ryan_Brush) Tarafından \ No newline at end of file diff --git a/tr/thing_13/README.md b/tr/thing_13/README.md new file mode 100644 index 00000000..58ca331a --- /dev/null +++ b/tr/thing_13/README.md @@ -0,0 +1,15 @@ +# Kod Düzeni Önemlidir + +Uzun bir süre önce, personelin zaten kodu değiştirmek için bir nedenleri olmadıkça girintiyi değiştirmesine izin verilmeyen bir Cobol sistemi üzerinde çalıştım, çünkü birisi bir satırın başındaki özel sütunlardan birine bir satırın kaymasına izin vererek bir şeyi bozdu. Bu, düzen yanıltıcı olsa bile uygulandı, ki bazen öyleydi, bu yüzden kodu çok dikkatli okumamız gerekiyordu çünkü ona güvenemedik. Politika, programcı sürüklemesinde bir servete mal olmuş olmalı. + +Hepimizin programlama zamanımızın çoğunu kod okumaya ve gezinmeye harcadığımızı gösteren araştırmalar var, değişikliğin *nerede* yapılacağı bulmak, aslında yazmaktan çok optimize etmek istediğimiz şey bu. + +- *Taraması kolay.* İnsanlar görsel desen eşleştirmede gerçekten iyiler (savanada aslanları tespit etmemiz gerektiğinden kalanlar), bu yüzden doğrudan alanla alakalı olmayan her şeyi yaparak kendime yardımcı olabilirim, çoğu ticari dilde gelen tüm "tesadüfi karmaşıklık", standartlaştırarak arka plana kaybolur. Aynı şekilde davranan kod aynı görünüyorsa, algısal sistemim farklılıkları seçmeme yardımcı olacaktır. Bu nedenle, bir sınıfın bölümlerinin bir derleme birimi içinde nasıl düzenleneceğine ilişkin kuralları da gözlemliyorum: sabitler, alanlar, genel yöntemler, özel yöntemler. + +- *Etkileyici düzen.* Kodumuzun yalnızca adımları listelemek yerine ne yaptığını olabildiğince açık bir şekilde ifade etmesi için doğru adları bulmaya zaman ayırmayı öğrendik, değil mi? Kodun düzeni de bu ifadenin bir parçasıdır. İlk adım, ekibin temel bilgiler için otomatik bir biçimlendirici üzerinde anlaşmasını sağlamaktır, ardından kodlama yaparken elle ayarlamalar yapabilirim. Aktif bir anlaşmazlık olmadıkça, bir ekip hızla ortak bir "el yapımı" stil üzerinde birleşecektir. Bir biçimlendirici niyetimi anlayamaz (bilmem gerekir ki, bir zamanlar bir tane yazmıştım) ve satır sonlarının ve gruplamaların sadece dilin sözdizimini değil, kodun amacını yansıtması benim için daha önemli. (Kevin McGuire beni otomatik kod biçimlendiricilere olan esaretimden kurtardı.) + +- *Kompakt format.* Bir ekrana ne kadar çok girebilirsem, dosyaları kaydırarak veya değiştirerek bağlamı bozmadan o kadar çok görebilirim, bu da kafamda daha az durum tutabileceğim anlamına gelir. Uzun prosedür yorumları ve çok sayıda boşluk, 8 karakterli adlar ve satır yazıcıları için anlamlıydı, ancak şimdi sözdizimi renklendirme ve çapraz bağlama yapan bir IDE'de yaşıyorum. Pikseller benim sınırlayıcı faktörümdür, bu yüzden herkesin kodu anlamama katkıda bulunmasını istiyorum. Düzenin kodu anlamama yardımcı olmasını istiyorum, ancak bundan daha fazlasını değil. + +Yazılımcı olmayan bir arkadaş bir keresinde kodun şiir gibi göründüğünü söylemişti. Gerçekten iyi bir koddan, metindeki her şeyin bir amacı olduğu ve fikri anlamama yardımcı olmak için orada olduğu hissini alıyorum. Ne yazık ki, kod yazmak şiir yazmakla aynı romantik imaja sahip değil. + +[Steve Freeman](http://programmer.97things.oreilly.com/wiki/index.php/Steve_Freeman) Tarafından diff --git a/tr/thing_14/README.md b/tr/thing_14/README.md new file mode 100644 index 00000000..25ecc057 --- /dev/null +++ b/tr/thing_14/README.md @@ -0,0 +1,15 @@ +# Kod İncelemeleri + +Kod incelemeleri yapmalısınız. Niye? Çünkü bunlar *kod kalitesini* artırır ve *hata oranını azaltır*. Ama mutlaka düşündüğünüz nedenlerden dolayı değil. + +Daha önce incelemelerle ilgili bazı kötü deneyimler yaşamış olabileceğinden, birçok yazılımcı kod incelemelerini sevmeme eğilimindedir. Üretime dağıtılmadan önce tüm kodların resmi bir incelemeden geçmesini gerektiren kuruluşlar gördüm. Bu incelemeyi genellikle mimar veya baş geliştirici yapar, *mimar her şeyi gözden geçirir* olarak da tanımlanabilir. Bu, yazılım geliştirme süreci kılavuzlarında belirtilmiştir, bu nedenle yazılımcılar buna uymak zorundadır. Böyle katı ve resmi bir sürece ihtiyaç duyan bazı kuruluşlar olabilir, ancak çoğu böyle değildir. Çoğu organizasyonda böyle bir yaklaşım ters etki yapar. Gözden geçirenler, şartlı tahliye kurulu tarafından yargılandıklarını hissedebilirler. Gözden geçirenlerin hem kodu okumak için zamana hem de sistemin tüm ayrıntılarını güncel tutmak için zamana ihtiyaçları vardır. Gözden geçirenler bu süreçte hızla tıkanabilir ve süreç kısa sürede dejenere olur. + +Koddaki hataları basitçe düzeltmek yerine, kod incelemelerinin amacı *bilgiyi paylaşmak* ve ortak kodlama yönergeleri oluşturmak olmalıdır. Kodunuzu diğer yazılımcılarla paylaşmak, toplu kod sahipliğini sağlar. Rastgele bir ekip üyesinin, ekibin geri kalanıyla birlikte *kodu incelemesine* izin verin. Hata aramak yerine kodu öğrenmeye ve anlamaya çalışarak gözden geçirmelisiniz. + +Kod incelemeleri sırasında nazik olun. Yorumların *yapıcı, yakıcı değil* olduğundan emin olun. Ekip üyeleri arasında kurumsal kıdemin kod incelemesini etkilemesini önlemek için inceleme toplantısı için farklı *inceleme rolleri* tanıtın. Rol örnekleri arasında, bir gözden geçirenin belgelere, diğerinin istisnalara ve üçüncü bir kişinin de işlevselliğe odaklanması sayılabilir. Bu yaklaşım, inceleme yükünü ekip üyeleri arasında dağıtmaya yardımcı olur. + +Her hafta düzenli bir *kod incelemesi* yapın. Bir inceleme toplantısında birkaç saat geçirin. İncelenen kişiyi her toplantıda basit bir tekrarlı deneme düzeninde döndürün. Her gözden geçirme toplantısında ekip üyeleri arasında rolleri değiştirmeyi de unutmayın. *Yeni başlayanları* kod incelemelerine dahil edin. Deneyimsiz olabilirler, ancak taze üniversite bilgileri farklı bir bakış açısı sağlayabilir. Deneyimleri ve bilgileri için *uzmanları dahil edin*. Hataya açık kodu daha hızlı ve daha doğru bir şekilde tanımlayacaklar. Ekip, araçlar tarafından kontrol edilen *kodlama kuralları* varsa, kod incelemeleri daha kolay akacaktır. Bu şekilde, kod inceleme toplantısında kod biçimlendirme asla tartışılmayacaktır. + +*Kod incelemelerini eğlenceli hale getirmek* belki de başarıya en önemli katkıdır. İncelemeler, inceleme yapan kişilerle ilgilidir. Gözden geçirme toplantısı acı verici veya sıkıcıysa, insanları motive etmek zor olacaktır. Bunu, asıl amacı ekip üyeleri arasında bilgi paylaşımı olan *gayri resmi bir kod incelemesi* yapın. Alaycı yorumları dışarıda bırakın ve bunun yerine bir pasta ya da kahverengi çantalı öğle yemeği getirin. + +[Mattias Karlsson](http://programmer.97things.oreilly.com/wiki/index.php/Mattias_Karlsson) Tarafından \ No newline at end of file diff --git a/tr/thing_15/README.md b/tr/thing_15/README.md new file mode 100644 index 00000000..e761cd62 --- /dev/null +++ b/tr/thing_15/README.md @@ -0,0 +1,25 @@ +# Akıllı Kodlama + +Yazılımın doğruluğu hakkında elle akıl yürütmeye çalışmak, koddan daha uzun ve koddan daha fazla hata içerme olasılığı daha yüksek olan resmi bir kanıtla sonuçlanır. Otomatik araçlar tercih edilir, ancak her zaman mümkün değildir. Aşağıdakiler bir orta yolu tanımlar: doğruluk hakkında yarı resmi olarak akıl yürütme. + +Temel yaklaşım, incelenen tüm kodu kısa bölümlere, örneğin bir fonksiyon çağrısı gibi tek bir satırdan on satırdan daha az bloklara bölmek ve bunların doğruluğunu tartışmaktır. Argümanların yalnızca şeytanın avukatlığını yapan içindeki yazılımcıyı ikna edecek kadar güçlü olması gerekir. + +Her uç noktada *programın durumu*(yani, program sayacı ve tüm "canlı" nesnelerin değerleri) kolayca açıklanan bir özelliği karşılayacak ve o bölümün işlevselliğinin (durum dönüşümü) tek bir görev olarak tanımlanması kolay olacak şekilde bir bölüm seçilmelidir, bunlar akıl yürütmeyi kolaylaştırır. Bu tür uç nokta özellikleri, fonksiyonlar için *önkoşul*, *sonkoşul*, döngüler ve sınıflar için (örneklerine göre) *değişmez* gibi kavramları genelleştirir. Bölümlerin mümkün olduğunca birbirinden bağımsız olması için çabalamak, akıl yürütmeyi kolaylaştırır ve bu bölümler değiştirileceği zaman vazgeçilmezdir. + +İyi bilinen (belki de daha az takip edilen) ve 'iyi' kabul edilen kodlama uygulamalarının çoğu, akıl yürütmeyi kolaylaştırır. Bu nedenle, yalnızca kodunuz hakkında akıl yürütme niyetiyle, daha iyi bir stil ve yapı düşünmeye başlarsınız. Şaşırtıcı olmayan bir şekilde, bu uygulamaların çoğu statik kod analizörleri tarafından kontrol edilebilir: + +- Uzak bölümleri son derece birbirine bağımlı hale getirdikleri için goto deyimlerini kullanmaktan kaçının. +- Değiştirilebilir global değişkenleri kullanmaktan kaçının çünkü bunları kullanan tüm bölümleri bağımlı hale getirir. +- Her değişken mümkün olan en küçük kapsama sahip olmalıdır. Örneğin, yerel bir nesne, ilk kullanımından hemen önce bildirilebilir. +- İlgili olduğunda nesneleri *değişmez(immutable)* yapın. +- Hem yatay hem de dikey boşluk kullanarak kodu okunabilir hale getirin. Örneğin, ilgili yapıları hizalamak ve iki bölümü ayırmak için boş bir çizgi kullanmak. +- Nesneler, türler, fonksiyonlar vb. için açıklayıcı (ancak nispeten kısa) adlar seçerek kodu kendi kendine belgeleyin. +- İç içe bir bölüme ihtiyacınız varsa, onu bir fonksiyon yapın. +- Fonksiyonlarınızı kısa tutun ve tek bir göreve odaklanın. Eski *24 satırlık sınır* hâlâ geçerlidir. Ekran boyutu ve çözünürlüğü değişse de, 1960'lardan bu yana insan bilişinde hiçbir şey değişmedi. +- Fonksiyonların birkaç parametresi olmalıdır (dört iyi bir üst sınırdır). Bu, işlevlere iletilen verileri kısıtlamaz: İlgili parametreleri tek bir nesnede gruplamak, *nesne değişmezlerinden* yararlanır ve tutarlılık ve tutarlılık gibi akıl yürütmeden tasarruf sağlar. +- Daha genel olarak, bir bloktan bir kitaplığa kadar her bir kod birimi *dar bir arayüze* sahip olmalıdır. Daha az iletişim, gerekli muhakemeyi azaltır. Bu, dahili durumu döndüren *alıcıların* bir yükümlülük olduğu anlamına gelir, çalışmak için bir nesneden bilgi istemeyin. Bunun yerine, nesneden zaten sahip olduğu bilgilerle işi yapmasını isteyin. Başka bir deyişle, *kapsülleme* tamamen ve yalnızca *dar arayüzler* ile ilgilidir. +- *değişmezler(invariants)* sınıfını korumak için, *ayarlayıcılar(setters)* bir nesnenin durumunu yöneten değişmezlerin kırılmasına izin verme eğiliminde olduğundan, *ayarlayıcıların* kullanılması önerilmez. + +Doğruluğu hakkında akıl yürütmenin yanı sıra, kodunuz hakkında tartışmak size onu anlamanızı sağlar. Kazandığınız bilgileri herkesin yararına iletin. + +[Yechiel Kimchi](http://programmer.97things.oreilly.com/wiki/index.php/Yechiel_Kimchi) Tarafından diff --git a/tr/thing_16/README.md b/tr/thing_16/README.md new file mode 100644 index 00000000..027ad907 --- /dev/null +++ b/tr/thing_16/README.md @@ -0,0 +1,15 @@ +# Yorumlar Üzerine Bir Yorum + +Üniversitedeki ilk programlama dersimde öğretmenim iki BASIC kodlama sayfası dağıttı. Tahtada, ödevde "Bir program yazın ve ortalama 10 bowling skoru yazın" yazıyordu. Sonra öğretmen odadan çıktı. Bu ne kadar zor olabilir? Son çözümümü hatırlamıyorum ama içinde bir 'FOR/NEXT' döngüsü olduğundan ve toplamda 15 satırdan uzun olamayacağından eminim. Kodlama sayfaları, bunu okuyan çocuklar için, evet, aslında bir bilgisayara girmeden önce uzunlamasına kod yazardık, her biri yaklaşık 70 satırlık koda izin verirdi. Öğretmenin bize neden iki sayfa vereceği konusunda kafam çok karıştı. El yazım her zaman acımasız olduğu için, stil için birkaç ekstra puan almayı umarak ikincisini kodumu çok düzgün bir şekilde yeniden kopyalamak için kullandım. + +Şaşırtıcı bir şekilde, bir sonraki dersin başında ödevi geri aldığımda, zar zor geçen bir not aldım. (Üniversitede geçirdiğim zamanın geri kalanında benim için bir kehanet olacaktı.) Özenle kopyalanmış kodumun üst kısmına karalanmış, "Yorum yok mu?" + +Öğretmenin de benim de programın ne yapması gerektiğini bilmemiz yeterli değildi. Görevin amacının bir kısmı, kodumun arkamdan gelen bir sonraki programcıya kendini açıklaması gerektiğini öğretmekti. Bu unutmadığım bir ders. + +Yorumlar kötü değil. Temel dallanma veya döngü yapıları kadar programlama için gereklidirler. Çoğu modern dilde, otomatik olarak bir API belgesi oluşturmak için uygun şekilde biçimlendirilmiş yorumları ayrıştıracak javadoc'a benzer bir araç bulunur. Bu çok iyi bir başlangıç, ancak neredeyse yeterli değil. Kodunuzun içinde, kodun ne yapması gerektiğine dair açıklamalar olmalıdır. Eski atasözüyle kodlama yapmak, "Yazması zorsa, okuması da zor olur", müşterinize, işvereninize, meslektaşlarınıza ve gelecekteki kendinize zarar verir. + +Öte yandan, yorumunuzda çok ileri gidebilirsiniz. Yorumlarınızın kodunuzu netleştirdiğinden emin olun, ancak onu gizlemeyin. Kodun neyi başarması gerektiğini açıklayan ilgili yorumları kodunuza serpiştirin. Başlık yorumlarınız, herhangi bir programcıya kodunuzu okumak zorunda kalmadan kullanmak için yeterli bilgi verirken, satır içi yorumlarınız bir sonraki geliştiriciye onu düzeltmede veya genişletmede yardımcı olmalıdır. + +Bir işte, üstümdekilerin verdiği bir tasarım kararına katılmadım. Genç programcıların sık sık yaptığı gibi, kendimi oldukça tuhaf hissederek, tasarımlarını kullanmamı söyleyen e-posta metnini dosyanın başlık yorum bloğuna yapıştırdım. Bu mağazadaki yöneticilerin, işlendiğinde kodu gerçekten inceledikleri ortaya çıktı. Bu benim *kariyer sınırlayıcı hareket* terimiyle ilk tanışmamdı. + +[Cal Evans](http://programmer.97things.oreilly.com/wiki/index.php/Cal_Evans) Tarafından \ No newline at end of file diff --git a/tr/thing_17/README.md b/tr/thing_17/README.md new file mode 100644 index 00000000..b14140c3 --- /dev/null +++ b/tr/thing_17/README.md @@ -0,0 +1,13 @@ +# Yalnızca Kodun Söyleyemediklerini Yorumlayın + +Teori ve pratik arasındaki fark pratikte teoride olduğundan daha fazladır, kesinlikle yorumlar için geçerli olan bir gözlem. Teoride, kodu yorumlamanın genel fikri kulağa değerli bir fikir gibi geliyor: Okuyucuya neler olup bittiğine dair bir ayrıntı, bir açıklama sunun. Yardımcı olmaktan daha yararlı ne olabilir? Bununla birlikte, pratikte, yorumlar genellikle bir felaket haline gelir. Diğer yazı türlerinde olduğu gibi, iyi yorumlar yazma becerisi vardır. Becerinin çoğu, onları ne zaman yazmayacağınızı bilmektir. + +Kod yanlış oluşturulduğunda, derleyiciler, yorumlayıcılar ve diğer araçlar kesinlikle itiraz edeceklerdir. Kod bir şekilde işlevsel olarak yanlışsa, incelemeler, statik analizler, testler ve üretim ortamındaki günlük kullanım çoğu hatayı giderecektir. Ama ya yorumlar? *Elements of Programming Style*'da Kernighan ve Plauger, "bir yorum yanlışsa, sıfır (veya negatif) değerdedir" demişlerdir. Yine de bu tür yorumlar genellikle kodlama hatalarının asla yapamayacağı şekilde bir kod tabanında çöp olur ve hayatta kalır. Sürekli bir dikkat dağınıklığı ve yanlış bilgi kaynağı, bir programcının düşüncesinde ince ama sürekli bir sürükleme sağlarlar. + +Teknik olarak yanlış olmayan, ancak koda değer katmayan yorumlara ne dersiniz? Bu tür yorumlar gürültüdür. Kodu papağan gibi tekrar eden yorumlar okuyucuya ekstra bir şey sunmaz, bir şeyi kodda ve tekrar doğal dilde belirtmek, onu daha doğru veya daha gerçek yapmaz. Yorumlanan kod yürütülebilir kod değildir, bu nedenle okuyucu veya çalışma zamanı için yararlı bir etkisi yoktur. Ayrıca çok çabuk bayatlar. Sürümle ilgili yorumlar ve yorum yapılan kod, sürüm oluşturma ve geçmişle ilgili soruları ele almaya çalışır. Bu sorular, sürüm kontrol araçları tarafından zaten (çok daha etkili bir şekilde) yanıtlanmıştır. + +Bir kod tabanında gürültülü yorumların ve yanlış yorumların yaygınlığı, programcıları tüm yorumları atlayarak veya onları gizlemek için aktif önlemler alarak görmezden gelmeye teşvik eder. Programcılar beceriklidir ve hasar olarak algılanan her şeyin etrafından dolaşırlar: yorumları yukarı katlamak; yorumların ve arka planın aynı renkte olması için renk şemasını değiştirme; yorumları filtrelemek için komut dosyası. Bir kod tabanını programcı yaratıcılığının bu tür yanlış uygulamalarından kurtarmak ve gerçek değeri olan herhangi bir yorumu gözden kaçırma riskini azaltmak için, yorumlara kodmuş gibi davranılmalıdır. Her yorum okuyucu için bir miktar değer katmalıdır, aksi takdirde kaldırılması veya yeniden yazılması israftır. + +O halde değer olarak nitelenen nedir? Yorumlar, kodun söylemediği ve söyleyemeyeceği bir şey söylemelidir. Bir kod parçasının zaten ne söylemesi gerektiğini açıklayan bir yorum, kodun kendisi için konuşması için kod yapısını veya kodlama kurallarını değiştirmeye yönelik bir davettir. Zayıf yöntem veya sınıf adlarını telafi etmek yerine, bunları yeniden adlandırın. Uzun işlevlerdeki bölümleri yorumlamak yerine, adları önceki bölümlerin amacını yakalayan daha küçük işlevleri çıkarın. Kod aracılığıyla mümkün olduğunca çok ifade etmeye çalışın. Kodda ifade edebileceğiniz ile toplamda ifade etmek istediğiniz şey arasındaki herhangi bir eksiklik, faydalı bir yorum için mantıklı bir aday haline gelir. Kodun söylemediklerini değil, söyleyemediklerini yorumlayın. + +[Kevlin Henney](http://programmer.97things.oreilly.com/wiki/index.php/Kevlin_Henney) Tarafından \ No newline at end of file diff --git a/tr/thing_18/README.md b/tr/thing_18/README.md new file mode 100644 index 00000000..9c3a57dc --- /dev/null +++ b/tr/thing_18/README.md @@ -0,0 +1,28 @@ +# Devamlı öğrenme + +İlginç zamanlarda yaşıyoruz. Geliştirme dünya geneline yayıldıkça, işinizi yapabilecek birçok insan olduğunu öğrenirsiniz. Pazarlanabilir olmayı öğrenmeye devam etmelisiniz. Aksi takdirde, bir gün size artık ihtiyaç duyulmayıncaya veya işiniz daha ucuz bir kaynağa devredilene kadar aynı işte sıkışıp kalan bir dinozor olursunuz. + +Peki bu konuda ne yaparsın? Bazı işverenler, beceri setinizi genişletmek için eğitim sağlayacak kadar cömerttir. Diğerleri herhangi bir eğitim için zaman veya para ayıramayabilir. Güvenli oynamak için kendi eğitiminizin sorumluluğunu almanız gerekir. + +İşte size öğrenmeye devam etmenin yollarının bir listesi. Bunların çoğu internette ücretsiz olarak bulunabilir: + +- Kitapları, dergileri, blogları, twitter feeds ve web sitelerini okuyun. Bir konuda daha derine inmek istiyorsanız, bir posta listesine veya haber grubuna katılmayı düşünün. +- Bir teknolojiye gerçekten dalmak istiyorsanız, biraz kod yazın. +- Her zaman bir akıl hocası ile çalışmayı deneyin, çünkü en iyi adam olmak eğitiminizi engelleyebilir. Herhangi birinden bir şeyler öğrenebilseniz de, sizden daha akıllı veya daha deneyimli birinden çok daha fazlasını öğrenebilirsiniz. Bir akıl hocası bulamıyorsanız, devam etmeyi düşünün. +- Sanal mentorlar kullanın. Web'de gerçekten sevdiğiniz yazarları ve geliştiricileri bulun ve yazdıkları her şeyi okuyun. Bloglarına abone olun. +- Kullandığınız araçları ve kütüphaneleri tanıyın. Bir şeyin nasıl çalıştığını bilmek, onu nasıl daha iyi kullanacağınızı bilmenizi sağlar. Açık kaynak iseler, gerçekten şanslısınız. Kaputun altında neler olduğunu görmek için kodda adım adım ilerlemek için hata ayıklayıcıyı kullanın. Gerçekten bazı akıllı insanlar tarafından yazılan ve gözden geçirilen kodu göreceksiniz. +- Bir hata yaptığınızda, bir hatayı düzelttiğinizde veya bir sorunla karşılaştığınızda, ne olduğunu gerçekten anlamaya çalışın. Muhtemelen başka biri de aynı sorunla karşılaşmış ve bunu web'de bir yere göndermiştir. Google burada gerçekten yararlıdır. +- Bir şeyi öğrenmenin gerçekten iyi bir yolu, onu öğretmek veya onun hakkında konuşmaktır. İnsanlar sizi dinleyecekleri ve size sorular soracakları zaman, öğrenmek için oldukça motive olacaksınız. İş yerinde, bir kullanıcı grubunda veya yerel bir konferansta bir öğle yemeğinde öğrenmeyi deneyin. +- İlgilendiğiniz bir dil, teknoloji veya disiplin için bir çalışma grubuna (desen topluluğu) veya yerel bir kullanıcı grubuna katılın veya başlayın. +- Konferanslara gidin. Ve gidemezseniz, birçok konferans konuşmalarını ücretsiz olarak çevrimiçi hale getirir. +- Uzun yola çıkmak? Podcast'leri dinleyin. +- Hiç kod tabanı üzerinde bir statik analiz aracı çalıştırdınız mı veya IDE'nizdeki uyarılara baktınız mı? Neyi ve nedenini bildirdiklerini anlayın. +- [Pragmatik Programcıların](http://www.pragprog.com/titles/tpp/the-pragmatic-programmer) tavsiyelerine uyun ve her yıl yeni bir dil öğrenin. En azından yeni bir teknoloji veya araç öğrenin. Dallanma, size mevcut teknoloji yığınınızda kullanabileceğiniz yeni fikirler verir. +- Öğrendiğiniz her şey teknoloji ile ilgili olmak zorunda değil. Gereksinimleri daha iyi anlamak ve iş sorununu çözmeye yardımcı olmak için çalıştığınız alanı öğrenin. Nasıl daha üretken olunacağını – nasıl daha iyi çalışılacağını öğrenmek başka bir iyi seçenektir. +- Okula geri dön. + +Neo'nun Matrix'te sahip olduğu yeteneğe sahip olmak ve sadece ihtiyacımız olan bilgiyi beynimize indirmek güzel olurdu. Ama yapmıyoruz, bu yüzden biraz zaman alacak. Uyandığınız her saati öğrenmek için harcamak zorunda değilsiniz. Her hafta biraz zaman, hiç yoktan iyidir. İş dışında bir hayat var (veya olmalı). + +Teknoloji hızlı değişiyor. Geride kalmayın. + +[Clint Shank](http://programmer.97things.oreilly.com/wiki/index.php/Clint_Shank) Tarafından \ No newline at end of file diff --git a/tr/thing_19/README.md b/tr/thing_19/README.md new file mode 100644 index 00000000..f98e5cfc --- /dev/null +++ b/tr/thing_19/README.md @@ -0,0 +1,21 @@ +# Kolaylık bir yetenek değildir + +İyi API'ler tasarlamanın önemi ve zorlukları hakkında çok şey söylendi. İlk seferde doğruyu bulmak zordur ve daha sonra değiştirmek daha da zordur. Çocuk yetiştirmek gibi bir şey. Deneyimli programcıların çoğu, iyi bir API'nin tutarlı bir soyutlama düzeyi izlediğini, tutarlılık ve simetri sergilediğini ve ifade edici bir dil için kelime dağarcığını oluşturduğunu öğrenmiştir. Ne yazık ki, yol gösterici ilkelerin farkında olmak otomatik olarak uygun davranışa dönüşmez. Tatlı yemek zararlıdır. + +Yukarıdan vaaz vermek yerine, defalarca karşılaştığım belirli bir API tasarım 'stratejisini' seçmek istiyorum: uygunluk argümanı. Genellikle aşağıdaki 'anlayışlardan' biriyle başlar: + +- Bu tek şeyi yapmak için diğer sınıfların iki ayrı çağrı yapmasını istemiyorum. +- Bu yöntemle hemen hemen aynıysa neden başka bir yöntem yapayım? Sadece basit bir anahtar ekleyeceğim. +- Bak, çok kolay: İkinci string parametresi ".txt" ile bitiyorsa, metod otomatik olarak ilk parametrenin bir dosya ismi olduğunu varsayar, yani gerçekten iki metoda ihtiyacım yok. + +İyi niyetli olsalar da, bu tür argümanlar API kullanılarak kodun okunabilirliğini azaltmaya eğilimlidir. Gibi bir yöntem çağırma + +``` +parser.processNodes(text, false); +``` + +uygulamayı bilmeden veya en azından belgelere danışmadan neredeyse anlamsızdır. Bu yöntem muhtemelen arayanın rahatlığının aksine uygulayıcının rahatlığı için tasarlanmıştır - "Arayanın iki ayrı arama yapmak zorunda kalmasını istemiyorum", "İki ayrı yöntemi kodlamak istemedim" olarak çevrilmiştir." Sıkıcılığın, hantallığın veya beceriksizliğin panzehiri olması amaçlanıyorsa, temelde yanlış bir şey yoktur. Bununla birlikte, bu konuda biraz daha dikkatli düşünürsek, bu semptomların panzehiri verimlilik, tutarlılık ve zarafettir, rahatlık değil. API'lerin temeldeki karmaşıklığı gizlemesi gerekiyor, bu nedenle gerçekçi bir şekilde iyi API tasarımının biraz çaba gerektirmesini bekleyebiliriz. Tek bir büyük yöntemin yazılması, iyi düşünülmüş bir dizi işlemden kesinlikle daha uygun olabilir, ancak kullanımı daha kolay olur mu? + +Bir dil olarak API metaforu, bu durumlarda bizi daha iyi tasarım kararlarına yönlendirebilir. Bir API, faydalı soruları sormak ve yanıtlamak için yeterli kelime dağarcığının üstündeki sonraki katmanı veren, ifade edici bir dil sağlamalıdır. Bu, sorulmaya değer olabilecek her soru için tam olarak bir yöntem veya fiil sağlaması gerektiği anlamına gelmez. Farklı bir kelime dağarcığı, anlamdaki incelikleri ifade etmemizi sağlar. Örneğin, temelde aynı işlem olarak görülebilse de, sadece farklı hızlarda yürütülmüş olsa da, yürü(doğru) yerine koş demeyi tercih ederiz. Tutarlı ve iyi düşünülmüş bir API sözlüğü, bir sonraki katmanda kodun anlamlı ve anlaşılması kolay olmasını sağlar. Daha da önemlisi, şekillendirilebilir bir sözcük dağarcığı, diğer programcıların API'yi tahmin etmediğiniz şekillerde kullanmasına olanak tanır, API kullanıcıları için gerçekten büyük bir kolaylık! Bir dahaki sefere, birkaç şeyi tek bir API yönteminde toplamaya can attığınızda, bu kadar sık istenen bir işlem için gerçekten uygun görünse de, İngilizce dilinde 'MakeUpYourRoomBeQuietAndDoYourHomeWork' için tek bir kelime olmadığını unutmayın. + +[Gregor Hohpe](http://programmer.97things.oreilly.com/wiki/index.php/Gregor_Hohpe) Tarafından \ No newline at end of file diff --git a/tr/thing_20/README.md b/tr/thing_20/README.md new file mode 100644 index 00000000..63b0101f --- /dev/null +++ b/tr/thing_20/README.md @@ -0,0 +1,15 @@ +# Erken ve Sıkça Dağıtın + +Dağıtım ve kurulum süreçlerinde hata ayıklama, genellikle bir projenin sonuna kadar ertelenir. Bazı projelerde, kurulum araçları yazmak, görevi "gerekli bir kötülük" olarak üstlenen bir yayın mühendisine devredilir. Her şeyin çalıştığından emin olmak için el yapımı bir ortamda incelemeler ve gösteriler yapılır. Sonuç olarak ekip, değişiklik yapmak için çok geç olana kadar dağıtım süreci veya dağıtılan ortamla ilgili hiçbir deneyim elde edemez. + +Kurulum/dağıtım süreci, müşterinin gördüğü ilk şeydir ve basit bir kurulum/dağıtım süreci, güvenilir (veya en azından hata ayıklaması kolay) bir üretim ortamına sahip olmanın ilk adımıdır. Dağıtılan yazılım, müşterinin kullanacağı şeydir. Dağıtımın uygulamayı doğru bir şekilde kurmasını sağlamazsanız, müşteriniz yazılımınızı tam olarak kullanmaya başlamadan önce onlara sorular yönelteceksiniz. + +Projenize bir kurulum süreci ile başlamak, siz ürün geliştirme döngüsü boyunca ilerlerken süreci geliştirmeniz için size zaman ve kurulumu kolaylaştırmak için uygulama kodunda değişiklik yapma şansı verecektir. Kurulum sürecini düzenli aralıklarla temiz bir ortamda çalıştırmak ve test etmek, geliştirme veya test ortamlarına dayanan kodda varsayımlarda bulunmadığınızı da kontrol eder. + +Dağıtımı en sona koymak, koddaki varsayımları çözmek için dağıtım sürecinin daha karmaşık olması gerekebileceği anlamına gelir. Bir ortam üzerinde tam kontrole sahip olduğunuz bir IDE'de harika bir fikir gibi görünen şey, çok daha karmaşık bir dağıtım süreci sağlayabilir. Tüm takasları bir an önce bilmek daha iyidir. + +Bir geliştiricinin dizüstü bilgisayarında çalışan bir uygulama görmekle karşılaştırıldığında, "dağıtabilmenin" erken dönemde çok fazla iş değeri yok gibi görünse de, basit gerçek şu ki, uygulamanızı hedef ortamda gösterene kadar, iş değeri sunmadan önce yapılacak çok iş var. Bir dağıtım sürecini erteleme gerekçeniz bunun önemsiz olmasıysa, düşük maliyetli olduğu için yine de yapın. Çok karmaşıksa veya çok fazla belirsizlik varsa, uygulama koduyla yapacağınızı yapın: ilerledikçe dağıtım sürecini deneyin, değerlendirin ve yeniden düzenleyin. + +Kurulum/dağıtım süreci, müşterilerinizin veya profesyonel hizmet ekibinizin üretkenliği için çok önemlidir; bu nedenle, devam ederken bu süreci test ediyor ve yeniden düzenlemelisiniz. Bir proje boyunca kaynak kodunu test eder ve yeniden düzenleriz. Dağıtım daha azını hak etmiyor. + +[Steve Berczuk](http://programmer.97things.oreilly.com/wiki/index.php/Steve_Berczuk) Tarafından \ No newline at end of file diff --git a/tr/thing_21/README.md b/tr/thing_21/README.md new file mode 100644 index 00000000..75d8af87 --- /dev/null +++ b/tr/thing_21/README.md @@ -0,0 +1,17 @@ +# İş İstisnalarını Tekniklerden Ayırın + +Çalışma zamanında işlerin ters gitmesinin temelde iki nedeni vardır: uygulamayı kullanmamızı engelleyen teknik sorunlar ve uygulamayı yanlış kullanmamızı engelleyen iş mantığı. LISP, Java, Smalltalk ve C# gibi çoğu modern dil, bu iki durumu belirtmek için istisnalar kullanır. Bununla birlikte, iki durum o kadar farklıdır ki, dikkatlice ayrı tutulmaları gerekir. Her ikisini de aynı istisna hiyerarşisini kullanarak temsil etmek, aynı istisna sınıfından bahsetmemek, olası bir karışıklık kaynağıdır. + +Bir programlama hatası olduğunda çözülemeyen bir teknik sorun ortaya çıkabilir. Örneğin, 17 boyutundaki bir diziden 83 numaralı öğeye erişmeye çalışırsanız, program açıkça yoldan çıkar ve bazı istisnalar ortaya çıkmalıdır. Daha ince sürüm, uygun olmayan argümanlarla bazı kütüphane kodlarını çağırıyor ve aynı duruma kütüphanenin içinde neden oluyor. + +Kendi başınıza sebep olduğunuz bu durumları çözmeye çalışmak hata olur. Bunun yerine, istisnanın en yüksek mimari düzeye çıkmasına izin veriyoruz ve bir işlemi geri alma, günlüğe kaydetme ve yönetimi uyarma ve geri raporlama gibi sistemin güvenli bir durumda olmasını sağlamak için bazı genel istisna işleme mekanizmalarının elinden geleni yapmasına izin veriyoruz ( kibarca) kullanıcıya. + +Bu durumun bir çeşidi, "kütüphane durumunda" olduğunuzda ve bir arayan, örneğin tamamen tuhaf bir argüman ileterek veya bağımlı bir nesneyi düzgün bir şekilde ayarlayamayarak, yönteminizin sözleşmesini bozduğunda ortaya çıkar. Bu, 17'den 83. öğeye erişimle aynı düzeydedir: arayan kişinin kontrol etmesi gerekirdi; bunu yapmamak, istemci tarafında bir programcı hatasıdır. Uygun yanıt, teknik bir istisna oluşturmaktır. + +Yanıt vermeyen bir veritabanı gibi yürütme ortamındaki bir sorun nedeniyle programın devam edememesi farklı ancak yine de teknik bir durumdur. Bu durumda, altyapının durumu çözmek için elinden geleni yaptığını, bağlantıları onararak ve makul sayıda yeniden deneme yaptığını ve başarısız olduğunu varsaymalısınız. Sebep farklı olsa bile, çağıran kodun durumu benzerdir: bu konuda yapabileceği çok az şey vardır. Bu nedenle, genel istisna işleme mekanizmasına kadar artmasına izin verdiğimiz bir istisna aracılığıyla durumu işaret ederiz. + +Bunların aksine, etki alanı mantıksal bir nedenle aramayı tamamlayamayacağınız bir durumumuz var. Bu durumda, bir istisna olan, yani olağandışı ve istenmeyen, ancak tuhaf olmayan veya programatik olarak hatalı olmayan bir durumla karşılaştık. Örneğin, yeterli bakiyesi olmayan bir hesaptan para çekmeye çalışırsam. Başka bir deyişle, bu tür bir durum sözleşmenin bir parçasıdır ve bir istisna atmak, yalnızca modelin bir parçası olan ve müşterinin bilmesi ve işlemeye hazır olması gereken *alternatif bir dönüş yolu*dur. Bu durumlar için, müşterinin durumu kendi şartlarında ele alabilmesi için belirli bir istisna veya ayrı bir istisna hiyerarşisi oluşturmak uygundur. + +Teknik istisnaları ve iş istisnalarını aynı hiyerarşide karıştırmak, ayrımı bulanıklaştırır ve arayanın yöntem sözleşmesinin ne olduğu, çağrıdan önce hangi koşulların sağlanması gerektiği ve hangi durumları ele alması gerektiği konusunda kafasını karıştırır. Vakaları ayırmak netlik sağlar ve teknik istisnaların bazı uygulama çerçeveleri tarafından ele alınma şansını artırırken, iş alanı istisnaları aslında müşteri kodu tarafından değerlendirilir ve işlenir. + +[Dan Bergh Johnsson](http://programmer.97things.oreilly.com/wiki/index.php/Dan_Bergh_Johnsson) Tarafından \ No newline at end of file diff --git a/tr/thing_22/README.md b/tr/thing_22/README.md new file mode 100644 index 00000000..ab47b0a3 --- /dev/null +++ b/tr/thing_22/README.md @@ -0,0 +1,25 @@ +# Bol Bol Kasıtlı Uygulama Yapın + +Kasıtlı uygulama sadece bir görevi yerine getirmek değildir. Kendinize "Bu görevi neden yapıyorum?" diye sorarsanız. ve cevabınız "Görevi tamamlamak için" ise, o zaman kasıtlı bir uygulama yapmıyorsunuz demektir. + +Bir görevi yerine getirme yeteneğinizi geliştirmek için kasıtlı olarak pratik yaparsınız. Beceri ve teknikle ilgili. Kasıtlı uygulama tekrar anlamına gelir. Görevin bir veya daha fazla yönüne ilişkin uzmanlığınızı artırmak amacıyla görevi gerçekleştirmek anlamına gelir. Tekrarı tekrar etmek demektir. Yavaşça, tekrar tekrar. İstediğiniz ustalık seviyesine ulaşana kadar. Görevi tamamlamak için değil, görevde ustalaşmak için kasıtlı olarak pratik yaparsınız. + +Ücretli geliştirmenin temel amacı bir ürünü bitirmek iken, kasıtlı uygulamanın temel amacı performansınızı iyileştirmektir. Onlar aynı değil. Kendinize sorun, başka birinin ürününü geliştirmek için ne kadar zaman harcıyorsunuz? Kendini ne kadar geliştiriyorsun? + +Uzmanlık kazanmak için ne kadar bilinçli bir uygulama gerekiyor? + +- Peter Norvig "Bu 10.000 saat [...] sihirli sayı olabilir" diye [yazıyor](http://norvig.com/21-days.html). +- *Yalın Yazılım Geliştirmede Öncü* Mary Poppendieck, "Elit sanatçıların uzman olmaları için en az 10.000 saat kasıtlı odaklı uygulama gerektiğini" belirtiyor. + +Uzmanlık zaman içinde kademeli olarak gelir, hepsi 10.000'inci saatte bir kerede değil! Yine de 10.000 saat çok fazla: 10 yıl boyunca haftada yaklaşık 20 saat. Bu düzeyde bağlılık göz önüne alındığında, yalnızca uzman malzeme olmadığınızdan endişe ediyor olabilirsiniz. Sen. Yücelik büyük ölçüde bilinçli bir seçim meselesidir. *Seçim sizin.* Son yirmi yılda yapılan araştırmalar, uzmanlık edinmedeki ana faktörün kasıtlı uygulama yapmak için harcanan zaman olduğunu göstermiştir. Doğuştan gelen yetenek ana faktör *değildir*. + +- Mary: "Uzman performans araştırmacıları arasında, doğuştan gelen yeteneğin bir eşikten çok daha fazlasını hesaba katmadığı konusunda geniş bir fikir birliği var; bir spora veya mesleğe başlamak için minimum miktarda doğal yeteneğe sahip olmanız gerekir. Bundan sonra insanlar, üstün olanlar, en çok çalışanlardır." + +Halihazırda uzman olduğunuz bir şeyi kasıtlı olarak uygulamanın pek bir anlamı yok. Kasıtlı uygulama, iyi olmadığınız bir şeyi uygulamak anlamına gelir. + +- Peter: "[Uzmanlığı geliştirmenin] anahtarı * müzakereci* uygulamadır: sadece tekrar tekrar yapmak değil, aynı zamanda mevcut yeteneğinizin hemen ötesinde bir görevle kendinize meydan okumak, denemek, bunu yaparken ve yaptıktan sonra performansınızı analiz etmek , ve herhangi bir hatayı düzeltmek." +- Mary: "Kasıtlı uygulama, iyi olduğunuz şeyi yapmak anlamına gelmez; kendinize meydan okumak, iyi olmadığınız şeyi yapmak anlamına gelir. Bu yüzden mutlaka eğlenceli değil." + +Kasıtlı uygulama öğrenme ile ilgilidir. Sizi değiştiren öğrenme hakkında; davranışınızı değiştiren öğrenme. İyi şanlar. + +[Jon Jagger](http://programmer.97things.oreilly.com/wiki/index.php/Jon_Jagger) Tarafından \ No newline at end of file diff --git a/tr/thing_23/README.md b/tr/thing_23/README.md new file mode 100644 index 00000000..3224c602 --- /dev/null +++ b/tr/thing_23/README.md @@ -0,0 +1,17 @@ +# Etki Alanına Özgü Diller + +Satranç oyuncuları, anaokulu öğretmenleri veya sigorta acenteleri gibi herhangi bir alandaki uzmanların bir tartışmasını her dinlediğinizde, kelime dağarcığının günlük dilden oldukça farklı olduğunu fark edeceksiniz. Bu, alana özgü dillerin (DSL'ler) neyle ilgili olduğunun bir parçasıdır: Belirli bir alan, o alana özgü şeyleri tanımlamak için özel bir kelime dağarcığına sahiptir. + +Yazılım dünyasında, DSL'ler, sınırlı kelime dağarcığına ve dilbilgisine sahip bir alana özgü bir dilde, okunabilir, anlaşılabilir ve umarım etki alanı uzmanları tarafından yazılabilir, yürütülebilir ifadelerle ilgilidir. Yazılım geliştiricileri veya bilim adamlarını hedef alan DSL'ler uzun süredir ortalıkta dolaşmaktadır. + +Örneğin, yapılandırma dosyalarında bulunan Unix 'küçük diller' ve LISP makrolarının gücüyle oluşturulan diller daha eski örneklerden bazılarıdır. + +DSL'ler genellikle *dahili* veya *harici* olarak sınıflandırılır: + +- **Dahili DSL'ler**, sözdizimi daha çok doğal dile benzeyecek şekilde bükülmüş genel amaçlı bir programlama dilinde yazılmıştır. Bu, daha fazla sözdizimsel şeker ve biçimlendirme olanakları (örn., Ruby ve Scala) sunan diller için, sunmayan diğer dillere (örn. Java) göre daha kolaydır. Çoğu dahili DSL, mevcut API'leri, kitaplıkları veya iş kodunu sarar ve işlevselliğe daha az akıl almaz erişim için bir sarmalayıcı sağlar. Sadece çalıştırılarak doğrudan çalıştırılabilirler. Uygulamaya ve etki alanına bağlı olarak, veri yapıları oluşturmak, bağımlılıkları tanımlamak, süreçleri veya görevleri çalıştırmak, diğer sistemlerle iletişim kurmak veya kullanıcı girdisini doğrulamak için kullanılırlar. Dahili bir DSL'nin sözdizimi, ana bilgisayar dili tarafından sınırlandırılmıştır. Ana bilgisayar dilini DSL'nize uyarlamanıza yardımcı olabilecek birçok kalıp (örneğin, ifade oluşturucu, yöntem zincirleme ve açıklama ekleme) vardır. Ana bilgisayar dili yeniden derleme gerektirmiyorsa, bir etki alanı uzmanıyla yan yana çalışarak oldukça hızlı bir şekilde dahili bir DSL geliştirilebilir. + +- **Harici DSL'ler** dilin metinsel veya grafiksel ifadeleridir, metinsel DSL'ler grafiksel olanlardan daha yaygın olma eğiliminde olsa da. Metinsel ifadeler, sözlük, ayrıştırıcı, model dönüştürücü, oluşturucular ve diğer herhangi bir son işleme türünü içeren bir araç zinciri tarafından işlenebilir. Harici DSL'ler çoğunlukla daha sonraki işlemler için temel oluşturan dahili modellere okunur. Bir dilbilgisi tanımlamak yararlıdır (örneğin, EBNF'de). Bir dilbilgisi, araç zincirinin parçalarını (ör. düzenleyici, görselleştirici, ayrıştırıcı oluşturucu) oluşturmak için başlangıç noktası sağlar. Basit DSL'ler için, örneğin normal ifadeler kullanarak el yapımı bir ayrıştırıcı yeterli olabilir. Kendilerinden çok fazla şey istenirse özel ayrıştırıcılar hantal hale gelebilir, bu nedenle özellikle dil gramerleri ve DSL'lerle çalışmak için tasarlanmış araçlara bakmak mantıklıdır, örneğin, openArchitectureWare, ANTlr, SableCC, AndroMDA. Harici DSL'leri XML lehçeleri olarak tanımlamak da oldukça yaygındır, ancak okunabilirlik genellikle bir sorundur, özellikle teknik olmayan okuyucular için. + +DSL'nizin hedef kitlesini her zaman hesaba katmalısınız. Geliştiriciler, yöneticiler, ticari müşteriler veya son kullanıcılar mı? Dilin teknik düzeyini, mevcut araçları, sözdizimi yardımını, erken doğrulamayı, görselleştirmeyi ve temsili hedef kitleye uyarlamanız gerekir. DSL'ler, teknik ayrıntıları gizleyerek kullanıcıları, geliştiricilerin yardımına ihtiyaç duymadan sistemleri ihtiyaçlarına göre uyarlama yeteneği vererek güçlendirilebilir. Ayrıca, ilk dil çerçevesi uygulandıktan sonra işin potansiyel dağılımı nedeniyle geliştirmeyi hızlandırabilir. Dil yavaş yavaş geliştirilebilir. Mevcut ifadeler ve gramerler için farklı geçiş yolları da mevcuttur. + +[Michael Hunger](http://programmer.97things.oreilly.com/wiki/index.php/Michael_Hunger) Tarafından \ No newline at end of file diff --git a/tr/thing_24/README.md b/tr/thing_24/README.md new file mode 100644 index 00000000..24d9094d --- /dev/null +++ b/tr/thing_24/README.md @@ -0,0 +1,13 @@ +# Bir Şeyleri Kırmaktan Korkma + +Sektör deneyimi olan herkes, kod tabanının en iyi ihtimalle güvencesiz olduğu bir projede yüksek bir ihtimalle çalışmıştır. Sistem zayıf bir şekilde çarpanlara ayrılmıştır ve bir şeyi değiştirmek her zaman başka bir alakasız özelliği bozmayı başarır. Bir modül eklendiğinde, kodlayıcının amacı mümkün olduğunca az değişiklik yapmak ve her sürümde nefesini tutmaktır. Bu, bir gökdelendeki kirişlerle Jenga oynamaya eşdeğer yazılımdır ve felakete mahkumdur. + +Değişiklik yapmanın bu kadar sinir bozucu olmasının nedeni, sistemin hasta olmasıdır. Bir doktora ihtiyacı var, aksi takdirde durumu daha da kötüleşecek. Sisteminizde neyin yanlış olduğunu zaten biliyorsunuz ama omletinizi yapmak için yumurtaları kırmaktan korkuyorsunuz. Yetenekli bir cerrah ameliyat için kesi yapılması gerektiğini bilir, ancak yetenekli cerrah kesilerin geçici olduğunu ve iyileşeceğini de bilir. Ameliyatın sonucu ilk acıya değer ve hasta ameliyattan önceki halinden daha iyi bir duruma gelmelidir. + +Kodunuzdan korkmayın. Bir şeyleri hareket ettirirken bir şeylerin geçici olarak kırılması kimin umurunda? Başlangıçta projenizi bu duruma getiren şey, felç edici bir değişim korkusudur. Yeniden düzenlemeye zaman ayırmak, projenizin yaşam döngüsü boyunca birkaç kez kendini amorti etmesine yetecektir. Ek bir fayda da, ekibinizin hastalıklı sistemle ilgili deneyiminin sizi sistemin nasıl *çalışması* gerektiği konusunda uzman yapmasıdır. Bu bilgiyi ona kızmak yerine uygulayın. Nefret ettiğiniz bir sistem üzerinde çalışmak, kimsenin zamanını harcaması gerektiği gibi değil. + +Dahili arayüzleri yeniden tanımlayın, modülleri yeniden yapılandırın, kopyala-yapıştır kodu yeniden yapılandırın ve bağımlılıkları azaltarak tasarımınızı basitleştirin. Genellikle yanlış bağlanmış özelliklerden kaynaklanan köşe durumlarını ortadan kaldırarak kod karmaşıklığını önemli ölçüde azaltabilirsiniz. Yol boyunca test ederek eski yapıyı yavaşça yenisine geçirin. "Bir büyük sorun" içinde büyük bir yeniden düzenleme yapmaya çalışmak, tüm çabayı yarıda bırakmayı düşünmenizi sağlayacak kadar soruna neden olacaktır. + +İyileşmeye yer açmak için hastalıklı parçaları kesmekten korkmayan cerrah olun. Bu tavır bulaşıcıdır ve başkalarına erteledikleri temizlik projeleri üzerinde çalışmaya başlamaları için ilham verecektir. Projenin genel iyiliği için ekibin değerli olduğunu düşündüğü görevlerin bir "hijyen" listesini tutun. Yönetimi, bu görevlerin görünür sonuçlar vermese bile, masrafları azaltacağına ve gelecekteki sürümleri hızlandıracağına ikna edin. Kodun genel "sağlığını" önemsemeyi asla bırakmayın. + +[Mike Lewis](http://programmer.97things.oreilly.com/wiki/index.php/Mike_Lewis) Tarafından \ No newline at end of file diff --git a/tr/thing_25/README.md b/tr/thing_25/README.md new file mode 100644 index 00000000..ef6afb21 --- /dev/null +++ b/tr/thing_25/README.md @@ -0,0 +1,25 @@ +# Test Verilerinizle Sevimli Olmayın + +> *Geç oluyordu. Üzerinde çalıştığım sayfa düzenini test etmek için bazı yer tutucu verileri gönderiyordum.* + +> *Kullanıcıların isimlerini The Clash üyelerine tahsis ettim. Şirket isimleri? Sex Pistols'un şarkı isimleri de işe yarardı. Şimdi birkaç hisse senedi sembolüne ihtiyacım vardı, sadece büyük harflerle birkaç harfli kelime.* + +> ***bu** birkaç harfli kelimeleri kullandım.* + +> *Zararsız görünüyordu. Gerçek veri kaynağını bağlamadan önceki gün kendimi ve belki diğer geliştiricileri eğlendirecek bir şey.* + +> *Ertesi sabah, bir proje yöneticisi sunum için bazı ekran görüntüleri aldı.** + +Programlama tarihi bu tür savaş hikayeleriyle dolu. Geliştiricilerin ve tasarımcıların "kimsenin göremeyeceği" şeyler beklenmedik bir şekilde görünür hale geldi. Sızıntı türü değişebilir, ancak gerçekleştiğinde sorumlu kişi, ekip veya şirket için ölümcül olabilir. Örnekler şunları içerir: + +- Bir durum toplantısı sırasında, müşteri henüz uygulanmamış bir düğmeye tıklar. Onlara "Bir daha tıklama, seni moron" deniyor. +- Eski bir sistemi koruyan bir yazılımcıya bir hata iletişim kutusu eklemesi söylendi ve onu güçlendirmek için mevcut sahne arkası günlük kaydının çıktısını kullanmaya karar verdi. Kullanıcılar birdenbire "Kutsal veritabanı işleme hatası Batman!" gibi mesajlarla karşı karşıya kalıyor herhangi bir hata alındığında. +- Birisi test ve canlı yönetim arayüzlerini karıştırıyor ve bazı "komik" veri girişleri yapıyor. Müşteriler, çevrimiçi mağazanızda 1 milyon dolarlık "Bill Gates şeklindeki kişisel masaj aletini" indirimde görüyor. + +"Gerçek ayakkabılarını giyerken, yalan dünyanın yarısını dolaşır" şeklindeki eski deyişi benimsemek için, Bu çağda, geliştiricinin saat dilimindeki herhangi biri bu konuda bir şey yapmak için uyanık olmadan önce Dugg, Twittered ve Flibflarbed olabilir. + +Kaynak kodunuz bile mutlaka incelemeden muaf değildir. 2004'te, Windows 2000 kaynak kodunun bir tarball'ı dosya paylaşım ağlarına girdiğinde, bazı insanlar neşeyle küfür, hakaret ve [diğer komik içerik](http://www.kuro5hin.org/story/2004/2/15/71552/7795) için bu dosyaya girdiler. (`// KORKUNÇ KORKUNÇ YOK İYİ ÇOK KÖTÜ HACK` yorumu, kabul ediyorum, o zamandan beri zaman zaman benim tarafımdan benimsendi!) + +Özetle, kodunuza herhangi bir metin yazarken (yorumlar, günlük kaydı, diyaloglar veya test verileri) her zaman kendinize, genel hale gelirse nasıl görüneceğini sorun. Her yönden bazı kırmızı yüzleri kurtaracak. + +[Rod Begbie](http://programmer.97things.oreilly.com/wiki/index.php/Rod_Begbie) Tarafından \ No newline at end of file diff --git a/tr/thing_26/README.md b/tr/thing_26/README.md new file mode 100644 index 00000000..55b781e9 --- /dev/null +++ b/tr/thing_26/README.md @@ -0,0 +1,47 @@ +# Hatayı Görmezden Gelmeyin! + +> *Bir akşam barda arkadaşlarla buluşmak için sokakta yürüyordum. Bir süredir bira içmemiştik ve onları tekrar görmeyi dört gözle bekliyordum. Acele içinde nereye gittiğime bakmıyordum. Bir kaldırımın kenarına takıldım ve yüz üstü kaldım. Eh, sanırım dikkat etmemem de bana hizmet ediyor.* + +> *Bacağımı acıttı ama arkadaşlarımla buluşmak için acelem vardı. Bu yüzden kendimi toparladım ve devam ettim. Yürüdükçe ağrım artıyordu. Başta bunu şok olarak görmeme rağmen, bir şeylerin ters gittiğini çabucak fark ettim.* + +> *Ama ne olursa olsun bara koştum. Geldiğimde acı içindeydim. Dışarıda harika bir gece geçirmedim çünkü dikkatim çok dağınıktı. Sabah doktora gittim ve kaval kemiğimin kırıldığını öğrendim. Acıyı hissettiğimde durmuş olsaydım, üzerinde yürüdüğüm bir çok ekstra hasarı önlemiş olurdum. Muhtemelen hayatımın en kötü ertesi sabahı.* + +Çok fazla yazılımcı benim felaket gecem gibi kod yazıyor. + +*Hata, ne hatası? Ciddi olmayacak. Açıkçası. Bunu görmezden gelebilirim.* Bu, katı kod için kazanan bir strateji değildir. Aslında, bu sadece basit tembellik. (Yanlış sıralama.) Kodunuzda bir hata olma ihtimali ne kadar düşük olursa olsun, her zaman onu kontrol etmeli ve her zaman onunla ilgilenmelisiniz. Her zaman. Bunu yapmazsanız zaman kazanmıyorsunuz: Gelecek için olası sorunları biriktiriyorsunuz. + +Kodumuzdaki hataları aşağıdakiler dahil olmak üzere çeşitli şekillerde rapor ederiz: + +- **Dönüş kodları**, "işe yaramadı" anlamına gelen bir işlevin sonuç değeri olarak kullanılabilir. Hata dönüş kodlarını görmezden gelmek çok kolaydır. Sorunu vurgulamak için kodda hiçbir şey görmezsiniz. Gerçekten de, bazı standart C işlevlerinin dönüş değerlerini yok saymak standart bir uygulama haline geldi. printf'ten dönüş değerini ne sıklıkla kontrol ediyorsunuz? + +- **errno** tuhaf bir C sapmasıdır, hatayı bildirmek için ayrı bir global değişkendir. Yok saymak kolaydır, kullanması zordur ve her türlü kötü soruna yol açar - örneğin, aynı işlevi çağıran birden fazla iş parçacığınız olduğunda ne olur? Bazı platformlar sizi burada acıdan yalıtır; diğerleri yapmaz. + +- **İstisnalar**, daha yapılandırılmış, dil destekli bir sinyal verme ve hataları işleme yöntemidir. Ve muhtemelen onları görmezden gelemezsiniz. Yoksa yapabilir misin? Bunun gibi birçok kod gördüm: + +``` +try { + // ...do something... +} +catch (...) {} // ignore errors +``` + +Bu korkunç yapının kurtarıcı zarafeti, ahlaki olarak şüpheli bir şey yaptığınız gerçeğini vurgulamasıdır. + +Bir hatayı görmezden gelirseniz, görmezden gelir ve hiçbir şey yolunda gitmemiş gibi davranırsanız, büyük riskler alırsınız. Bacağımın üzerinde yürümeyi bıraktığımdan daha kötü bir duruma gelmesi gibi, sürmeye devam etmek de çok karmaşık arızalara yol açabilir. Sorunlarla ilk fırsatta ilgilenin. Kısa bir hesap tutun. + +Hataları ele almamak şunlara yol açar: + +- **Kırılgan kod.** Heyecan verici, bulunması zor hatalarla dolu kod. +- **Güvensiz kod.** Çatlaklar, yazılım sistemlerine girmek için genellikle zayıf hata işlemeden yararlanır. +- **Kötü yapı.** Kodunuzda sürekli olarak uğraşılması sıkıcı hatalar varsa, muhtemelen kötü bir arayüze sahipsiniz demektir. Hatalar daha az müdahaleci olacak ve bunların ele alınması daha az zahmetli olacak şekilde ifade edin. + +Kodunuzdaki tüm olası hataları kontrol etmeniz gerektiği gibi, arayüzlerinizdeki tüm olası hatalı koşulları ortaya çıkarmanız gerekir. Hizmetlerinizin her zaman işe yarayacağını iddia ederek onları saklamayın. + +Neden hataları kontrol etmiyoruz? Bir dizi yaygın mazeret var. Bunlardan hangisine katılıyorsunuz? Her birine nasıl karşı koyarsınız? + +- Hata işleme, kodun akışını karıştırır, okumayı zorlaştırır ve "normal" yürütme akışını tespit etmeyi zorlaştırır. +- Fazladan bir iş ve yaklaşan bir teslim tarihim var. +- Bu işlev çağrısının *asla* bir hata döndürmeyeceğini biliyorum (printf her zaman çalışır, malloc her zaman yeni bellek döndürür - başarısız olursa daha büyük sorunlarımız olur...). +- Bu sadece bir oyuncak programıdır ve prodüksiyona uygun bir seviyede yazılması gerekmez. + +[Pete Goodliffe](http://programmer.97things.oreilly.com/wiki/index.php/Pete_Goodliffe) Tarafından \ No newline at end of file diff --git a/tr/thing_27/README.md b/tr/thing_27/README.md new file mode 100644 index 00000000..4d4bff75 --- /dev/null +++ b/tr/thing_27/README.md @@ -0,0 +1,13 @@ +# Sadece Dili Öğrenmeyin, Kültürünü Anlayın + +Lisede yabancı dil öğrenmek zorunda kaldım. O zamanlar iyi bir İngilizceyle iyileşeceğimi düşündüm, bu yüzden üç yıllık Fransızca dersinde uyumayı seçtim. Birkaç yıl sonra tatil için Tunus'a gittim. Arapça oradaki resmi dildir ve eski bir Fransız kolonisi olduğu için Fransızca da yaygın olarak kullanılmaktadır. İngilizce sadece turistik bölgelerde konuşulur. Dil konusundaki bilgisizliğim yüzünden, kendimi havuz başında James Joyce'un biçim ve dildeki güç gösterisi olan *Finnegans Wake*'i okurken buldum. Joyce'un kırktan fazla dili eğlenceli bir şekilde harmanlaması, yorucu olsa da şaşırtıcı bir deneyimdi. Yabancı kelimelerin ve cümlelerin nasıl iç içe geçtiğini anlamak, yazara kendini ifade etmenin yeni yollarını verdiğini anlamak, programlama kariyerimde yanımda taşıdığım bir şeydi. + +Andy Hunt ve Dave Thomas, çığır açıcı kitaplarında *The Pragmatic Programmer*, her yıl yeni bir programlama dili öğrenmemizi teşvik ediyor. Onların tavsiyelerine göre yaşamaya çalıştım ve yıllar boyunca birçok dilde programlama deneyimim oldu. Çok dilli maceralarımdan aldığım en önemli ders, bir dili öğrenmek için söz dizimini öğrenmekten fazlasının gerektiğidir: Kültürünü anlamanız gerekir. Fortran'ı herhangi bir dilde yazabilirsiniz, ancak bir dili gerçekten öğrenmek için o dili benimsemeniz gerekir. C# kodunuz çoğunlukla statik yardımcı yöntemler içeren uzun bir Main yöntemiyse mazeret üretmeyin, ancak sınıfların neden anlamlı olduğunu öğrenin. + +Yeni bir dilin iplerini öğrendikten sonra, zaten bildiğiniz dilleri yeni şekillerde kullanmaya nasıl başlayacağınıza şaşıracaksınız. C#'ta delegeleri etkili bir şekilde kullanmayı Ruby'yi programlayarak öğrendim, .NET jeneriklerinin tüm potansiyelini ortaya çıkarmak bana Java jeneriklerini nasıl daha kullanışlı hale getirebileceğim konusunda fikirler verdi ve LINQ kendime Scala'yı öğretmeyi bir esinti haline getirdi. + +Ayrıca farklı diller arasında geçiş yaparak tasarım kalıplarını daha iyi anlayacaksınız. C yazılımcıları, C# ve Java'nın yineleyici kalıbı metalaştırdığını bulur. Ruby ve diğer dinamik dillerde yine de bir ziyaretçi kullanabilirsiniz, ancak uygulamanız Gang of Four kitabındaki örneğe benzemeyecektir. + +Bazıları *Finnegans Wake*'in okunamaz olduğunu iddia edebilir, bazıları ise onu stilistik güzelliği için alkışlayabilir. Kitabı daha az ürkütücü bir okuma yapmak için, tek dilli çeviriler mevcuttur. İronik olarak, bunlardan ilki Fransızcaydı. Kod birçok yönden benzerdir. Biraz Python, biraz Java ve biraz Erlang ile *Wakese* kodu yazarsanız, projeleriniz karmakarışık olur. Bunun yerine zihninizi genişletmek için yeni diller keşfederseniz ve işleri farklı şekillerde nasıl çözebileceğiniz konusunda yeni fikirler edinirseniz, eski güvenilir dilinizde yazdığınız kodun öğrendiğiniz her yeni dil için daha güzel olduğunu göreceksiniz. + +Anders Norås Tarafından \ No newline at end of file diff --git a/tr/thing_28/README.md b/tr/thing_28/README.md new file mode 100644 index 00000000..f84d9b02 --- /dev/null +++ b/tr/thing_28/README.md @@ -0,0 +1,19 @@ +# Programınızı Dik Konumda Çivilemeyin + +Bir keresinde, istisna işleme için aşağıdaki stratejiyi hicivli bir şekilde önerdiğim bir sahte C++ sınavı yazdım: + +> Kod tabanımızdaki çok sayıda `try...catch` yapısı sayesinde, bazen uygulamalarımızın iptal edilmesini önleyebiliriz. Ortaya çıkan durumu "cesedi dik pozisyonda çivilemek" olarak düşünürüz. + +Alaysızlığıma rağmen, aslında Dame Bitter Experience'ın dizinin dibinde aldığım bir dersi özetledim. + +Kendi ev yapımı C++ kitaplığımızda temel bir uygulama sınıfıydı. Yıllar boyunca pek çok yazılımcının parmaklarını dürttü: Kimsenin eli temiz değildi. Diğer her şeyden kaçan istisnalarla başa çıkmak için kod içeriyordu. Catch-22'de Yossarian'dan yola çıkarak, bu sınıfın bir örneğinin sonsuza kadar yaşaması veya bu girişimde ölmesi gerektiğine karar verdik veya daha doğrusu hissettik (*karar verdi* bu canavarın inşasına girmekten daha fazla düşünce anlamına gelir). + +Bu amaçla, birden çok istisna işleyicisini iç içe geçirdik. Windows'un yapılandırılmış özel durum işlemesini yerel türle karıştırdık (C++'da '__try...__except'i hatırla? Ben de yokum). Beklenmedik bir şekilde işler ters gittiğinde, parametrelere daha sert basarak onları tekrar çağırmayı denedik. Geriye dönüp baktığımda, bir başkasının catch cümlesi içinde içsel bir 'try...catch' işleyicisi yazarken, iyi uygulama otoyolundan kazara bir kayma yolu seçmiş olabileceğime dair bir tür farkındalığın üzerime çöktüğünü düşünmek hoşuma gidiyor, aromatik ama sağlığa zararlı delilik şeridi. Ancak, bu muhtemelen geriye dönük bir bilgeliktir. + +Söylemeye gerek yok, ne zaman bu sınıfa dayalı uygulamalarda bir şeyler ters gitse, rıhtımdaki Mafya kurbanları gibi ortadan kayboldular ve felaketi kaydetmek için çağrıldığı varsayılan çöplük rutinlerine rağmen, arkalarında ne olduğunu gösteren hiçbir yararlı kabarcık izi bırakmadılar. Sonunda, uzun bir süre sonra yaptıklarımızın hesabını yaptık ve utanç duyduk. Tüm karmaşayı minimal ve sağlam bir raporlama mekanizmasıyla değiştirdik. Ancak bu, çizgide birçok kaza oldu. + +Seni bununla rahatsız etmem, kesinlikle başka kimse bizim kadar aptal olamaz ama geçenlerde, akademik iş unvanı daha iyi bilmesi gerektiğini söyleyen bir adamla çevrimiçi bir tartışma yaptım. Uzak bir işlemde Java kodunu tartışıyorduk. Kodun başarısız olması durumunda, *in situ* istisnasını yakalaması ve engellemesi gerektiğini savundu. ("Peki onunla *ne* yapacaksın?" diye sordum. "Akşam yemeği için pişirelim mi?") + +UI tasarımcılarının kuralından alıntı yaptı: KULLANICININ ASLA İSTİSNA RAPORU GÖRMESİNE İZİN VERMEYİN, sanki bu meseleyi çözmüş gibi, ne büyük harflerle ve her şeyle. Fotoğrafları daha zayıf blogları süsleyen mavi ekranlı ATM'lerden birindeki koddan sorumlu olup olmadığını ve kalıcı olarak travmatize olup olmadığını merak ediyorum. Her neyse, eğer onunla karşılaşırsan, başını salla ve gülümse ve kapıya doğru yan yan dönerken aldırma. + +[Verity Stob](http://programmer.97things.oreilly.com/wiki/index.php/Verity_Stob) Tarafından \ No newline at end of file diff --git a/tr/thing_29/README.md b/tr/thing_29/README.md new file mode 100644 index 00000000..719d59da --- /dev/null +++ b/tr/thing_29/README.md @@ -0,0 +1,21 @@ +# "Burada Sihir Olur"a Güvenmeyin + +Herhangi bir faaliyete, sürece veya disipline yeterince uzaktan bakarsanız basit görünür. Geliştirme deneyimi olmayan yöneticiler, yazılımcıların yaptıklarının basit olduğunu düşünürler ve yönetim deneyimi olmayan yazılımcılar, yöneticilerin yaptıklarıyla aynı şeyi düşünür. + +Programlama, bazı insanların yaptığı bir şeydir. Ve zor kısım düşünmedir, deneyimsizler tarafından en az görülen ve en az takdir edilen kısımdır. Onlarca yıldır bu yetenekli düşünceye olan ihtiyacı ortadan kaldırmak için birçok girişimde bulunuldu. En eski ve en akılda kalıcı olanlardan biri, Grace Hopper'ın programlama dillerini daha az şifreli hale getirme çabasıdır, bazı hesapların tahminlerine göre uzman yazılımcılara olan ihtiyacı ortadan kaldıracaktır. Sonuç (COBOL), sonraki on yıllarda birçok uzman yazılımcının gelirine katkıda bulunmuştur. + +Yazılım geliştirmenin programlamayı kaldırarak basitleştirilebileceği konusundaki ısrarlı vizyon, neyin dahil olduğunu anlayan yazılımcı için açıkça naiftir. Ancak bu hataya yol açan zihinsel süreç insan doğasının bir parçasıdır ve yazılımcılar da herkes gibi bunu yapmaya meyillidir. + +Herhangi bir projede muhtemelen bireysel bir yazılımcının aktif olarak dahil olmadığı pek çok şey vardır: kullanıcılardan gereksinimleri ortaya çıkarmak, bütçelerin onaylanmasını sağlamak, yapı sunucusunu kurmak, uygulamayı QA ve üretim ortamlarına dağıtmak, işi eskisinden taşımak süreçler veya programlar, vb. + +Bir şeylere aktif olarak dahil olmadığınızda, bunların basit olduğunu ve "sihirle" gerçekleştiğini varsaymak için bilinçsiz bir eğilim vardır. Sihir gerçekleşmeye devam ederken, her şey yolunda. Ama genellikle "ne zaman" ve "eğer" olmadığı zamanlar, sihir durduğunda projenin başı belada. + +Projelerin haftalarca geliştirici zamanı kaybettiğini biliyorum çünkü kimse yüklenen bir DLL'nin "doğru" sürümüne nasıl güvendiklerini anlamadı. İşler aralıklı olarak başarısız olmaya başladığında, birileri DLL'nin "yanlış" bir sürümünün yüklendiğini fark etmeden önce ekip üyeleri başka her yere baktı. + +Başka bir departman sorunsuz çalışıyordu, projeler zamanında teslim edildi, gece geç saatlerde hata ayıklama oturumları yok, acil durum düzeltmeleri yok. Aslında o kadar sorunsuz ki, üst yönetim işlerin "kendi kendine yürüdüğüne" ve proje yöneticisi olmadan da yapabileceklerine karar verdi. Altı ay içinde departmandaki projeler tıpkı organizasyonun geri kalanına benziyordu geç, sorunlu ve sürekli olarak yamalanıyor. + +Projenizin çalışmasını sağlayan tüm sihri anlamak zorunda değilsiniz, ancak bazılarını anlamaktan ya da anlamadığınız kısımları anlayan birini takdir etmekten zarar gelmez. + +En önemlisi, sihir durduğunda yeniden başlatılabileceğinden emin olun. + +[AlanGriffiths](http://programmer.97things.oreilly.com/wiki/index.php/AlanGriffiths) Tarafından \ No newline at end of file diff --git a/tr/thing_30/README.md b/tr/thing_30/README.md new file mode 100644 index 00000000..72ff77e3 --- /dev/null +++ b/tr/thing_30/README.md @@ -0,0 +1,27 @@ +# Kendinizi Tekrar Etmeyin (Don't Repeat Yourself - DRY) + +Programlamanın tüm ilkeleri arasında, Kendini Tekrar Etme (DRY) belki de en temellerinden biridir. İlke, Andy Hunt ve Dave Thomas tarafından *The Pragmatic Programmer*'da formüle edilmiştir ve diğer birçok iyi bilinen yazılım geliştirme en iyi uygulamalarının ve tasarım modellerinin temelini oluşturur. Tekrarlamayı tanımayı öğrenen ve uygun uygulama ve doğru soyutlama yoluyla bunu nasıl ortadan kaldıracağını anlayan geliştirici, uygulamayı sürekli olarak gereksiz tekrarlarla bulaştıran birinden çok daha temiz kod üretebilir. + +Tekrarlamak israftır +--- + +Bir uygulamaya giren her kod satırı korunmalıdır ve gelecekteki hataların potansiyel bir kaynağıdır. Tekrarlama, kod tabanını gereksiz yere şişirir, bu da hatalar için daha fazla fırsat sağlar ve sisteme kazara karmaşıklık ekler. Tekrarlamanın sisteme eklediği şişkinlik, sistemle çalışan geliştiricilerin tüm sistemi tam olarak anlamasını veya bir yerde yapılan değişikliklerin mantığı kopyalayan başka yerlerde yapılması gerekmediğinden emin olmasını da zorlaştırır. DRY, "her bilgi parçasının bir sistem içinde tek, açık ve yetkili bir temsile sahip olmasını" gerektirir. + +Süreçte tekrar, otomasyon gerektirir +--- + +Yazılım geliştirmedeki birçok süreç tekrarlanır ve kolayca otomatikleştirilir. DRY ilkesi, bu bağlamlarda ve uygulamanın kaynak kodunda geçerlidir. Manuel test yavaştır, hataya açıktır ve tekrarlanması zordur, bu nedenle mümkünse otomatik test paketleri kullanılmalıdır. Yazılımı entegre etmek, manuel olarak yapıldığında zaman alıcı ve hataya açık olabilir, bu nedenle bir oluşturma işlemi, ideal olarak her check-in ile mümkün olduğunca sık çalıştırılmalıdır. Otomatikleştirilebilen zahmetli manuel süreçler nerede olursa olsun, bunlar otomatikleştirilmeli ve standartlaştırılmalıdır. Amaç, görevi tamamlamanın tek bir yolu olduğundan ve mümkün olduğu kadar acısız olduğundan emin olmaktır. + +Mantıkta tekrar, soyutlamayı gerektirir. +--- + +Mantıkta tekrar birçok biçim alabilir. Kopyala-yapıştır *if-then* veya *switch-case* mantığı, tespit edilmesi ve düzeltilmesi en kolay olanlardan biridir. Birçok tasarım deseni, bir uygulama içinde mantıkta tekrarlamayı azaltmak veya ortadan kaldırmak gibi açık bir amaca sahiptir. Bir nesne, kullanılmadan önce tipik olarak birkaç şeyin olmasını gerektiriyorsa, bu bir Abstract Factory veya Factory Yöntemi ile gerçekleştirilebilir. Bir nesnenin davranışında birçok olası varyasyon varsa, bu davranışlar büyük *if-then* yapıları yerine Strategy kalıbı kullanılarak enjekte edilebilir. Aslında, tasarım kalıplarının formülasyonu, ortak sorunları çözmek ve bu çözümleri tartışmak için gereken çabanın tekrarını azaltma girişimidir. Ek olarak, veritabanı şeması gibi yapılara DRY uygulanarak normalizasyon sağlanır. + +Prensip meselesi +--- + +Diğer yazılım ilkeleri de DRY ile ilgilidir. Yalnızca kodun işlevsel davranışı için geçerli olan Bir Kez ve Yalnızca Bir Kez ilkesi, DRY'nin bir alt kümesi olarak düşünülebilir. "Yazılım varlıklarının genişletilmeye açık, ancak değiştirilmeye kapalı olması gerektiğini" belirten Açık/Kapalı(Open/Closed) İlkesi, pratikte yalnızca DRY'ye uyulduğunda çalışır. Benzer şekilde, iyi bilinen Tek Sorumluluk(Single Responsibility) İlkesi, bir sınıfın "değişmek için tek bir nedeni" olmasını gerektirir, DRY'ye dayanır. + +Yapı, mantık, süreç ve işlev açısından izlendiğinde, DRY ilkesi yazılım geliştiricilere temel rehberlik sağlar ve daha basit, daha sürdürülebilir, daha yüksek kaliteli uygulamaların oluşturulmasına yardımcı olur. Performansı veya diğer gereksinimleri karşılamak için tekrarlamanın gerekli olabileceği senaryolar olsa da (örneğin, bir veritabanında veri denormalizasyonu), yalnızca hayali bir sorundan ziyade gerçek bir sorunu doğrudan ele aldığı durumlarda kullanılmalıdır. + +[Steve Smith](http://programmer.97things.oreilly.com/wiki/index.php/Steve_Smith) Tarafından \ No newline at end of file diff --git a/tr/thing_31/README.md b/tr/thing_31/README.md new file mode 100644 index 00000000..0022d212 --- /dev/null +++ b/tr/thing_31/README.md @@ -0,0 +1,22 @@ +# O Koda Dokunma! + +Hepimizin başına bir noktada gelmiştir. Kodunuz, sistem testi için hazırlama sunucusuna alındı ve test yöneticisi bir sorunla karşılaştığını yazar. İlk tepkiniz "Çabuk, bunu düzeltmeme izin verin neyin yanlış olduğunu biliyorum." + +Daha geniş anlamda, yanlış olan şey, bir geliştirici olarak hazırlama sunucusuna erişiminizin olması gerektiğini düşünmenizdir. + +Çoğu web tabanlı geliştirme ortamında, mimari şu şekilde bölünebilir: + +- Geliştiricinin makinesinde yerel geliştirme ve birim testi +- Manuel veya otomatik entegrasyon testinin yapıldığı geliştirme sunucusu +- QA ekibinin ve kullanıcıların kabul testi yaptığı aşamalandırma sunucusu +- Üretim sunucusu + +Evet, kaynak kodu kontrolü ve biletleme gibi oraya serpiştirilmiş başka sunucular ve hizmetler var, ancak siz anladınız. Bu modeli kullanan bir geliştirici hatta kıdemli bir geliştirici bile geliştirme sunucusunun ötesine asla erişememelidir. Çoğu geliştirme, bir geliştiricinin yerel makinesinde, en sevdikleri IDE'ler, sanal makineler ve iyi şanslar için üzerine serpilmiş uygun miktarda kara büyü karışımı kullanılarak yapılır. + +Otomatik veya manuel olarak SCC'ye kontrol edildikten sonra, her şeyin birlikte çalıştığından emin olmak için test edilebileceği ve gerekirse ince ayar yapılabileceği geliştirme sunucusuna aktarılmalıdır. Ancak bu noktadan itibaren, geliştirici sürecin bir izleyicisidir. + +Hazırlama yöneticisi, kodu QA ekibi için hazırlama sunucusuna paketlemeli ve yuvarlamalıdır. Tıpkı geliştiricilerin geliştirme sunucusunun ötesinde herhangi bir şeye erişmesine gerek olmaması gerektiği gibi, QA ekibinin ve kullanıcıların geliştirme sunucusunda herhangi bir şeye dokunmasına gerek yoktur. Kabul testi için hazırsa, bir yayın kes ve yuvarla, kullanıcıdan geliştirme sunucusunda "Gerçekten hızlı bir şeye bak" deme. Unutmayın, projeyi kendiniz kodlamıyorsanız, diğer insanların orada kodu vardır ve kullanıcının görmesi için hazır olmayabilirler. Sürüm yöneticisi, her ikisine de erişimi olması gereken tek kişidir. + +Hiçbir koşulda, hiçbir zaman bir geliştiricinin bir üretim sunucusuna erişimi olmamalıdır. Bir sorun varsa, destek personeliniz sorunu çözmeli veya sizden düzeltmenizi istemelidir. SCC'de kontrol edildikten sonra oradan bir yama yayınlayacaklar. Parçası olduğum en büyük programlama felaketlerinden bazıları, birinin \**öksürük*\*ben\**öksürük\** bu son kuralı ihlal etmesiyle gerçekleşti. Bozulursa, onu tamir etmenin yeri üretim değildir. + +[Cal Evans](http://programmer.97things.oreilly.com/wiki/index.php/Cal_Evans) Tarafından \ No newline at end of file diff --git a/tr/thing_32/README.md b/tr/thing_32/README.md new file mode 100644 index 00000000..9dc33718 --- /dev/null +++ b/tr/thing_32/README.md @@ -0,0 +1,15 @@ +# Sadece Durumu Değil, Davranışı Kapsülleyin + +Sistem teorisinde, büyük ve karmaşık sistem yapılarıyla uğraşırken, kapsama en yararlı yapılardan biridir. Yazılım endüstrisinde, kapsama veya kapsüllemenin değeri iyi anlaşılmıştır. Kapsama, alt rutinler ve işlevler, modüller ve paketler, sınıflar vb. gibi programlama dili yapıları tarafından desteklenir. + +Modüller ve paketler, kapsülleme için daha büyük ölçekli ihtiyaçları ele alırken, sınıflar, alt rutinler ve işlevler konunun daha incelikli yönlerini ele alır. Yıllar geçtikçe, sınıfların, geliştiricilerin doğru yapması en zor kapsülleme yapılarından biri gibi göründüğünü keşfettim. 3000 satırlık tek bir ana yönteme sahip bir sınıf veya ilkel nitelikleri için yalnızca *set* ve *get* yöntemlerine sahip bir sınıf bulmak nadir değildir. Bu örnekler, dahil olan geliştiricilerin, modelleme yapıları olarak nesnelerin gücünden yararlanmada başarısız olduklarından, nesne yönelimli düşünceyi tam olarak anlamadıklarını göstermektedir. POJO (Düz Eski Java Nesnesi) ve POCO (Düz Eski C# Nesnesi veya Düz Eski CLR Nesnesi) terimlerine aşina olan geliştiriciler için, bir modelleme paradigması olarak OO'nun temellerine geri dönme niyeti buydu, nesneler sade ve basittir, ama aptal değil. + +Bir nesne, davranışın gerçek durum tarafından tanımlandığı hem durumu hem de davranışı kapsar. Bir kapı nesnesi düşünün. Dört durumu vardır: kapalı, açık, kapanıyor, açılıyor. İki işlem sağlar: aç ve kapat. Duruma bağlı olarak, açma ve kapama işlemleri farklı davranacaktır. Bir nesnenin bu doğal özelliği, tasarım sürecini kavramsal olarak basitleştirir. İki basit göreve indirgenir: nesneler arası etkileşim protokolleri de dahil olmak üzere farklı nesnelere sorumluluk tahsisi ve delegasyonu. + +Bunun pratikte nasıl çalıştığı en iyi bir örnekle gösterilmiştir. Diyelim ki üç sınıfımız var: Customer, Order ve Item. Customer nesnesi, kredi limiti ve kredi doğrulama kuralları için doğal yer tutucudur. Bir Order nesnesi, ilişkili Customer hakkında bilgi sahibidir ve addItem işlemi, "customer.validateCredit(item.price())" item ini çağırarak gerçek kredi kontrolünü devreder. Yöntemin son koşulu başarısız olursa, bir istisna atılabilir ve satın alma iptal edilebilir. + +Daha az deneyimli nesne yönelimli geliştiriciler, tüm iş kurallarını, genellikle "OrderManager" veya "OrderService" olarak adlandırılan bir nesneye sarmaya karar verebilir. Bu tasarımlarda, `Order`, `Customer` ve `Item`, kayıt türlerinden biraz daha fazlası olarak ele alınır. Tüm mantık, sınıflardan ayrılır ve çok sayıda dahili *if-then-else* yapısıyla büyük, prosedürel bir yöntemle birbirine bağlanır. Bu yöntemler kolayca bozulur ve bakımı neredeyse imkansızdır. Sebep? Kapsülleme bozuldu. + +Sonuç olarak, kapsüllemeyi bozmayın ve onu korumak için programlama dilinizin gücünü kullanın. + +[Einar Landre](http://programmer.97things.oreilly.com/wiki/index.php/Einar_Landre) Tarafından \ No newline at end of file diff --git a/tr/thing_33/README.md b/tr/thing_33/README.md new file mode 100644 index 00000000..91185b49 --- /dev/null +++ b/tr/thing_33/README.md @@ -0,0 +1,17 @@ +# Kayan Noktalı Sayılar Gerçek Değil + +Kayan noktalı sayıları, Pascal ve Fortran gibi bazı programlama dillerinde *gerçek* olarak adlandırılsalar da, matematiksel anlamda "gerçek sayılar" değildir. Gerçek sayılar sonsuz kesinliğe sahiptir ve bu nedenle süreklidir ve kayıpsızdır; kayan noktalı sayıların kesinliği sınırlıdır, bu nedenle sonludurlar ve "kötü davranışlı" tam sayılara benzerler çünkü aralıkları boyunca eşit aralıklarla dağılmazlar. + +Örneklemek için, 32 bitlik bir kayan değişkene (x, diyelim) 2147483647 (en büyük işaretli 32 bit tam sayı) atayın ve yazdırın. 2147483648'i göreceksiniz. Şimdi `x - 64` yazdırın. Hala 2147483648. Şimdi `x - 65` yazdırın ve 2147483520 elde edeceksiniz! Niye ya? Çünkü bu aralıktaki bitişik kayan noktalar arasındaki boşluk 128'dir ve kayan nokta işlemleri en yakın kayan nokta sayısına yuvarlanır. + +IEEE kayan nokta sayıları, iki tabanlı bilimsel gösterime dayalı sabit kesinlikli sayılardır: 1.d1d2...dp-1 × 2e, burada *p* kesinliktir (float için 24, double için 53). Ardışık iki sayı arasındaki boşluk 21-p+e'tır, bu da ε|x| ile güvenli bir şekilde tahmin edilebilir; burada ε *makine epsilonudur* (21-p). + +Bir kayan noktalı sayının çevresindeki boşluğu bilmek, klasik sayısal hatalardan kaçınmanıza yardımcı olabilir. Örneğin, bir denklemin kökünü aramak gibi yinelemeli bir hesaplama yapıyorsanız, cevabın komşuluğunda sayı sisteminin verebileceğinden daha fazla kesinlik istemenin bir anlamı yoktur. İstediğiniz toleransın buradaki boşluktan daha küçük olmadığından emin olun; yoksa sonsuza kadar döngü yaparsın. + +Kayan noktalı sayıları, gerçek sayıların yaklaşık değerleri olduğundan, kaçınılmaz olarak küçük bir hata vardır. *Yuvarlama* adı verilen bu hata şaşırtıcı sonuçlara yol açabilir. Örneğin, neredeyse eşit sayıları çıkardığınızda, en anlamlı rakamlar birbirini yok eder, bu nedenle en az anlamlı olan rakam (yuvarlama hatasının bulunduğu yer) kayan nokta sonucunda en önemli konuma yükseltilir ve esasen herhangi birini kirletir. diğer ilgili hesaplamalar (*bulaşma* olarak bilinen bir olgu). Böyle bir *felaket iptalini* önlemek için algoritmalarınıza yakından bakmanız gerekir. Örneklemek için, *x2 - 100000x + 1 = 0* denklemini ikinci dereceden formülle çözmeyi düşünün. *-b + sqrt(b2 - 4)* ifadesindeki işlenenlerin büyüklükleri hemen hemen eşit olduğundan, bunun yerine *r1 = -b + sqrt(b2 - 4)* kökünü hesaplayabilir ve ardından *r2 = 1/r1* elde edebilirsiniz, çünkü herhangi bir ikinci dereceden ax2 + bx + c = 0 denklemi için kökler *r1r2 = c/a*'ı sağlar. + +Bulaşma daha da ince şekillerde ortaya çıkabilir. Bir kitaplığın *ex*'ü *1 + x + x2/2 + x3/3! + ...* formülüyle basitçe hesapladığını varsayalım. Bu, pozitif *x* için iyi çalışır, ancak *x* büyük bir negatif sayı olduğunda ne olduğunu düşünün. Çift güçlü terimler büyük pozitif sayılarla sonuçlanır ve tek güçlü büyüklüklerin çıkarılması sonucu bile etkilemez. Buradaki sorun, büyük, pozitif terimlerdeki yuvarlamanın, gerçek cevaptan çok daha önemli bir rakam konumunda olmasıdır. Cevap pozitif sonsuzluğa doğru sapıyor! Buradaki çözüm de basittir: negatif *x* için *ex = 1/e|x|*'u hesaplayın. + +Finansal uygulamalar için kayan noktalı sayıları kullanmamanız gerektiğini söylemeye gerek yok, Python ve C# gibi dillerdeki ondalık sınıflar bunun içindir. Kayan noktalı sayıları verimli bilimsel hesaplama için tasarlanmıştır. Ancak doğruluk olmadan verimlilik değersizdir, bu nedenle yuvarlama hatalarının kaynağını unutmayın ve buna göre kodlayın! + +[Chuck Allison](http://programmer.97things.oreilly.com/wiki/index.php/Chuck_Allison) Tarafından \ No newline at end of file diff --git a/tr/thing_34/README.md b/tr/thing_34/README.md new file mode 100644 index 00000000..f1ed4b57 --- /dev/null +++ b/tr/thing_34/README.md @@ -0,0 +1,13 @@ +# Açık Kaynak ile Hedeflerinizi Gerçekleştirin + +En hırslı yazılım geliştirme hayallerinizi gerçekleştiren iş yerinde yazılım geliştirmiyor olma ihtimaliniz oldukça yüksek. Belki de Google, Apple, Microsoft'ta veya bir sonraki büyük şeyi geliştirmek için kendi girişiminizde çalışmayı tercih ederken büyük bir sigorta şirketi için yazılım geliştiriyorsunuzdur. Önemsemediğiniz sistemler için yazılım geliştirdikçe istediğiniz yere asla varamayacaksınız. + +Neyse ki sorununuzun bir cevabı var: açık kaynak. Dışarıda, birçoğu oldukça aktif olan ve size isteyebileceğiniz her türlü yazılım geliştirme deneyimini sunan binlerce açık kaynak projesi var. İşletim sistemleri geliştirme fikrini seviyorsanız, bir düzine işletim sistemi projesinden birine yardım edin. Müzik yazılımı, animasyon yazılımı, kriptografi, robotik, PC oyunları, devasa çevrimiçi oyuncu oyunları, cep telefonları veya herhangi bir şey üzerinde çalışmak istiyorsanız, neredeyse kesinlikle bu ilgi alanına adanmış en az bir açık kaynaklı proje bulacaksınız. + +Tabii ki bedava öğle yemeği yok. Günlük işinizde muhtemelen açık kaynaklı bir video oyunu üzerinde çalışamayacağınız için boş zamanınızdan vazgeçmeye istekli olmalısınız, yine de işvereninize karşı bir sorumluluğunuz var. Ek olarak, çok az insan açık kaynak projelerine katkıda bulunarak para kazanıyor, bazıları yapıyor ama çoğu yapmıyor. Boş zamanınızın bir kısmından vazgeçmeye istekli olmalısınız (daha az video oyunları oynamak ve TV izlemek sizi öldürmez). Açık kaynaklı bir proje üzerinde ne kadar çok çalışırsanız, bir programcı olarak gerçek hedeflerinizi o kadar hızlı gerçekleştirirsiniz. Çalışan sözleşmenizi dikkate almak da önemlidir - bazı işverenler, kendi zamanınızda bile katkıda bulunabileceğiniz şeyleri kısıtlayabilir. Ayrıca, telif hakkı, patentler, ticari markalar ve ticari sırlarla ilgili fikri mülkiyet yasalarını ihlal etme konusunda dikkatli olmanız gerekir. + +Açık kaynak, motive olmuş programcılar için muazzam fırsatlar sunar. İlk olarak, bir başkasının sizi ilgilendiren bir çözümü nasıl uygulayacağını görürsünüz, diğer insanların kaynak kodunu okuyarak çok şey öğrenebilirsiniz. İkinci olarak, projeye kendi kodunuz ve fikirlerinizle katkıda bulunacaksınız, sahip olduğunuz her parlak fikir kabul edilmeyecek, ancak bazıları olabilir ve sadece çözümler üzerinde çalışarak ve koda katkıda bulunarak yeni bir şeyler öğreneceksiniz. Üçüncüsü, sahip olduğunuz yazılım türü için aynı tutkuya sahip harika insanlarla tanışacaksınız, bu açık kaynaklı arkadaşlıklar bir ömür boyu sürebilir. Dördüncüsü, yetkin bir katkıda bulunduğunuzu varsayarsak, sizi gerçekten ilgilendiren teknolojiye gerçek dünya deneyimini ekleyebileceksiniz. + +Açık kaynak kullanmaya başlamak oldukça kolaydır. İhtiyaç duyacağınız araçlarla ilgili (örneğin, kaynak kodu yönetimi, editörler, programlama dilleri, yapı sistemleri vb.) çok sayıda belge bulunmaktadır. Önce üzerinde çalışmak istediğiniz projeyi bulun ve projenin kullandığı araçlar hakkında bilgi edinin. Projelerle ilgili belgeler çoğu durumda hafif olacaktır, ancak bu belki daha az önemlidir çünkü öğrenmenin en iyi yolu kodu kendiniz araştırmaktır. Katılmak istiyorsanız, belgelere yardım etmeyi teklif edebilirsiniz. Veya test kodu yazmaya gönüllü olarak başlayabilirsiniz. Bu kulağa heyecan verici gelmese de, gerçek şu ki, diğer insanların yazılımı için test kodu yazarak, yazılımdaki hemen hemen tüm diğer etkinliklerden çok daha hızlı öğrenirsiniz. Test kodu yazın, gerçekten iyi test kodu. Hataları bulun, düzeltmeler önerin, arkadaşlar edinin, sevdiğiniz yazılımlar üzerinde çalışın ve yazılım geliştirme hedeflerinizi gerçekleştirin. + +[Richard Monson-Haefel](http://programmer.97things.oreilly.com/wiki/index.php/Richard_Monson-Haefel) Tarafından \ No newline at end of file diff --git a/tr/thing_35/README.md b/tr/thing_35/README.md new file mode 100644 index 00000000..3ca5a211 --- /dev/null +++ b/tr/thing_35/README.md @@ -0,0 +1,13 @@ +# API Tasarımının Altın Kuralı + +API tasarımı, özellikle büyük ölçekte zordur. Yüzlerce veya binlerce kullanıcıya sahip olacak bir API tasarlıyorsanız, gelecekte bunu nasıl değiştirebileceğinizi ve değişikliklerinizin istemci kodunu bozup bozamayacağını düşünmelisiniz. Bunun ötesinde, API'nizin kullanıcılarının sizi nasıl etkilediğini düşünmelisiniz. API sınıflarınızdan biri dahili olarak kendi yöntemlerinden birini kullanıyorsa, bir kullanıcının sınıfınızı alt sınıflara ayırıp onu geçersiz kılabileceğini ve bunun felaketle sonuçlanabileceğini hatırlamanız gerekir. Bazı kullanıcılarınız ona farklı bir anlam verdiği için bu yöntemi değiştiremezsiniz. Gelecekteki dahili uygulama seçenekleriniz, kullanıcılarınızın insafına kalmıştır. + +API geliştiricileri bu sorunu çeşitli şekillerde çözer, ancak en kolay yol API'yi kilitlemektir. Java'da çalışıyorsanız, sınıflarınızın ve yöntemlerinizin çoğunu final yapmak isteyebilirsiniz. C#'da sınıflarınızı ve yöntemlerinizi sealed hale getirebilirsiniz. Kullanmakta olduğunuz dil ne olursa olsun, API'nizi bir singleton aracılığıyla sunmaya veya statik fabrika yöntemlerini kullanmaya cazip gelebilirsiniz, böylece onu davranışı geçersiz kılabilecek ve kodunuzu daha sonra seçimlerinizi kısıtlayabilecek şekillerde kullanabilecek kişilerden koruyabilirsiniz. Bütün bunlar makul görünüyor, ama gerçekten öyle mi? + +Son on yılda, birim testinin uygulamanın son derece önemli bir parçası olduğunu yavaş yavaş fark ettik, ancak bu ders endüstriye tam olarak nüfuz etmedi. Kanıtlar etrafımızda. Üçüncü taraf API kullanan rastgele denenmemiş bir sınıf alın ve bunun için birim testleri yazmaya çalışın. Çoğu zaman başın belaya girecek. API'yi kullanan kodun ona yapıştırıcı gibi yapıştığını göreceksiniz. Kodunuzun bunlarla olan etkileşimlerini hissedebilmeniz veya test için dönüş değerleri sağlayabilmeniz için API sınıflarının kimliğine bürünmenin bir yolu yoktur. + +Zamanla, bu daha iyi olacak, ancak yalnızca API'leri tasarlarken testi gerçek bir kullanım durumu olarak görmeye başlarsak. Ne yazık ki, kodumuzu test etmekten biraz daha fazla ilgili. **API Tasarımının Altın Kuralı** tam da bu noktada devreye girer: *Geliştirdiğiniz bir API için testler yazmak yeterli değildir; API'nizi kullanan kod için birim testleri yazmanız gerekir. Bunu yaptığınızda, kullanıcılarınızın kodlarını bağımsız olarak test etmeye çalıştıklarında üstesinden gelmek zorunda kalacakları engelleri ilk elden öğrenirsiniz.* + +Geliştiricilerin API'nizi kullanan kodu test etmesini kolaylaştırmanın tek bir yolu yoktur. `static`, `final` ve `sealed` doğal olarak kötü yapılar değildir. Zaman zaman faydalı olabilirler. Ancak test konusunun farkında olmak önemlidir ve bunu yapmak için bunu kendiniz deneyimlemelisiniz. Bir kez sahip olduğunuzda, diğer herhangi bir tasarım zorluğunda olduğu gibi ona da yaklaşabilirsiniz. + +[Michael Feathers](http://programmer.97things.oreilly.com/wiki/index.php/Michael_Feathers) Tarafından \ No newline at end of file diff --git a/tr/thing_36/README.md b/tr/thing_36/README.md new file mode 100644 index 00000000..775af7f4 --- /dev/null +++ b/tr/thing_36/README.md @@ -0,0 +1,17 @@ +# Guru Efsanesi + +Yazılımda yeterince uzun süre çalışmış olan herkes şuna benzer sorular duymuştur: + +> *XYZ istisnası alıyorum. Sorunun ne olduğunu biliyor musun?* + +Soruyu soran kişiler nadiren yığın izlerini, hata günlüklerini veya soruna yol açan herhangi bir bağlamı dahil etmekle uğraşmazlar. Sizin farklı bir düzlemde çalıştığınızı, çözümlerin size kanıta dayalı analizler olmadan göründüğünü düşünüyorlar. Senin bir guru olduğunu düşünüyorlar. + +Yazılıma aşina olmayanlardan böyle sorular bekliyoruz: Onlara sistemler neredeyse sihirli görünebilir. Beni endişelendiren, bunu yazılım camiasında görmek. Program tasarımında "Envanter yönetimi yapıyorum" gibi benzer sorular ortaya çıkıyor. İyimser kilitleme kullanmalı mıyım?" İronik olarak, soruyu soran insanlar genellikle soruyu yanıtlamak için soruyu alan kişiden daha donanımlıdır. Sorgulayıcılar muhtemelen bağlamı biliyor, gereksinimleri biliyor ve farklı stratejilerin avantaj ve dezavantajlarını okuyabiliyor. Yine de, bağlam olmadan akıllıca bir cevap vermenizi beklerler. Büyü beklerler. + +Yazılım endüstrisinin bu guru efsanesini ortadan kaldırmasının zamanı geldi. "Gurular" insandır. Mantık uygularlar ve geri kalanımız gibi sorunları sistematik olarak analiz ederler. Zihinsel kısayollardan ve sezgiden yararlanırlar. Tanıştığınız en iyi programcıyı düşünün: Bir noktada o kişi yazılım hakkında sizin şimdi olduğundan daha az şey biliyordu. Birisi bir guru gibi görünüyorsa, bunun nedeni düşünce süreçlerini öğrenmeye ve iyileştirmeye adanmış yılların olmasıdır. Bir "guru", sadece amansız bir meraka sahip akıllı bir kişidir. + +Tabii ki, doğal yetenekte büyük bir farklılık var. Dışarıdaki birçok bilgisayar korsanı benim olabileceğimden daha akıllı, daha bilgili ve daha üretken. Öyle olsa bile, guru efsanesini çürütmek olumlu bir etkiye sahiptir. Örneğin, benden daha zeki biriyle çalışırken, kişinin becerilerini verimli bir şekilde uygulayabilmesi için yeterli bağlam sağlamak için ayak işlerini yapacağımdan eminim. Guru mitini ortadan kaldırmak, aynı zamanda gelişmeye karşı algılanan bir engeli ortadan kaldırmak anlamına gelir. Sihirli bir engel yerine üzerinde ilerleyebileceğim bir süreklilik görüyorum. + +Son olarak, yazılımın en büyük engellerinden biri, guru efsanesini bilerek yayan akıllı insanlardır. Bu, egodan veya bir müşteri veya işveren tarafından algılanan kişinin değerini artırma stratejisi olarak yapılabilir. İronik olarak, bu tutum, akranlarının gelişimine katkıda bulunmadıkları için akıllı insanları daha az değerli hale getirebilir. Gurulara ihtiyacımız yok. Kendi alanlarında başka uzmanlar geliştirmeye istekli uzmanlara ihtiyacımız var. Hepimize yer var. + +[Ryan Brush](http://programmer.97things.oreilly.com/wiki/index.php/Ryan_Brush) Tarafından \ No newline at end of file diff --git a/tr/thing_37/README.md b/tr/thing_37/README.md new file mode 100644 index 00000000..412de26d --- /dev/null +++ b/tr/thing_37/README.md @@ -0,0 +1,13 @@ +# Sıkı Çalışmanın Getirisi Yok + +Bir yazılımcı olarak, çok çalışmak çoğu zaman işe yaramaz. Ofiste uzun saatler geçirerek kendinizi ve birkaç iş arkadaşınızı bir projeye çok şey kattığınıza inandırabilirsiniz. Ancak gerçek şu ki, daha az çalışarak daha fazlasını elde edebilirsiniz bazen çok daha fazlasını. Haftada 30 saatten fazla odaklanmış ve 'verimli' olmaya çalışıyorsanız, muhtemelen çok çalışıyorsunuzdur. Daha etkili olmak ve daha fazlasını yapmak için iş yükünü azaltmayı düşünmelisiniz. + +Bu ifade mantıksız ve hatta tartışmalı görünebilir, ancak programlama ve yazılım geliştirmenin bir bütün olarak sürekli bir öğrenme sürecini içerdiği gerçeğinin doğrudan bir sonucudur. Bir proje üzerinde çalışırken, problem alanını daha fazla anlayacaksınız ve umarım hedefe ulaşmanın daha etkili yollarını bulacaksınız. Boşa harcanan işlerden kaçınmak için, yaptıklarınızın etkilerini gözlemlemek, gördükleriniz üzerinde düşünmek ve buna göre davranışlarınızı değiştirmek için zaman tanımalısınız. + +Profesyonel programlama, genellikle, asfalt bir yolun sonunda hedefin görülebildiği birkaç kilometre için çok koşmak gibi değildir. Çoğu yazılım projesi daha çok uzun bir oryantiring maratonu gibidir. Karanlıkta. Kılavuz olarak sadece kabataslak bir harita ile. Olabildiğince hızlı koşarak tek bir yöne doğru yola çıkarsanız, bazılarını etkileyebilirsiniz, ancak muhtemelen başarılı olamazsınız. Sürdürülebilir bir tempo tutmanız ve nerede olduğunuz ve nereye gittiğinizle ilgili daha fazla bilgi edindiğinizde rotayı ayarlamanız gerekir. + +Ayrıca, genel olarak yazılım geliştirme ve özel olarak programlama teknikleri hakkında her zaman daha fazla bilgi edinmeniz gerekir. Muhtemelen kitap okumanız, konferanslara gitmeniz, diğer profesyonellerle iletişim kurmanız, yeni uygulama tekniklerini denemeniz ve işinizi basitleştiren güçlü araçlar hakkında bilgi edinmeniz gerekiyor. Profesyonel bir yazılımcı olarak, kendinizi uzmanlık alanınızda güncel tutmalısınız, tıpkı beyin cerrahlarının ve pilotların kendi uzmanlık alanlarında kendilerini güncel tutmaları beklendiği gibi. Akşamları, hafta sonlarını ve tatilleri kendinizi eğitmek için harcamanız gerekiyor, bu nedenle akşamları, hafta sonlarını ve tatillerinizi mevcut projenizde fazla mesai yaparak geçiremezsiniz. Beyin cerrahlarının haftada 60 saat ameliyat yapmasını mı yoksa pilotların haftada 60 saat uçmasını mı bekliyorsunuz? Tabii ki hayır, hazırlık ve eğitim mesleklerinin önemli bir parçasıdır. + +Projeye odaklanın, akıllı çözümler bularak elinizden geldiğince katkıda bulunun, becerilerinizi geliştirin, yaptığınız işe odaklanın ve davranışlarınızı uyarlayın. Çarkı çeviren kafesteki bir hamster gibi davranarak kendinizi ve mesleğimizi utandırmaktan kaçının. Profesyonel bir yazılımcı olarak haftada 60 saat odaklanmaya ve 'üretken' olmaya çalışmanın mantıklı bir şey olmadığını bilmelisiniz. Bir profesyonel gibi davranın: hazırlanın, etkileyin, gözlemleyin, yansıtın ve değiştirin. + +[Olve Maudal](http://programmer.97things.oreilly.com/wiki/index.php/Olve_Maudal) Tarafından \ No newline at end of file diff --git a/tr/thing_38/README.md b/tr/thing_38/README.md new file mode 100644 index 00000000..0a3db875 --- /dev/null +++ b/tr/thing_38/README.md @@ -0,0 +1,23 @@ +# Hata İzleyici Nasıl Kullanılır + +Bunlara *hata*, *kusur*, hatta *tasarım yan etkileri* deseniz de, onlardan kaçış yoktur. İyi bir hata raporunun nasıl gönderileceğini ve ayrıca bir tanesinde nelerin aranacağını bilmek, bir projenin güzel bir şekilde ilerlemesini sağlamak için temel becerilerdir. + +İyi bir hata raporunun üç şeye ihtiyacı vardır: + +- Hatanın mümkün olduğunca kesin olarak nasıl yeniden oluşturulacağı ve bunun ne sıklıkla hatanın ortaya çıkmasına neden olacağı. +- En azından sana göre ne olması gerekirdi. +- Gerçekte ne olduğu veya en azından kaydettiğiniz kadar bilgi. + +Bir hatada bildirilen bilgilerin miktarı ve kalitesi, hata hakkında olduğu kadar rapor eden hakkında da çok şey söyler. Kızgın, kısa hatalar ("Bu işlev berbat!"), geliştiricilere kötü zaman geçirdiğinizi söyler, ancak başka bir şey değil. Çoğaltmayı kolaylaştırmak için bol miktarda içeriğe sahip bir hata, bir sürümü durdursa bile herkesin saygısını kazanır. + +Hatalar, herkesin önünde tüm geçmişi olan bir sohbet gibidir. Başkalarını suçlamayın veya hatanın varlığını inkar etmeyin. Bunun yerine daha fazla bilgi isteyin veya neleri kaçırmış olabileceğinizi düşünün. + +Bir hatanın durumunu, örneğin *Açık*'ı *Kapalı* olarak değiştirmek, hata hakkında ne düşündüğünüzün genel bir ifadesidir. Hatanın neden kapatılması gerektiğini düşündüğünüzü açıklamak için zaman ayırmak, hayal kırıklığına uğramış yöneticilere ve müşterilere haklı çıkarmanın ardından sıkıcı saatler kazandıracaktır. Bir hatanın önceliğini değiştirmek benzer bir genel açıklamadır ve sizin için önemsiz olması, başka birinin ürünü kullanmasını engellemediği anlamına gelmez. + +Kendi amaçlarınız için bir böceğin alanlarını aşırı yüklemeyin. Bir hatanın konu alanına "VITAL:" eklemek, bazı raporların sonuçlarını sıralamanızı kolaylaştırabilir, ancak sonunda başkaları tarafından kopyalanacak ve kaçınılmaz olarak yanlış yazılacak veya başka bir raporda kullanılmak üzere kaldırılması gerekecektir. Bunun yerine yeni bir değer veya yeni bir alan kullanın ve diğer kişilerin kendilerini tekrar etmesine gerek kalmaması için alanın nasıl kullanılması gerektiğini belgeleyin. + +Herkesin, ekibin üzerinde çalışması gereken hataları nasıl bulacağını bildiğinden emin olun. Bu genellikle açık bir ada sahip genel bir sorgu kullanılarak yapılabilir. Herkesin aynı sorguyu kullandığından emin olun ve herkesin üzerinde çalıştığı şeyi değiştirdiğinizi ekibe bildirmeden bu sorguyu güncellemeyin. + +Son olarak, bir hatanın standart bir iş birimi olmadığını, bir kod satırının kesin bir çaba ölçümü olmadığını unutmayın. + +[Matt Doar](http://programmer.97things.oreilly.com/wiki/index.php/Matt_Doar) Tarafından \ No newline at end of file diff --git a/tr/thing_39/README.md b/tr/thing_39/README.md new file mode 100644 index 00000000..068842ea --- /dev/null +++ b/tr/thing_39/README.md @@ -0,0 +1,24 @@ +# Kodu Kaldırarak İyileştirin + +*Az* ama öz. Bu oldukça basmakalıp küçük bir özdeyiş, ama bazen gerçekten de doğru. + +Son birkaç hafta içinde kod tabanımızda yaptığım iyileştirmelerden biri, onun parçalarını kaldırmak. + +Yazılımı, YAGNI (yani, İhtiyacınız Olmayacak(You Aren't Gonna Need It)) dahil olmak üzere XP ilkelerini izleyerek yazdık. İnsan doğası ne ise, kaçınılmaz olarak birkaç yerde yetersiz kaldık. + +Ürünün belirli görevleri yerine getirmesinin çok uzun sürdüğünü gözlemledim, neredeyse anında olması gereken basit görevlerdi. Bunun nedeni, aşırı uygulanmış olmalarıydı; Gerekmeyen ekstra çan ve ıslıklarla süslenmişti, ama o zamanlar iyi bir fikir gibi görünüyordu. + +Bu nedenle, kodu basitleştirdim, ürün performansını iyileştirdim ve yalnızca rahatsız edici özellikleri kod tabanından kaldırarak global kod entropisi seviyesini düşürdüm. Yararlı bir şekilde, birim testlerim bana operasyon sırasında başka hiçbir şeyi kırmadığımı söylüyor. + +Basit ve tamamen tatmin edici bir deneyim. + +Öyleyse neden gereksiz kod ilk etapta orada kaldı? Neden bir yazılımcı fazladan kod yazma ihtiyacı hissetti ve bu, gözden geçirme veya eşleştirme sürecini nasıl geçti? Neredeyse kesinlikle şöyle bir şey: + +- Eğlenceli ekstra bir şeydi ve yazılımcı bunu yazmak istedi. *(İpucu: Kod yazın, sizi eğlendirdiği için değil değer kattığı için yazın.)* +- Birisi gelecekte gerekli olabileceğini düşündü, bu yüzden şimdi kodlamanın en iyisi olduğunu düşündü. *(İpucu: Bu YAGNI değil. Şu anda ihtiyacınız yoksa hemen yazmayın.)* +- O kadar büyük bir "ekstra" gibi görünmüyordu, bu yüzden gerçekten gerekli olup olmadığını görmek için müşteriye geri dönmek yerine uygulamak daha kolaydı. *(İpucu: Fazladan kod yazmak ve korumak her zaman daha uzun sürer. Ve müşteriye aslında oldukça ulaşılabilir. Fazladan küçük bir kod parçası zamanla kartopu yaparak bakım gerektiren büyük bir iş parçasına dönüşür.)* +- Yazılımcı, ek özelliği haklı çıkaran ne belgelenmiş ne de tartışılmış ek gereksinimler icat etti. Gereksinim aslında sahteydi. *(İpucu: Sistem gereksinimlerini yazılımcılar belirlemez; müşteri yapar.)* + +Şu an ne üzerinde çalışıyorsunuz? Hepsi gerekli mi? + +[Pete Goodliffe](http://programmer.97things.oreilly.com/wiki/index.php/Pete_Goodliffe) Tarafından diff --git a/tr/thing_40/README.md b/tr/thing_40/README.md new file mode 100644 index 00000000..9d6d6d65 --- /dev/null +++ b/tr/thing_40/README.md @@ -0,0 +1,24 @@ +# Beni Kur + +Programınızla zerre kadar ilgilenmiyorum. + +Etrafım sorunlarla çevrili ve kolum kadar uzun bir yapılacaklar listem var. Şu anda web sitenizde bulunmamın tek nedeni, her sorunumun yazılımınız tarafından ortadan kaldırılacağına dair olası olmayan bir söylenti duymamdır. Eğer şüpheciysem beni affedeceksiniz. + +Göz küresi izleme çalışmaları doğruysa, başlığı zaten okudum ve *şimdi indir* olarak işaretlenmiş mavi altı çizili metni tarıyorum. Bir kenara, eğer bu sayfaya Birleşik Krallık IP'sinden bir Linux tarayıcısıyla geldiysem, muhtemelen bir Avrupa aynasından gelen Linux sürümünü isterim, bu yüzden lütfen sormayın. Dosya iletişim kutusunun hemen açıldığını varsayarsak, dosyayı indirme klasörüme gönderiyorum ve okumaya devam ediyorum. + +Hepimiz sürekli olarak yaptığımız her şeyin maliyet-fayda analizini yaparız. Projeniz eşiğimin bir saniye bile altına düşerse, onu bırakıp başka bir şeye geçeceğim. Anında memnuniyet en iyisidir. + +İlk engel *kurulum*. Bunun büyük bir sorun olduğunu düşünmüyor musun? Şimdi indirme klasörünüze gidin ve etrafa bir göz atın. *tar* ve *zip* dosyalarıyla dolu değil mi? Bunların yüzde kaçını açtınız? Kaç tane kurdunuz? Benim gibiyseniz, yalnızca üçte biri sabit disk dolgusu görevi yapmaktan biraz daha fazlasını yapıyor. + +Kapı eşiğinde rahatlık isteyebilirim ama evime davetsiz girmeni istemiyorum. Kurulumu yazmadan önce, tam olarak nereye bir şeyler koyduğunuzu bilmek istiyorum. Bu benim bilgisayarım ve elimden geldiğince düzenli tutmayı seviyorum. Ayrıca, büyüm bozulduğu anda programınızı kaldırabilmek istiyorum. Bunun imkansız olduğundan şüphelenirsem, ilk etapta kurmayacağım. Makinem şu anda kararlı ve bu şekilde kalmasını istiyorum. + +Programınız GUI tabanlıysa, basit bir şey yapmak ve bir sonuç görmek istiyorum. Sihirbazlar yardımcı olmuyor çünkü anlamadığım şeyler yapıyorlar. Muhtemelen bir dosya okumak veya bir tane yazmak istiyorum. Projeler oluşturmak, dizinleri içe aktarmak veya size e-posta adresimi söylemek istemiyorum. Her şey çalışıyorsa, eğitime geçin. + +Yazılımınız bir kitaplık ise, o zaman bir *hızlı başlangıç kılavuzu* arayarak web sayfanızı okumaya devam ediyorum. Tam olarak web siteniz tarafından açıklanan çıktıyla beş satırlık bir beyinsizde "Merhaba dünya" eşdeğerini istiyorum. Doldurulması gereken büyük XML dosyaları veya şablonları yok, yalnızca tek bir komut dosyası. Unutmayın, rakibinizin çerçevesini de indirdim. Bilirsin, forumlarda her zaman seninkinden çok daha iyi olduğunu iddia eden kişi? Her şey çalışıyorsa, eğiticiye. + +Bir eğitim var değil mi? Benimle anlayacağım dilde konuşan biri mi? + +Ve öğretici benim sorunumdan bahsederse, neşeleneceğim. Şimdi yapabileceğim şeyleri okuyorum, ilginç, hatta eğlenceli olmaya başlıyor. Arkama yaslanıp çayımı yudumlayacağım. İngiltere'den geldiğimi söylemiş miydim? ve örneklerinizle oynayacağım ve yaratıcılığınızı kullanmayı öğreneceğim. Eğer sorunumu çözerse, sana bir teşekkür e-postası göndereceğim. Çöktüğünde size hata raporları ve özellikler için öneriler göndereceğim. Rakibinizin yazılımını hiç denememiş olmama rağmen, tüm arkadaşlarıma yazılımınızın nasıl en iyi olduğunu söyleyeceğim. Ve hepsi, ilk geçici adımlarıma bu kadar özen gösterdiğin için. +Senden nasıl şüphelendim? + +[Marcus Baker](http://programmer.97things.oreilly.com/wiki/index.php/Marcus_Baker) Tarafından \ No newline at end of file diff --git a/tr/thing_41/README.html b/tr/thing_41/README.html new file mode 100644 index 00000000..b9375c16 --- /dev/null +++ b/tr/thing_41/README.html @@ -0,0 +1,1079 @@ +README

Süreçler Arası İletişim Uygulama Yanıt Süresini Etkiler

+

Yanıt süresi, yazılımın kullanılabilirliği için kritik öneme sahiptir. Bazı yazılım sistemlerinin yanıt vermesini beklemek kadar sinir bozucu çok az şey vardır, özellikle de yazılımla etkileşimimiz tekrarlanan uyaran ve tepki döngülerini içerdiğinde. Yazılımın zamanımızı boşa harcadığını ve verimliliğimizi etkilediğini hissediyoruz. Performans yönetimi literatürünün çoğu, bazı durumlarda fark yaratabilecek, ancak modern çok katmanlı kurumsal uygulamalarda performansa hükmetme olasılığı çok daha düşük olan veri yapıları ve algoritmalara hala odaklanmaktadır.

+

Bu tür uygulamalarda performans bir sorun olduğunda, benim deneyimim, veri yapılarını ve algoritmaları incelemenin iyileştirme aramak için doğru yer olmadığı yönündeydi. Tepki süresi, en çok, bir uyarana yanıt olarak yürütülen uzak süreçler arası iletişimlerin (IPC’ler) sayısına bağlıdır. Başka yerel darboğazlar olsa da, süreçler arası uzak iletişimlerin sayısı genellikle baskındır. Her bir uzak süreçler arası iletişim, genel yanıt süresine ihmal edilemeyecek bir gecikme süresine katkıda bulunur ve bu bireysel katkılar, özellikle sırayla gerçekleştiklerinde toplanır.

+

En iyi örnek, nesne-ilişkisel eşleme kullanan bir uygulamada dalgalanma yüklemesidir(ripple loading).

+

Inter-Process Communication Affects Application Response Time

+

A prime example is ripple loading in an application using object–relational mapping. +Ripple loading describes the sequential execution of many database calls to select the data needed for building a graph of objects (see Lazy Load in Martin Fowler’s Patterns of Enterprise Application Architecture). +When the database client is a middle-tier application server rendering a web page, these database calls are usually executed sequentially in a single thread. +Their individual latencies accumulate, contributing to the overall response time. +Even if each database call takes only 10ms, a page requiring 1000 calls (which is not uncommon) will exhibit at least a 10-second response time. Other examples include web-service invocation, HTTP requests from a web browser, distributed object invocation, request–reply messaging, and data-grid interaction over custom network protocols. +The more remote IPCs needed to respond to a stimulus, the greater the response time will be.

+

There are a few relatively obvious and well-known strategies for reducing the number of remote inter-process communications per stimulus. One strategy is to apply the principle of parsimony, optimizing the interface between processes so that exactly the right data for the purpose at hand is exchanged with the minimum amount of interaction. Another strategy is to parallelize the inter-process communications where possible, so that the overall response time becomes driven mainly by the longest-latency IPC. A third strategy is to cache the results of previous IPCs, so that future IPCs may be avoided by hitting local cache instead.

+

When you’re designing an application, be mindful of the number of inter-process communications in response to each stimulus. When analyzing applications that suffer from poor performance, I have often found IPC-to-stimulus ratios of thousands-to-one. Reducing this ratio, whether by caching or parallelizing or some other technique, will pay off much more than changing data structure choice or tweaking a sorting algorithm.

+

Randy Stafford Tarafından

\ No newline at end of file diff --git a/tr/thing_41/README.md b/tr/thing_41/README.md new file mode 100644 index 00000000..ceb34fb5 --- /dev/null +++ b/tr/thing_41/README.md @@ -0,0 +1,13 @@ +# Süreçler Arası İletişim Uygulama Yanıt Süresini Etkiler + +Yanıt süresi, yazılımın kullanılabilirliği için kritik öneme sahiptir. Bazı yazılım sistemlerinin yanıt vermesini beklemek kadar sinir bozucu çok az şey vardır, özellikle de yazılımla etkileşimimiz tekrarlanan uyaran ve tepki döngülerini içerdiğinde. Yazılımın zamanımızı boşa harcadığını ve verimliliğimizi etkilediğini hissediyoruz. Performans yönetimi literatürünün çoğu, bazı durumlarda fark yaratabilecek, ancak modern çok katmanlı kurumsal uygulamalarda performansa hükmetme olasılığı çok daha düşük olan veri yapıları ve algoritmalara hala odaklanmaktadır. + +Bu tür uygulamalarda performans bir sorun olduğunda, benim deneyimim, veri yapılarını ve algoritmaları incelemenin iyileştirme aramak için doğru yer olmadığı yönündeydi. Tepki süresi, en çok, bir uyarana yanıt olarak yürütülen uzak süreçler arası iletişimlerin (IPC'ler) sayısına bağlıdır. Başka yerel darboğazlar olsa da, süreçler arası uzak iletişimlerin sayısı genellikle baskındır. Her bir uzak süreçler arası iletişim, genel yanıt süresine ihmal edilemeyecek bir gecikme süresine katkıda bulunur ve bu bireysel katkılar, özellikle sırayla gerçekleştiklerinde toplanır. + +En iyi örnek, nesne-ilişkisel eşleme kullanan bir uygulamada *dalgalanma yüklemesidir(ripple loading)*. Dalgalı yükleme, nesnelerin grafiğini oluşturmak için gereken verileri seçmek için birçok veritabanı çağrısının sıralı yürütülmesini açıklar (Martin Fowler'ın *Patterns of Enterprise Application Architecture* içindeki [Lazy Load](http://martinfowler.com/eaaCatalog/lazyLoad.html) bölümüne bakın). Veritabanı istemcisi bir web sayfası oluşturan orta düzey bir uygulama sunucusu olduğunda, bu veritabanı çağrıları genellikle tek bir iş parçacığında sırayla yürütülür. Bireysel gecikme süreleri birikerek genel yanıt süresine katkıda bulunur. Her veritabanı araması yalnızca 10 ms sürse bile, 1000 arama gerektiren bir sayfa (ki bu nadir değildir) en az 10 saniyelik bir yanıt süresi sergileyecektir. Diğer örnekler arasında web hizmeti çağırma, bir web tarayıcısından HTTP istekleri, dağıtılmış nesne çağırma, istek-yanıt mesajlaşma ve özel ağ protokolleri üzerinden veri sistemi etkileşimi sayılabilir. Bir uyarana yanıt vermek için ne kadar uzak IPC'ye ihtiyaç duyulursa, yanıt süresi o kadar uzun olacaktır. + +Uyaran başına uzak süreçler arası iletişimlerin sayısını azaltmak için nispeten açık ve iyi bilinen birkaç strateji vardır. Bir strateji, eldeki amaç için tam olarak doğru verilerin minimum miktarda etkileşimle değiş tokuş edilmesi için süreçler arasındaki arayüzü optimize ederek tutumluluk ilkesini uygulamaktır. Diğer bir strateji, mümkün olduğunda süreçler arası iletişimi paralel hale getirmektir, böylece genel yanıt süresi esas olarak en uzun gecikmeli IPC tarafından yönlendirilir. Üçüncü bir strateji, önceki IPC'lerin sonuçlarını önbelleğe almaktır, böylece bunun yerine yerel önbelleğe basarak gelecekteki IPC'lerden kaçınılabilir. + +Bir uygulama tasarlarken, her bir uyarana yanıt olarak süreçler arası iletişimlerin sayısına dikkat edin. Düşük performanstan muzdarip uygulamaları analiz ederken, genellikle IPC-uyarıcı oranlarının binlere bir olduğunu gördüm. İster önbelleğe alma, ister paralelleştirme veya başka bir teknikle bu oranı azaltmak, veri yapısı seçimini değiştirmekten veya bir sıralama algoritmasında ince ayar yapmaktan çok daha fazlasını kazandıracaktır. + +[Randy Stafford](http://programmer.97things.oreilly.com/wiki/index.php/Randy_Stafford) Tarafından \ No newline at end of file diff --git a/tr/thing_42/README.html b/tr/thing_42/README.html new file mode 100644 index 00000000..a356a426 --- /dev/null +++ b/tr/thing_42/README.html @@ -0,0 +1,1074 @@ +README

Yapıyı Temiz Tutun

+

Hiç kötü kodlama üzerine bir makalenin uzunluğu hakkında bir derleyici uyarısı listesine bakıp ve kendi kendinize düşündünüz mü: “Biliyorsunuz, bu konuda gerçekten bir şeyler yapmalıyım… ama şu anda zamanım yok?” Öte yandan, bir derlemede yeni ortaya çıkan ve onu düzelten yalnız bir uyarıya hiç baktınız mı?

+

Sıfırdan yeni bir projeye başladığımda hiçbir uyarı, dağınıklık, sorun yok. Ancak kod tabanı büyüdükçe, dikkat etmezsem, dağınıklık, boşluk, uyarılar ve sorunlar birikmeye başlayabilir. Çok fazla gürültü olduğunda, umursamadığım yüzlerce uyarı arasında gerçekten okumak istediğim uyarıyı bulmak çok daha zor.

+

Uyarıları tekrar kullanışlı hale getirmek için yapıdan gelen uyarılar için sıfır tolerans politikası kullanmaya çalışıyorum. Uyarı önemli olmasa bile, onunla ilgilenirim. Kritik değilse, ancak yine de alakalıysa, düzeltirim. Derleyici potansiyel bir boş gösterici istisnası hakkında uyarırsa, nedeni düzeltirim, sorunun üretimde asla ortaya çıkmayacağını “bilsem” bile. Gömülü belgeler (Javadoc veya benzeri), kaldırılmış veya yeniden adlandırılmış parametrelere atıfta bulunuyorsa, belgeleri temizlerim.

+

Gerçekten umurumda olmayan bir şeyse ve bu gerçekten önemli değilse, ekibe uyarı politikamızı değiştirip değiştiremeyeceğimizi soruyorum. Örneğin, birçok durumda bir yöntemin parametrelerini ve dönüş değerini belgelemenin herhangi bir değer eklemediğini görüyorum, bu nedenle eksiklerse bir uyarı olmamalıdır. Veya, programlama dilinin yeni bir sürümüne yükseltmek, daha önce uygun olan kodun şimdi uyarı vermesine neden olabilir. Örneğin, Java 5 generic leri tanıttığında, generic tür parametresini belirtmeyen tüm eski kodlar bir uyarı verirdi. Bu, hakkında rahatsız edilmek istemediğim bir tür uyarı (en azından henüz değil).

+

Keep the Build Clean

+

By making sure that the build is always clean, I will not have to decide that a warning is irrelevant every time I encounter it. Ignoring things is mental work, and I need to get rid of all the unnecessary mental work I can. Having a clean build also makes it easier for someone else to take over my work. If I leave the warnings, someone else will have to wade through what is relevant and what is not. Or more likely, just ignore all the warnings, including the significant ones.

+

Warnings from your build are useful. You just need to get rid of the noise to start noticing them. Don’t wait for a big clean-up. When something appears that you don’t want to see, deal with it right away. Either fix the source of the warning, suppress this warning or fix the warning policies of your tool. Keeping the build clean is not just about keeping it free of compilation errors or test failures: Warnings are also an important and critical part of code hygiene.

+

Johannes Brodwall Tarafından

\ No newline at end of file diff --git a/tr/thing_42/README.md b/tr/thing_42/README.md new file mode 100644 index 00000000..b161cee3 --- /dev/null +++ b/tr/thing_42/README.md @@ -0,0 +1,15 @@ +# Yapıyı Temiz Tutun + +Hiç kötü kodlama üzerine bir makalenin uzunluğu hakkında bir derleyici uyarısı listesine bakıp ve kendi kendinize düşündünüz mü: "Biliyorsunuz, bu konuda gerçekten bir şeyler yapmalıyım... ama şu anda zamanım yok?" Öte yandan, bir derlemede yeni ortaya çıkan ve onu düzelten yalnız bir uyarıya hiç baktınız mı? + +Sıfırdan yeni bir projeye başladığımda hiçbir uyarı, dağınıklık, sorun yok. Ancak kod tabanı büyüdükçe, dikkat etmezsem, dağınıklık, boşluk, uyarılar ve sorunlar birikmeye başlayabilir. Çok fazla gürültü olduğunda, umursamadığım yüzlerce uyarı arasında gerçekten okumak istediğim uyarıyı bulmak çok daha zor. + +Uyarıları tekrar kullanışlı hale getirmek için yapıdan gelen uyarılar için sıfır tolerans politikası kullanmaya çalışıyorum. Uyarı önemli olmasa bile, onunla ilgilenirim. Kritik değilse, ancak yine de alakalıysa, düzeltirim. Derleyici potansiyel bir boş gösterici istisnası hakkında uyarırsa, nedeni düzeltirim, sorunun üretimde asla ortaya çıkmayacağını "bilsem" bile. Gömülü belgeler (Javadoc veya benzeri), kaldırılmış veya yeniden adlandırılmış parametrelere atıfta bulunuyorsa, belgeleri temizlerim. + +Gerçekten umurumda olmayan bir şeyse ve bu gerçekten önemli değilse, ekibe uyarı politikamızı değiştirip değiştiremeyeceğimizi soruyorum. Örneğin, birçok durumda bir yöntemin parametrelerini ve dönüş değerini belgelemenin herhangi bir değer eklemediğini görüyorum, bu nedenle eksiklerse bir uyarı olmamalıdır. Veya, programlama dilinin yeni bir sürümüne yükseltmek, daha önce uygun olan kodun şimdi uyarı vermesine neden olabilir. Örneğin, Java 5 generic leri tanıttığında, generic tür parametresini belirtmeyen tüm eski kodlar bir uyarı verirdi. Bu, hakkında rahatsız edilmek istemediğim bir tür uyarı (en azından henüz değil). Gerçeğe uymayan bir dizi uyarıya sahip olmak kimseye fayda sağlamaz. + +Yapının her zaman temiz olduğundan emin olarak, her karşılaştığımda bir uyarının alakasız olduğuna karar vermek zorunda kalmayacağım. Bir şeyleri görmezden gelmek zihinsel iş ve yapabileceğim tüm gereksiz zihinsel çalışmalardan kurtulmam gerekiyor. Temiz bir yapıya sahip olmak, bir başkasının işimi devralmasını da kolaylaştırıyor. Uyarıları bırakırsam, bir başkasının neyin alakalı olup neyin olmadığını gözden geçirmesi gerekecek. Veya daha büyük olasılıkla, önemli olanlar da dahil olmak üzere tüm uyarıları görmezden gelin. + +Yapınızdan gelen uyarılar faydalıdır. Onları fark etmeye başlamak için sadece gürültüden kurtulmanız gerekir. Büyük bir temizlik için beklemeyin. Görmek istemediğiniz bir şey göründüğünde, hemen onunla ilgilenin. Ya uyarının kaynağını düzeltin, bu uyarıyı bastırın ya da aracınızın uyarı ilkelerini düzeltin. Derlemeyi temiz tutmak yalnızca derleme hatalarından veya test hatalarından uzak tutmakla ilgili değildir: Uyarılar da kod hijyeninin önemli ve kritik bir parçasıdır. + +[Johannes Brodwall](http://programmer.97things.oreilly.com/wiki/index.php/Johannes_Brodwall) Tarafından \ No newline at end of file diff --git a/tr/thing_43/README.md b/tr/thing_43/README.md new file mode 100644 index 00000000..ce6ee220 --- /dev/null +++ b/tr/thing_43/README.md @@ -0,0 +1,13 @@ +# Komut Satırı Araçlarını Nasıl Kullanacağınızı Bilin + +Günümüzde birçok yazılım geliştirme aracı, Entegre Geliştirme Ortamları (IDE'ler) biçiminde paketlenmiştir. Microsoft'un Visual Studio'su ve açık kaynaklı Eclipse, daha birçokları olmasına rağmen iki popüler örnektir. IDE'ler hakkında sevilecek çok şey var. Sadece kullanımları kolay olmakla kalmaz, aynı zamanda programcıyı yapım süreciyle ilgili birçok küçük ayrıntıyı düşünmekten kurtarır. + +Ancak kullanım kolaylığının dezavantajı vardır. Tipik olarak, bir aracın kullanımı kolay olduğunda, bunun nedeni aracın sizin adınıza kararlar vermesi ve sahne arkasında birçok şeyi otomatik olarak yapmasıdır. Bu nedenle, bir IDE şimdiye kadar kullandığınız tek programlama ortamıysa, araçlarınızın gerçekte ne yaptığını asla tam olarak anlayamayabilirsiniz. Bir düğmeye tıklarsınız, biraz sihir oluşur ve proje klasöründe yürütülebilir bir dosya belirir. + +Komut satırı oluşturma araçlarıyla çalışarak, projeniz oluşturulurken araçların ne yaptığı hakkında çok daha fazla şey öğreneceksiniz. Kendi make dosyalarınızı yazmak, yürütülebilir bir dosya oluşturmaya giden tüm adımları (derleme, birleştirme, bağlama, vb.) anlamanıza yardımcı olacaktır. Bu araçlar için birçok komut satırı seçeneğiyle denemeler yapmak da değerli bir eğitim deneyimidir. Komut satırı oluşturma araçlarını kullanmaya başlamak için GCC gibi açık kaynaklı komut satırı araçlarını kullanabilir veya tescilli IDE'nizle sağlananları kullanabilirsiniz. Sonuçta, iyi tasarlanmış bir IDE, bir dizi komut satırı aracının yalnızca grafiksel bir ön yüzüdür. + +Oluşturma sürecini anlamanızı geliştirmenin yanı sıra, komut satırı araçlarıyla bir IDE'den daha kolay veya daha verimli bir şekilde gerçekleştirilebilecek bazı görevler vardır. Örneğin, *grep* ve *sed* yardımcı programları tarafından sağlanan arama ve değiştirme yetenekleri, genellikle IDE'lerde bulunanlardan daha güçlüdür. Komut satırı araçları, programlanmış günlük derlemeler oluşturma, bir projenin birden çok sürümünü oluşturma ve test takımlarını çalıştırma gibi görevlerin otomasyonuna olanak tanıyan komut dosyası oluşturmayı doğal olarak destekler. Bir IDE'de, inşa seçenekleri genellikle GUI iletişim kutuları kullanılarak belirlendiğinden ve oluşturma işlemi bir fare tıklamasıyla başlatıldığından, bu tür bir otomasyonun yapılması (imkansız değilse) daha zor olabilir. IDE'nin dışına hiç çıkmadıysanız, bu tür otomatik görevlerin mümkün olduğunu bile fark etmeyebilirsiniz. + +Fakat bekle. IDE, geliştirmeyi kolaylaştırmak ve programcının üretkenliğini artırmak için mevcut değil mi? İyi evet. Burada sunulan öneri, IDE'leri kullanmayı bırakmanız gerektiği değildir. Öneri, "başlığın altına bakmanız" ve IDE'nizin sizin için ne yaptığını anlamanızdır. Bunu yapmanın en iyi yolu komut satırı araçlarını kullanmayı öğrenmektir. Ardından, IDE'nizi kullanmaya geri döndüğünüzde, sizin için ne yaptığını ve oluşturma sürecini nasıl kontrol edebileceğinizi çok daha iyi anlayacaksınız. Öte yandan, komut satırı araçlarının kullanımında ustalaştıktan ve sundukları güç ve esnekliği deneyimledikten sonra, IDE yerine komut satırını tercih ettiğinizi görebilirsiniz. + +[Carroll Robinson](http://programmer.97things.oreilly.com/wiki/index.php/Carroll_Robinson) Tarafından \ No newline at end of file diff --git a/tr/thing_44/README.md b/tr/thing_44/README.md new file mode 100644 index 00000000..a39ba028 --- /dev/null +++ b/tr/thing_44/README.md @@ -0,0 +1,19 @@ +# İkiden Fazla Programlama Dilini İyi Bilin + +Programlama psikolojisi, programlama uzmanlığının, bir programcının rahat olduğu farklı programlama paradigmalarının sayısıyla doğrudan ilişkili olduğunu uzun zamandır biliyor. Bu sadece hakkında bilmek veya biraz bilmek değil, aynı zamanda gerçekten programlayabilir. + +Her programcı bir programlama dili ile başlar. Bu dil, programcının yazılım hakkında düşünme biçimi üzerinde baskın bir etkiye sahiptir. Programcı o dili kullanmak için kaç yıllık deneyime sahip olursa olsun, o dilde kalırsa sadece o dili bilecektir. *Tek dil* bir programcı, düşüncelerinde o dil tarafından kısıtlanır. + +İkinci bir dil öğrenen bir programcı, özellikle o dilin ilkinden farklı bir hesaplama modeline sahipse, zorlanacaktır. C, Pascal, Fortran, hepsi aynı temel hesaplama modeline sahiptir. Fortran'dan C'ye geçiş, pek çok olmasa da birkaç zorluk getirir. C veya Fortran'dan C++ veya Ada'ya geçiş, programların davranış biçiminde temel zorlukları beraberinde getirir. C++'dan Haskell'e geçiş önemli bir değişiklik ve dolayısıyla önemli bir zorluktur. C'den Prolog'a geçmek çok kesin bir zorluktur. + +Bir dizi hesaplama paradigmasını sıralayabiliriz: prosedürel, nesne yönelimli, işlevsel, mantık, veri akışı, vb. Bu paradigmalar arasında hareket etmek en büyük zorlukları yaratır. + +Bu zorluklar neden iyi? Algoritmaların uygulanması hakkında düşünme şeklimiz ve geçerli olan uygulama deyimleri ve kalıpları ile ilgilidir. Özellikle çapraz gübreleme, uzmanlığın merkezinde yer alır. Bir dilde geçerli olan problem çözümleri için deyimler başka bir dilde mümkün olmayabilir. Deyimleri bir dilden diğerine aktarmaya çalışmak bize her iki dili ve çözülmekte olan sorunu öğretir. + +Programlama dillerinin kullanımında çapraz gübrelemenin büyük etkileri vardır. Belki de en belirgin olanı, zorunlu dillerde uygulanan sistemlerde bildirimsel ifade biçimlerinin artan ve artan kullanımıdır. İşlevsel programlama konusunda bilgili herkes, C gibi bir dil kullanırken bile bildirimsel bir yaklaşımı kolaylıkla uygulayabilir. Bildirimsel yaklaşımları kullanmak genellikle daha kısa ve daha anlaşılır programlara yol açar. Örneğin, C++, neredeyse bildirimsel bir ifade kipini gerektiren genel programlamaya yönelik yürekten desteğiyle bunu kesinlikle kabul ediyor. + +Tüm bunların sonucu, her programcının en az iki farklı paradigmada ve ideal olarak en az yukarıda belirtilen beş paradigmada programlama konusunda iyi becerilere sahip olması gerektiğidir. Programcılar her zaman, tercihen yabancı bir paradigmadan yeni diller öğrenmekle ilgilenmelidir. Günlük iş her zaman aynı programlama dilini kullansa bile, bir kişi diğer paradigmalardan çapraz gübreleme yapabildiğinde bu dilin kullanımının artan karmaşıklığı hafife alınmamalıdır. İşverenler bunu dikkate almalı ve eğitim bütçelerinde çalışanların, kullanılan dillerin kullanımının karmaşıklığını artırmanın bir yolu olarak şu anda kullanılmayan dilleri öğrenmelerine izin vermelidir. + +Her ne kadar bir başlangıç olsa da, bir haftalık eğitim kursu yeni bir dil öğrenmek için yeterli değildir: Bir dil hakkında uygun bir çalışma bilgisi kazanmak için genellikle birkaç ay, yarı zamanlı bile olsa, kullanım yeterlidir. Önemli faktörler sadece sözdizimi ve hesaplama modeli değil, kullanım deyimleridir. + +[Russel Winder](http://programmer.97things.oreilly.com/wiki/index.php/Russel_Winder) Tarafından \ No newline at end of file diff --git a/tr/thing_45/README.md b/tr/thing_45/README.md new file mode 100644 index 00000000..214025d8 --- /dev/null +++ b/tr/thing_45/README.md @@ -0,0 +1,23 @@ +# IDE'nizi Bilin + +1980'lerde programlama ortamlarımız tipik olarak yüceltilmiş metin editörlerinden daha iyi değildi... eğer şanslıysak. Bugünlerde hafife aldığımız sözdizimi vurgulama, kesinlikle herkesin erişemeyeceği bir lükstü. Kodumuzu güzel bir şekilde biçimlendirmek için güzel yazıcılar, genellikle boşluklarımızı düzeltmek için çalıştırılması gereken harici araçlardı. Hata ayıklayıcılar aynı zamanda kodumuzda adım adım ilerleyen, ancak çok sayıda şifreli tuş vuruşuyla çalışan ayrı programlardı. + +1990'larda şirketler, programcıları daha iyi ve daha kullanışlı araçlarla donatmaktan elde edebilecekleri potansiyel geliri fark etmeye başladılar. Entegre Geliştirme Ortamı (IDE), önceki düzenleme özelliklerini bir derleyici, hata ayıklayıcı, güzel yazıcı ve diğer araçlarla birleştirdi. Bu süre zarfında menüler ve fare de popüler hale geldi, bu da geliştiricilerin editörlerini kullanmak için artık şifreli tuş kombinasyonlarını öğrenmeleri gerekmediği anlamına geliyordu. Menüden komutlarını kolayca seçebilirler. + +21. yüzyılda IDE'ler o kadar yaygın hale geldi ki, diğer alanlarda pazar payı kazanmak isteyen şirketler tarafından ücretsiz olarak dağıtılıyor. Modern IDE, inanılmaz bir dizi özellikle donatılmıştır. En sevdiğim, otomatik yeniden düzenleme, özellikle bir kod yığınını seçip bir yönteme dönüştürebildiğim *Çıkarma Yöntemi*. Yeniden düzenleme aracı, yönteme geçirilmesi gereken tüm parametreleri alır ve bu da kodu değiştirmeyi son derece kolaylaştırır. IDE'm, bu yöntemle değiştirilebilecek diğer kod parçalarını bile algılayacak ve onları da değiştirmek isteyip istemediğimi soracak. + +Modern IDE'lerin bir başka şaşırtıcı özelliği de bir şirket içinde stil kurallarını uygulama yeteneğidir. Örneğin, Java'da bazı programcılar tüm parametreleri nihai hale getirmeye başladılar (bence bu bir zaman kaybıdır). Ancak, böyle bir stil kuralına sahip oldukları için, bunu takip etmek için tek yapmam gereken, onu IDE'mde ayarlamak: Son olmayan herhangi bir parametre için bir uyarı alırdım. Stil kuralları, örneğin, referans nesnelere otomatik kutulanmış ilkel değerler üzerinde `==` kullanmak gibi, otomatik kutulanmış nesneleri referans eşitliği için karşılaştırmak gibi olası hataları bulmak için de kullanılabilir. + +Ne yazık ki modern IDE'ler, onları nasıl kullanacağımızı öğrenmek için çaba harcamamızı gerektirmiyor. Unix'te C'yi ilk programladığımda, dik öğrenme eğrisi nedeniyle vi editörünün nasıl çalıştığını öğrenmek için biraz zaman harcamak zorunda kaldım. Önceden harcanan bu süre, yıllar içinde cömertçe karşılığını verdi. Hatta bu yazının taslağını *vi* ile yazıyorum. Modern IDE'lerin çok kademeli bir öğrenme eğrisi vardır ve bu, aracın en temel kullanımının ötesine asla geçemeyeceğimiz etkisine sahip olabilir. + +Bir IDE öğrenmede ilk adımım klavye kısayollarını ezberlemektir. Kodumu yazarken parmaklarım klavyede olduğundan, bir değişkeni satır içi yapmak için *Ctrl+Shift+I* tuşlarına basmak akışı bozmaktan tasarruf sağlarken, faremle bir menüde gezinmeye geçmek akışı keser. Bu kesintiler gereksiz bağlam geçişlerine yol açıyor ve her şeyi tembel bir şekilde yapmaya çalışırsam beni çok daha az üretken yapıyor. Aynı kural klavye becerileri için de geçerlidir: Yazıya dokunmayı öğrenin, önceden harcadığınız zamana pişman olmayacaksınız. + +Son olarak, programcılar olarak, kodumuzu değiştirmemize yardımcı olabilecek, zamanı kanıtlanmış Unix akış araçlarına sahibiz. Örneğin, bir kod incelemesi sırasında, programcıların birçok sınıfı aynı adlandırdığını fark edersem, *find*, *sed*, *sort*, *uniq* ve *grep* araçlarını kullanarak bunları çok kolay bulabilirim, bunun gibi: + +``` +find . -name "*.java" | sed 's/.*\///' | sort | uniq -c | grep -v "^ *1 " | sort -r +``` + +Evimize gelen bir tesisatçının el fenerini kullanabilmesini bekliyoruz. IDE'mizle nasıl daha etkili olabileceğimizi incelemek için biraz zaman harcayalım. + +[Heinz Kabutz](http://programmer.97things.oreilly.com/wiki/index.php/Heinz_Kabutz) Tarafından \ No newline at end of file diff --git a/tr/thing_46/README.md b/tr/thing_46/README.md new file mode 100644 index 00000000..1cfaed52 --- /dev/null +++ b/tr/thing_46/README.md @@ -0,0 +1,49 @@ +# Sınırlarınızı Bilin + +> *"İnsan sınırlarını bilmeli." — Dirty Harry* + +Kaynaklarınız sınırlı. Bilginizi, becerilerinizi ve araçlarınızı güncel tutmak için gereken zaman ve para dahil, işinizi yapmak için yalnızca çok fazla zamanınız ve paranız var. Sadece çok sıkı, çok hızlı, çok akıllı ve çok uzun süre çalışabilirsin. Araçlarınız sadece çok güçlü. Hedef makineleriniz sadece çok güçlü. Bu yüzden kaynaklarınızın sınırlarına saygı göstermelisiniz. + +Bu sınırlara nasıl saygı duyulur? Kendinizi tanıyın, çalışanlarınızı tanıyın, bütçelerinizi bilin ve eşyalarınızı bilin. Özellikle bir yazılım mühendisi olarak, veri yapılarınızın ve algoritmalarınızın uzay ve zaman karmaşıklığını, sistemlerinizin mimarisini ve performans özelliklerini bilin. İşiniz, yazılım ve sistemlerin optimal bir evliliğini yaratmaktır. + +Uzay ve zaman karmaşıklığı, *O(f(n))* işlevi olarak verilir; bu, n için girdinin boyutuna eşit, asimptotik uzay veya n sonsuza kadar büyürken gereken zamandır. *f(n)* için önemli karmaşıklık sınıfları arasında *ln(n)*, *n*, *n ln(n)*, *ne* ve *en< bulunur /sup>*. Bu fonksiyonların grafiğinin açıkça gösterdiği gibi, *n* büyüdükçe *O(ln(n))*, *O(n)* ve *O(n ln(n))*'den çok daha küçüktür, ki bunlar hep böyledir *O(ne)* ve *O(en)*'dan çok daha küçüktür. Sean Parent'in belirttiği gibi, ulaşılabilir n için tüm karmaşıklık sınıfları sabite yakın, doğrusala yakın veya sonsuza yakındır. + +![](http://programmer.97things.oreilly.com/wiki/images/c/c0/Clearly.jpeg) + +| | access time | capacity | +|--------------|-----------------:| ----------:| +| register | < 1 ns | 64b | +| cache line | | 64B | +| L1 cache | 1 ns | 64 KB | +| L2 cache | 4 ns | 8 MB | +| RAM | 20 ns | 32 GB | +| disk | 10 ms | 10 TB | +| LAN | 20 ms | > 1 PB | +| internet | 100 ms | > 1 ZB | + +Karmaşıklık analizi, soyut bir makine açısından yapılır, ancak yazılım gerçek makinelerde çalışır. Modern bilgisayar sistemleri, dil çalışma zamanları, işletim sistemleri, CPU'lar, önbellek belleği, rastgele erişimli bellek, disk sürücüleri ve ağlar dahil olmak üzere fiziksel ve sanal makinelerin hiyerarşileri olarak düzenlenir. İlk tablo, tipik bir ağ bağlantılı sunucu için rasgele erişim süresi ve depolama kapasitesi üzerindeki sınırları gösterir. + +Kapasite ve hızın birkaç büyüklük derecesine göre değiştiğini unutmayın. Önbelleğe alma ve ileriye dönük, bu varyasyonu gizlemek için sistemlerimizin her düzeyinde yoğun olarak kullanılır, ancak bunlar yalnızca erişim öngörülebilir olduğunda çalışır. Önbellek kayıpları sık olduğunda sistem çöker. Örneğin, bir sabit sürücüdeki her baytı rastgele incelemek 32 yıl sürebilir. RAM'deki her baytı rastgele incelemek bile 11 dakika sürebilir. Rastgele erişim tahmin edilemez. Nedir? Bu, sisteme bağlıdır, ancak son kullanılan öğelere yeniden erişmek ve öğelere sırayla erişmek genellikle bir kazançtır. + +Algoritmalar ve veri yapıları, önbellekleri ne kadar etkili kullandıklarına göre değişir. Örneğin: +- Doğrusal arama, ileriye bakmayı iyi bir şekilde kullanır, ancak *O(n)* karşılaştırmaları gerektirir. +- Sıralanmış bir dizinin ikili araması yalnızca *O(log(n))* karşılaştırmalarını gerektirir. +- Bir van Emde Boas ağacının aranması *O(log(n))* ve önbellekten habersiz. + + +|Elements | Search time (ns)| | | +|:--------|-----------:|-----------:|--------:| +| | **linear** | **binary** | **vEB** | +| 8 | 50 | 90 | 40 | +| 64 | 180 | 150 | 70 | +| 512 | 1200 | 230 | 100 | +| 4096 | 17000 | 320 | 160 | + + +Nasıl seçilir? Son tahlilde, ölçerek. İkinci tablo, bu üç yöntemle 64 bit tamsayı dizilerini aramak için gereken süreyi gösterir. Bilgisayarımda: +- Doğrusal arama, küçük diziler için rekabetçidir, ancak daha büyük diziler için katlanarak kaybeder. +- Van Emde Boas, tahmin edilebilir erişim modeli sayesinde kesinlikle kazanıyor. + +> *"Paranı ödüyorsun ve seçimini yapıyorsun." — [Punch](http://www.nytimes.com/1988/02/28/magazine/on-language-you-pays-yer-money.html?pagewanted=all)* + +[Greg Colvin](http://programmer.97things.oreilly.com/wiki/index.php/Greg_Colvin) Tarafından diff --git a/tr/thing_47/README.md b/tr/thing_47/README.md new file mode 100644 index 00000000..d8e58c18 --- /dev/null +++ b/tr/thing_47/README.md @@ -0,0 +1,19 @@ +# Bir Sonraki İşleminizi(Commit) Bilin + +Üç programcının omuzlarına dokundum ve ne yaptıklarını sordum. "Bu yöntemleri yeniden gözden geçiriyorum," diye yanıtladı ilki. İkincisi, "Bu web işlemine bazı parametreler ekliyorum" diye yanıtladı. Üçüncüsü, "Bu kullanıcı hikayesi üzerinde çalışıyorum" yanıtını verdi. + +İlk ikisi işlerinin ayrıntılarına dalmış gibi görünebilirken, yalnızca üçüncüsü büyük resmi görebiliyordu ve ikincisi daha iyi odaklanmıştı. Ancak, ne zaman ve ne işlemi yapacaklarını sorduğumda, resim çarpıcı bir şekilde değişti. İlk ikisi, hangi dosyaların dahil olacağı konusunda oldukça netti ve bir saat içinde bitecekti. Üçüncü programcı, "Ah, sanırım birkaç gün içinde hazır olacağım. Muhtemelen birkaç sınıf ekleyeceğim ve bu hizmetleri bir şekilde değiştirebilirim." + +İlk ikisi, genel hedefe yönelik bir vizyondan yoksun değildi. Verimli bir yöne gittiğini düşündükleri görevleri seçmişlerdi ve birkaç saat içinde bitirilebiliyorlardı. Bu görevleri bitirdikten sonra, üzerinde çalışmak için yeni bir özellik veya yeniden düzenleme seçeceklerdi. Böylece yazılan tüm kodlar net bir amaç ve sınırlı, ulaşılabilir bir hedef göz önünde bulundurularak yapıldı. + +Üçüncü programcı sorunu ayrıştırmayı başaramamıştı ve aynı anda tüm yönler üzerinde çalışıyordu. Temelde spekülatif programlama yaparak, işlem yapabileceği bir noktaya gelmeyi umarak, bunun ne gerektirdiği hakkında hiçbir fikri yoktu. Büyük olasılıkla bu uzun oturumun başında yazılan kod, sonunda ortaya çıkan çözüm için yetersizdi. + +İlk iki programcı, görevleri iki saatten fazla sürseydi ne yapardı? Çok fazla üstlendiklerini fark ettikten sonra, büyük olasılıkla değişiklikleri bir kenara atacak, daha küçük görevler tanımlayacak ve baştan başlayacaklardı. Çalışmaya devam etmek, odaktan yoksun olurdu ve depoya spekülatif kodun girmesine yol açardı. Bunun yerine, değişiklikler çöpe atılır, ancak içgörüler korunur. + +Üçüncü programcı tahmin etmeye devam edebilir ve umutsuzca değişikliklerini taahhüt edilebilecek bir şeye dönüştürmeye çalışabilir. Sonuçta, yaptığınız kod değişikliklerini çöpe atamazsınız - bu boşa giden bir iş olur, değil mi? Ne yazık ki, kodu çöpe atmamak, depoya girmek için net bir amacı olmayan biraz garip koda yol açar. + +Bir noktada, işlem odaklı programcılar bile iki saat içinde tamamlanabileceğini düşündükleri yararlı bir şey bulamayabilir. Ardından, doğrudan spekülatif moda geçerler, kodla oynarlar ve elbette, ne zaman bir içgörü onları tekrar rayına oturtsa değişiklikleri bir kenara atarlardı. Bu görünüşte yapılandırılmamış bilgisayar korsanlığı oturumlarının bile amacı vardır: verimli bir adım oluşturacak bir görevi tanımlayabilmek için kod hakkında bilgi edinmek. + +Bir sonraki işleminizi bilin. Bitiremezseniz, değişikliklerinizi atın ve kazandığınız içgörülerle inandığınız yeni bir görev tanımlayın. Gerektiğinde spekülatif deneyler yapın, ancak fark etmeden spekülatif moda kaymanıza izin vermeyin. Deponuza tahminde bulunmayın. + +[Dan Bergh Johnsson](http://programmer.97things.oreilly.com/wiki/index.php/Dan_Bergh_Johnsson) Tarafından \ No newline at end of file diff --git a/tr/thing_48/README.md b/tr/thing_48/README.md new file mode 100644 index 00000000..8a7ef9ac --- /dev/null +++ b/tr/thing_48/README.md @@ -0,0 +1,15 @@ +# Büyük Birbirine Bağlı Veriler Bir Veritabanına Aittir + +Uygulamanız büyük, kalıcı, birbirine bağlı bir veri öğeleri kümesini işleyecekse, onu ilişkisel bir veritabanında depolamaktan çekinmeyin. Geçmişte RDBMS'ler pahalı, kıt, karmaşık ve hantal hayvanlardı. Bu artık geçerli değil. Günümüzde RDBMS sistemlerini bulmak kolaydır - kullandığınız sistemde zaten bir veya iki tane kurulu olması muhtemeldir. MySQL ve PostgreSQL gibi bazı çok yetenekli RDBMS'ler açık kaynaklı yazılım olarak mevcuttur, bu nedenle satın alma maliyeti artık bir sorun değildir. Daha da iyisi, sözde gömülü veritabanı sistemleri, neredeyse hiçbir kurulum veya yönetim gerektirmeden doğrudan uygulamanıza kitaplıklar olarak bağlanabilir - iki dikkate değer açık kaynak, SQLite ve HSQLDB'dir. Bu sistemler son derece verimlidir. + +Uygulamanızın verileri sistemin RAM'inden daha büyükse, dizine alınmış bir RDBMS tablosu, sanal bellek sayfalarını bozacak olan kitaplığınızın harita toplama türünden çok daha hızlı işlem yapacaktır. Modern veritabanı teklifleri, ihtiyaçlarınızla kolayca büyüyebilir. Uygun bakımla, gerektiğinde gömülü bir veritabanını daha büyük bir veritabanı sistemine yükseltebilirsiniz. Daha sonra ücretsiz, açık kaynaklı bir tekliften daha iyi desteklenen veya daha güçlü bir tescilli sisteme geçebilirsiniz. + +SQL'e alıştıktan sonra, veritabanı merkezli uygulamalar yazmak bir zevktir. Veri tabanında düzgün bir şekilde normalize edilmiş verilerinizi depoladıktan sonra, okunabilir bir SQL sorgusu ile gerçekleri verimli bir şekilde çıkarmak kolaydır; herhangi bir karmaşık kod yazmaya gerek yoktur. Benzer şekilde, tek bir SQL komutu karmaşık veri değişiklikleri gerçekleştirebilir. Tek seferlik değişiklikler için, kalıcı verilerinizi düzenleme şeklinizde bir değişiklik olduğunu söyleyin, kod yazmanıza bile gerek yok: Veritabanının doğrudan SQL arayüzünü çalıştırmanız yeterli. Bu aynı arayüz aynı zamanda, normal bir programlama dilinin derleme-düzenleme döngüsünden kaçınarak sorgularla denemeler yapmanıza da olanak tanır. + +Kodunuzu bir RDBMS'ye dayandırmanın bir başka avantajı, veri öğeleriniz arasındaki ilişkilerin ele alınmasını içerir. Verilerinizi bir uç durumda güncellemeyi unutursanız, aldığınız işaretçilerin sarkan riskinden kaçınarak, verileriniz üzerindeki tutarlılık kısıtlamalarını bildirimsel bir şekilde tanımlayabilirsiniz. Örneğin, bir kullanıcı silinirse, o kullanıcı tarafından gönderilen mesajların da kaldırılması gerektiğini belirtebilirsiniz. + +Ayrıca, sadece bir dizin oluşturarak, istediğiniz zaman veritabanında depolanan varlıklar arasında verimli bağlantılar oluşturabilirsiniz. Sınıf alanlarının pahalı ve kapsamlı yeniden düzenlemelerini gerçekleştirmeye gerek yoktur. Ek olarak, bir veritabanı etrafında kodlama yapmak, birden çok uygulamanın verilerinize güvenli bir şekilde erişmesine olanak tanır. Bu, uygulamanızı eşzamanlı kullanım için yükseltmeyi ve ayrıca uygulamanızın her bir bölümünü en uygun dil ve platformu kullanarak kodlamayı kolaylaştırır. Örneğin, web tabanlı bir uygulamanın XML arka ucunu Java'da, bazı denetleme komut dosyalarını Ruby'de ve bir görselleştirme arayüzünü [İşleme](http://www.processing.org/)'de yazabilirsiniz. + +Son olarak, RDBMS'nin SQL komutlarınızı optimize etmek için çok terleyeceğini ve algoritmik ayar yerine uygulamanızın işlevselliğine konsantre olmanızı sağlayacağını unutmayın. Gelişmiş veritabanı sistemleri, arkanızdaki çok çekirdekli işlemcilerden bile faydalanacaktır. Ve teknoloji geliştikçe uygulamanızın performansı da artacaktır. + +[Diomidis Spinellis](http://programmer.97things.oreilly.com/wiki/index.php/Diomidis_Spinellis) Tarafından \ No newline at end of file diff --git a/tr/thing_49/README.md b/tr/thing_49/README.md new file mode 100644 index 00000000..edcd7db8 --- /dev/null +++ b/tr/thing_49/README.md @@ -0,0 +1,19 @@ +# Yabancı Diller Öğrenin + +Yazılımcıların iletişim kurması gerekir. Hem de çok fazla. + +Bir yazılımcının hayatında, çoğu iletişimin bilgisayarla gerçekleştiği dönemler vardır. Daha doğrusu, o bilgisayarda çalışan programlarla. Bu iletişim, fikirleri makine tarafından okunabilir bir şekilde ifade etmekle ilgilidir. Heyecan verici bir olasılık olmaya devam ediyor: Programlar, neredeyse hiçbir fiziksel madde içermeyen, gerçeğe dönüştürülmüş fikirlerdir. + +Yazılımcıların, gerçek veya sanal olsun, makinenin dilinde ve geliştirme araçları aracılığıyla o dille ilişkilendirilebilecek soyutlamalarda akıcı olması gerekir. Birçok farklı soyutlama öğrenmek önemlidir, aksi takdirde bazı fikirleri ifade etmek inanılmaz derecede zorlaşır. İyi yazılımcıların günlük rutinlerinin dışında durabilmeleri, başka amaçlar için anlamlı olan diğer dillerin farkında olmaları gerekir. Bunun karşılığını alacağı zaman her zaman gelir. + +Makinelerle iletişimin ötesinde, yazılımcıların akranlarıyla iletişim kurması gerekir. Günümüzün büyük projeleri, programlama sanatının basit bir uygulamasından daha çok sosyal çabalardır. Makine tarafından okunabilen soyutlamaların yapabileceğinden daha fazlasını anlamak ve ifade etmek önemlidir. Tanıdığım en iyi yazılımcıların çoğu, ana dillerinde ve tipik olarak diğer dillerde de çok akıcıdır. Bu sadece başkalarıyla iletişim kurmakla ilgili değildir: Bir dili iyi konuşmak aynı zamanda bir sorunu soyutlarken vazgeçilmez olan bir düşünce netliğine de yol açar. Ve programlama da bununla ilgilidir. + +Bir projenin makineyle, kendiyle ve akranlarla iletişimin ötesinde, çoğu farklı teknik geçmişi olan veya hiç olmayan birçok paydaşı vardır. Test, kalite ve dağıtımda, pazarlama ve satışta yaşarlar, bir ofiste (veya mağazada veya evde) son kullanıcılardır. Onları ve endişelerini anlamalısınız. Eğer onların dilini konuşamıyorsanız bu neredeyse imkansızdır. onların dünyasının dilini, onların etki alanını. Onlarla bir konuşmanın iyi gittiğini düşünebilirsiniz, ancak muhtemelen gitmezler. + +Muhasebecilerle konuşursanız, maliyet merkezi muhasebesi, bağlı sermaye, kullanılan sermaye vb. hakkında temel bilgilere ihtiyacınız vardır. Pazarlama veya avukatlarla konuşursanız, onların bazı jargonları ve dilleri (ve dolayısıyla zihinleri) size aşina olmalıdır. Tüm bu alana özgü dillerin projedeki biri tarafından ideal olarak yazılımcılar tarafından öğrenilmesi gerekir. Yazılımcılar, fikirleri bir bilgisayar aracılığıyla hayata geçirmekten nihai olarak sorumludur. + +Ve elbette hayat, yazılım projelerinden daha fazlasıdır. [Charlemagne](http://en.wikipedia.org/wiki/Charlemagne) tarafından belirtildiği gibi, başka bir dil bilmek, başka bir ruha sahip olmaktır. Yazılım endüstrisinin ötesindeki bağlantılarınız için yabancı dil bilmekten memnun kalacaksınız. Konuşmak yerine ne zaman dinleyeceğini bilmek. Çoğu dilin kelimeler olmadan olduğunu bilmek. + +> *Hakkında konuşulamayan şey, hakkında susmak gerekir.* - Ludwig Wittgenstein + +[Klaus Marquardt](http://programmer.97things.oreilly.com/wiki/index.php/Klaus_Marquardt) Tarafından \ No newline at end of file diff --git a/tr/thing_50/README.md b/tr/thing_50/README.md new file mode 100644 index 00000000..036d7101 --- /dev/null +++ b/tr/thing_50/README.md @@ -0,0 +1,31 @@ +# Tahmin Etmeyi Öğrenin + +Bir yazılımcı olarak yöneticilerinize, meslektaşlarınıza ve kullanıcılarınıza gerçekleştirmeniz gereken görevler için tahminler sunabilmeniz gerekir, böylece onlar hedefleri başarmak için gereken zaman, maliyetler, teknoloji ve diğer kaynaklar hakkında makul derecede doğru bir fikre sahip olurlar. + +İyi tahmin yapabilmek için bazı tahmin tekniklerini öğrenmek elbette önemlidir. Bununla birlikte, her şeyden önce, tahminlerin ne olduğunu ve ne için kullanılmaları gerektiğini öğrenmek esastır. Ne kadar garip görünse de, birçok geliştirici ve yönetici bunu gerçekten bilmiyor. + +Bir proje yöneticisi ve bir yazılımcı arasındaki aşağıdaki alışveriş alışılmışın dışında değildir: + +> *Proje Yöneticisi:* *xyz* özelliğini geliştirmek için gereken süreyi tahmin edebilir misin? + +> *Yazılımcı:* Bir ay. + +> *Proje Yöneticisi:* Bu çok uzun! Sadece bir haftamız var. + +> *Yazılımcı:* En az üç haftaya ihtiyacım var. + +> *Proje Yöneticisi:* Sana en fazla iki hafta verebilirim. + +> *Yazılımcı:* Anlaştık! + +Yazılımcı, sonunda yönetici için kabul edilebilir olanla eşleşen bir "tahmin" ile gelir. Ancak yazılımcının tahmini olduğu görüldüğünden, yönetici yazılımcıyı buna karşı sorumlu tutacaktır. Bu konuşmada neyin yanlış olduğunu anlamak için üç tanıma ihtiyacımız var - tahmin, hedef ve taahhüt: + +- Bir *tahmin*, bir şeyin değeri, sayısı, miktarı veya kapsamına ilişkin yaklaşık bir hesaplama veya yargıdır. Bu tanım, bir tahminin somut verilere ve önceki deneyimlere dayanan olgusal bir ölçü olduğunu ima eder - hesaplanırken umutlar ve istekler göz ardı edilmelidir. Tanım ayrıca, yaklaşık olarak bir tahminin kesin olamayacağını, örneğin bir geliştirme görevinin 234,14 gün süreceğini tahmin edemeyeceğini ima eder. +- *hedef*, arzu edilen bir iş hedefinin ifadesidir, örneğin, "Sistem en az 400 eşzamanlı kullanıcıyı desteklemelidir." +- *taahhüt*, belirli bir tarihe veya olaya kadar belirli bir kalitede belirli bir işlevsellik sağlama taahhüdüdür. Bir örnek, "Arama işlevi, ürünün sonraki sürümünde kullanıma sunulacaktır" olabilir. + +Tahminler, hedefler ve taahhütler birbirinden bağımsızdır, ancak hedefler ve taahhütler sağlam tahminlere dayanmalıdır. Steve McConnell'in belirttiği gibi, "Yazılım tahmininin birincil amacı, bir projenin sonucunu tahmin etmek değil; bir projenin hedeflerinin, projenin bunları karşılamak için kontrol edilmesine izin verecek kadar gerçekçi olup olmadığını belirlemektir." Bu nedenle, tahminin amacı, proje paydaşlarının gerçekçi hedeflere dayalı taahhütlerde bulunmalarına izin vererek uygun proje yönetimi ve planlamasını mümkün kılmaktır. + +Yukarıdaki konuşmada yöneticinin yazılımcıdan gerçekten istediği şey, bir tahminde bulunmak değil, yöneticinin aklındaki belirtilmemiş bir hedefe dayalı bir taahhütte bulunmasıydı. Bir dahaki sefere bir tahmin sağlamanız istendiğinde, katılan herkesin ne hakkında konuştuğunu bildiğinden emin olun ve projelerinizin başarılı olma şansı daha yüksek olacaktır. Şimdi bazı teknikleri öğrenmenin zamanı geldi.... + +[Giovanni Asproni](http://programmer.97things.oreilly.com/wiki/index.php/Giovanni_Asproni) Tarafından \ No newline at end of file diff --git a/tr/thing_51/README.md b/tr/thing_51/README.md new file mode 100644 index 00000000..d000d7bc --- /dev/null +++ b/tr/thing_51/README.md @@ -0,0 +1,39 @@ +# "Merhaba Dünya" Demeyi Öğrenin + +Daha yaygın olarak Hoppy olarak bilinen kullanıcı adı leep olan Paul Lee, programlama konularında yerel uzman olarak ün yapmıştır. Yardıma ihtiyacım vardı. Hoppy'nin masasına doğru yürüdüm ve benim için bir koda bakabilir mi? diye sordum. + +Tabii, dedi Hoppy, bir sandalye çek. Arkasında piramit şeklinde yığılmış boş kola kutularını devirmemeye özen gösterdim. + +Ne kodu? + +Bir dosyadaki bir fonksiyonda, dedim. + +Öyleyse bu fonksiyona bir göz atalım. Hoppy K&R'ın bir kopyasını kenara çekti ve klavyesini önüme kaydırdı. + +IDE nerede? Görünüşe göre Hoppy'nin çalışan IDE'si yoktu, sadece çalıştıramadığım bir editör. Klavyeyi geri aldı. Birkaç tuşa bastıktan sonra dosyayı açtık, oldukça büyük bir dosyaydı ve işleve bakıyorduk, oldukça büyük bir işlevdi. Sormak istediğim koşullu bloğa çağrı yaptı. + +'x' negatifse bu cümle gerçekte ne yapar? diye sordum. Elbette yanlış. + +Bütün sabah "x"i negatif olmaya zorlamanın bir yolunu bulmaya çalışıyordum, ancak büyük dosyadaki büyük işlev büyük bir projenin parçasıydı ve deneylerimi yeniden derleme *sonra* yeniden çalıştırma döngüsü beni yıpratıyordu. Hoppy gibi bir uzman bana cevabı söyleyemez mi? + +Hoppy emin olmadığını itiraf etti. Sürprizime göre, K&R'ye ulaşmadı. Bunun yerine, kod bloğunu yeni bir düzenleyici arabelleğine kopyaladı, yeniden girinti yaptı, bir işleve sardı. Kısa bir süre sonra, sonsuza kadar döngüye giren, kullanıcıdan giriş değerlerini isteyen, bunları işleve ileten ve sonucu yazdıran bir ana işlevi kodlamıştı. Tamponu yeni bir dosya olarak, tryit.c olarak kaydetti. Bütün bunları kendim için yapabilirdim, belki de o kadar çabuk olmasa da. Ancak bir sonraki adımı son derece basitti ve o zamanlar benim çalışma şeklime oldukça yabancıydı: + +``` +$ cc tryit.c && ./a.out +``` + +Bakmak! Sadece birkaç dakika önce tasarlanan asıl programı şimdi çalışır durumdaydı. Birkaç değer denedik ve şüphelerimi doğruladık (yani bir konuda haklıydım!) ve ardından K&R'nin ilgili bölümünü kontrol etti. Hoppy'ye teşekkür ettim ve yine kola piramidini bozmamaya özen göstererek ayrıldım. + +Kendi masama döndüğümde IDE'mi kapattım. Büyük bir ürün içinde büyük bir proje üzerinde çalışmaya o kadar alışmıştım ki, yapmam gerekenin bu olduğunu düşünmeye başlamıştım. Genel amaçlı bir bilgisayar da küçük işler yapabilir. Bir metin düzenleyici açtım ve yazmaya başladım. + +``` +#include + +int main() +{ + printf("Hello, World\n"); + return 0; +} +``` + +[Thomas Guest](http://programmer.97things.oreilly.com/wiki/index.php/Thomas_Guest) Tarafından \ No newline at end of file diff --git a/tr/thing_52/README.md b/tr/thing_52/README.md new file mode 100644 index 00000000..933e9acf --- /dev/null +++ b/tr/thing_52/README.md @@ -0,0 +1,17 @@ +# Bırakın Projeniz Kendi Adına Konuşsun + +Projenizde muhtemelen bir sürüm kontrol sistemi vardır. Belki de otomatik testlerle doğruluğunu doğrulayan sürekli bir entegrasyon sunucusuna bağlıdır. Bu harika. + +Kod ölçümlerini toplamak için sürekli tümleştirme sunucunuza statik kod analizi araçları dahil edebilirsiniz. Bu metrikler, kodunuzun belirli yönleri ve bunların zaman içindeki gelişimi hakkında geri bildirim sağlar. Kod metriklerini yüklediğinizde, her zaman geçmek istemediğiniz kırmızı bir çizgi olacaktır. %20 test kapsamıyla başladığınızı ve asla %15'in altına düşmek istemediğinizi varsayalım. Sürekli entegrasyon, tüm bu sayıları takip etmenize yardımcı olur, ancak yine de düzenli olarak kontrol etmeniz gerekir. Bu görevi projenin kendisine devredebileceğinizi ve işler daha da kötüye gittiğinde rapor vermek için ona güvenebileceğinizi hayal edin. + +Projenize ses vermelisiniz. Bu, e-posta veya anlık mesajlaşma yoluyla yapılabilir ve geliştiricilere sayılardaki en son düşüş veya iyileşme hakkında bilgi verilir. Ancak projeyi ofisinizde bir aşırı geri bildirim cihazı (XFD - extreme feedback device) kullanarak somutlaştırmak daha da etkilidir. + +XFD'lerin fikri, otomatik analiz sonuçlarına dayalı olarak bir lamba, taşınabilir bir çeşme, bir oyuncak robot ve hatta bir USB roketatar gibi fiziksel bir cihazı sürmektir. Limitleriniz aşıldığında, cihaz durumunu değiştirir. Bir lamba olması durumunda, yanacak, parlak ve belirgin olacaktır. Eve gitmek için kapıdan aceleyle çıksanız bile mesajı kaçıramazsınız. + +Aşırı geri bildirim cihazının türüne bağlı olarak, yapı kesintisini duyabilir, kodunuzdaki kırmızı uyarı sinyallerini görebilir ve hatta kodunuzun kokusunu bile alabilirsiniz. Dağıtılmış bir ekip üzerinde çalışıyorsanız, cihazlar farklı konumlarda çoğaltılabilir. Proje yöneticinizin ofisine, genel proje sağlık durumunu gösteren bir trafik ışığı yerleştirebilirsiniz. Proje yöneticiniz bunu takdir edecektir. + +Uygun bir cihaz seçerken yaratıcılığınızın size rehberlik etmesine izin verin. Kültürünüz biraz geekse, takım maskotunuzu radyo kontrollü oyuncaklarla donatmanın yollarını arayabilirsiniz. Daha profesyonel bir görünüm istiyorsanız, şık tasarımlı lambalara yatırım yapın. Daha fazla ilham almak için İnternet'te arama yapın. Elektrik fişi veya uzaktan kumandası olan her şey, aşırı geri bildirim cihazı olarak kullanılma potansiyeline sahiptir. + +Aşırı geri bildirim cihazı, projenizin ses kutusu görevi görür. Proje şimdi fiziksel olarak geliştiricilerle birlikte, ekibin seçtiği kurallara göre onları şikayet ediyor veya övüyor. Konuşma sentez yazılımı ve bir çift hoparlör uygulayarak bu kişileştirmeyi daha da ileri götürebilirsiniz. Şimdi projeniz gerçekten kendisi için konuşuyor. + +[Daniel Lindner](http://programmer.97things.oreilly.com/wiki/index.php/Daniel_Lindner) Tarafından \ No newline at end of file diff --git a/tr/thing_53/README.md b/tr/thing_53/README.md new file mode 100644 index 00000000..d14f0c68 --- /dev/null +++ b/tr/thing_53/README.md @@ -0,0 +1,52 @@ +# Bağlayıcı Sihirli Bir Program Değildir + +Sık sık (bunu yazmadan hemen önce başıma geldi), birçok programcının kaynak koddan derlenmiş bir dilde statik olarak bağlantılı bir yürütülebilir dosyaya geçme süreciyle ilgili görüşü şudur: + +1. Kaynak kodunu düzenleyin +2. Kaynak kodunu nesne dosyalarına derleyin +3. Sihirli bir şey olur +4. Yürütülebilir dosyayı çalıştırın + +Adım 3, elbette, bağlama adımıdır. Neden böyle çirkin bir şey söyleyeyim ki? Onlarca yıldır teknik destek yapıyorum ve aşağıdaki soruları tekrar tekrar alıyorum: + +- Bağlayıcı, def'in birden fazla kez tanımlandığını söylüyor. +- Bağlayıcı, abc'nin çözülmemiş bir sembol olduğunu söylüyor. +- Yürütülebilir dosyam neden bu kadar büyük? + +Ardından "Şimdi ne yapacağım?" genellikle "görünüyor" ve "bir şekilde" ifadeleri birbirine karışmış ve tam bir şaşkınlık havası ile. Bağlama sürecinin büyülü bir süreç olarak görüldüğünü gösteren "görünüyor" ve "bir şekilde", muhtemelen yalnızca sihirbazlar ve büyücüler tarafından anlaşılabilir. Derleme süreci bu tür ifadeleri ortaya çıkarmaz, bu da programcıların genellikle derleyicilerin nasıl çalıştığını veya en azından ne yaptıklarını anladığını ima eder. + +Bir bağlayıcı çok aptal, yaya, basit bir programdır. Tek yaptığı, nesne dosyalarının kod ve veri bölümlerini bir araya getirmek, sembollere referansları tanımlarıyla bağlamak, çözülmemiş sembolleri kitaplıktan çıkarmak ve bir yürütülebilir dosya yazmaktır. Bu kadar. Büyü yok! Sihir yok! Bir bağlayıcı yazmanın sıkıcılığı genellikle tamamen gülünç derecede karmaşık dosya biçimlerinin kodunu çözmek ve oluşturmakla ilgilidir, ancak bu bir bağlayıcının temel yapısını değiştirmez. + +Diyelim ki bağlayıcı, def'in bir kereden fazla tanımlandığını söylüyor. C, C++ ve D gibi birçok programlama dilinin hem bildirimleri hem de tanımları vardır. Bildirimler normalde aşağıdaki gibi başlık dosyalarına girer: + +``` +extern int iii; +``` + +bu da `iii` sembolüne harici bir referans oluşturur. Öte yandan, bir tanım aslında sembol için depolamayı bir kenara bırakır, genellikle uygulama dosyasında görünür ve şöyle görünür: + +``` +int iii = 3; +``` + +Her bir sembol için kaç tanım olabilir? *Highlander* filminde olduğu gibi, sadece bir tane olabilir. Peki ya birden fazla uygulama dosyasında bir iii tanımı görünüyorsa? + +``` +// File a.c +int iii = 3; +``` + +``` +// File b.c +double iii(int x) { return 3.7; } +``` + +Bağlayıcı, `iii`ün birden çok tanımlı olduğundan şikayet edecektir. + +Sadece bir tane olamaz, bir tane olmalı. iii yalnızca bir bildirim olarak görünüyorsa, ancak asla bir tanım değilse, bağlayıcı, iii'ün çözülmemiş bir sembol olduğundan şikayet edecektir. + +Bir yürütülebilir dosyanın neden bu boyutta olduğunu belirlemek için, bağlayıcıların isteğe bağlı olarak oluşturduğu harita dosyasına bakın. Bir harita dosyası, yürütülebilir dosyadaki tüm sembollerin adresleriyle birlikte bir listesinden başka bir şey değildir. Bu size kitaplıktan hangi modüllerin bağlandığını ve her modülün boyutunu söyler. Artık şişkinliğin nereden geldiğini görebilirsiniz. Genellikle, neden bağlantılı oldukları hakkında hiçbir fikriniz olmayan kitaplık modülleri olacaktır. Bunu anlamak için, şüpheli modülü kitaplıktan geçici olarak kaldırın ve yeniden bağlayın. Daha sonra oluşturulan tanımsız sembol hatası, o modüle kimin başvurduğunu gösterecektir. + +Belirli bir bağlayıcı mesajını neden aldığınız her zaman hemen açık olmasa da, bağlayıcılarla ilgili sihirli bir şey yoktur. Mekanikler basittir; her durumda çözmeniz gereken ayrıntılardır. + +[Walter Bright](http://creativecommons.org/licenses/by/3.0/us/) Tarafından \ No newline at end of file diff --git a/tr/thing_54/README.md b/tr/thing_54/README.md new file mode 100644 index 00000000..9ff7ce12 --- /dev/null +++ b/tr/thing_54/README.md @@ -0,0 +1,33 @@ +# Geçici Çözümlerin Uzun Ömrü + +Neden geçici çözümler üretiyoruz? + +Tipik olarak, çözülmesi gereken acil bir sorun vardır. Takım zincirindeki bir boşluğu dolduran bazı takımlar, geliştirme ekibinin içinde olabilir. Eksik işlevleri gideren bir geçici çözüm gibi harici olabilir, son kullanıcılar tarafından görülebilir. + +Çoğu sistemde ve ekipte, sistemden bir şekilde ayrılmış, bazen değiştirilecek bir taslak olarak kabul edilen, kodun geri kalanını şekillendiren standartları ve yönergeleri takip etmeyen bazı yazılımlar bulacaksınız. Kaçınılmaz olarak geliştiricilerin bunlardan şikayet ettiğini duyacaksınız. Oluşturulmalarının nedenleri çok ve çeşitlidir, ancak geçici bir çözümün başarısının anahtarı basittir: Yararlıdır. + +Bununla birlikte, ara çözümler atalet (veya bakış açınıza bağlı olarak momentum) kazanır. Orada olduklarından, nihayetinde yararlı olduklarından ve geniş çapta kabul edildiğinden, başka bir şey yapmaya hemen gerek yoktur. Bir paydaş hangi eylemin en fazla değeri katacağına karar vermek zorunda kaldığında, bir ara çözümün uygun entegrasyonundan daha yüksek sıralarda yer alan pek çok kişi olacaktır. Niye? Çünkü oradadır, çalışır ve kabul edilir. Algılanan tek dezavantajı, seçilen standartları ve yönergeleri takip etmemesidir, birkaç niş pazar dışında, bu önemli bir güç olarak kabul edilmez. + +Böylece geçici çözüm yerinde kalır. Sonsuza kadar. + +Ve bu geçici çözümle ilgili sorunlar ortaya çıkarsa, onu kabul edilen üretim kalitesiyle uyumlu hale getirecek bir güncelleme sağlanması olası değildir. Ne yapalım? Bu geçici çözümde hızlı bir geçici güncelleme genellikle işi yapar. Ve büyük olasılıkla iyi karşılanacaktır. İlk ara çözümle aynı güçlü yönleri sergiliyor... sadece daha güncel. + +Bu bir sorun mu? + +Cevap, projenize ve üretim kodu standartlarındaki kişisel payınıza bağlıdır. Sistemler çok fazla ara çözüm içerdiğinde, entropisi veya dahili karmaşıklığı artar ve sürdürülebilirliği azalır. Ancak, bu muhtemelen ilk önce sorulacak yanlış sorudur. Bir çözümden bahsettiğimizi unutmayın. Tercih ettiğiniz çözüm olmayabilir, herhangi birinin tercih ettiği bir çözüm olmayabilir, ancak bu çözümü yeniden işleme motivasyonu zayıftır. + +Peki bir sorun görürsek ne yapabiliriz? + +1. Her şeyden önce geçici bir çözüm yaratmaktan kaçının. +2. Proje yöneticisinin kararını etkileyen güçleri değiştirin. +3. Olduğu gibi bırakın. + +Bu seçenekleri daha yakından inceleyelim: + +1. Kaçınma çoğu yerde işe yaramaz. Çözülmesi gereken gerçek bir sorun var ve standartların çok kısıtlayıcı olduğu ortaya çıktı. Standartları değiştirmek için biraz enerji harcayabilirsiniz. Onurlu olsa da sıkıcı bir çaba... ve bu değişiklik, elinizdeki problem için zamanında etkili olmayacak. +2. Güçler, gönüllü değişime direnen proje kültüründe kök salmıştır. Çok küçük projelerde başarılı olabilir, özellikle de sadece sizseniz ve önceden sormadan pisliği temizleyebilirsiniz. Proje, gözle görülür bir şekilde durdurulacak ve temizlik için biraz zaman tanınacak kadar dağınıksa da başarılı olabilir. +3. Önceki seçenek geçerli değilse, statüko otomatik olarak uygulanır. + +Birçok çözüm üreteceksiniz, bazıları geçici olacak, çoğu faydalı olacak. Ara çözümleri aşmanın en iyi yolu onları gereksiz kılmak, daha şık ve kullanışlı bir çözüm sunmaktır. Değiştiremeyeceğiniz şeyleri kabul etmek için [huzur](http://en.wikipedia.org/wiki/Serenity_prayer), değiştirebileceğiniz şeyleri değiştirmek için cesaret ve aradaki farkı bilmek için bilgelik bahşedilsin. + +[Klaus Marquardt](http://programmer.97things.oreilly.com/wiki/index.php/Klaus_Marquardt) Tarafından diff --git a/tr/thing_55/README.md b/tr/thing_55/README.md new file mode 100644 index 00000000..9446c823 --- /dev/null +++ b/tr/thing_55/README.md @@ -0,0 +1,16 @@ +# Arayüzlerin Doğru Kullanımını Kolay ve Yanlış Kullanımını Zorlaştırın + +Yazılım geliştirmede en yaygın görevlerden biri arayüz belirtimidir. Arayüzler en yüksek soyutlama seviyesinde (kullanıcı arayüzleri), en düşük seviyede (fonksiyon arayüzleri) ve aradaki seviyelerde (sınıf arayüzleri, kütüphane arayüzleri vb.) oluşur. Bir sistemle nasıl etkileşime gireceklerini belirlemek için son kullanıcılarla birlikte çalışın, bir API belirtmek için geliştiricilerle işbirliği yapın veya bir sınıfa özel işlevler bildirin, arayüz tasarımı işinizin önemli bir parçasıdır. Bunu iyi yaparsanız, arayüzlerinizi kullanmak bir zevk olacak ve başkalarının üretkenliğini artıracaktır. Kötü yaparsanız, arayüzleriniz bir hayal kırıklığı ve hata kaynağı olacaktır. + +İyi arayüzler şunlardır: + +- **Doğru kullanımı kolay.** İyi tasarlanmış bir arayüz kullanan kişiler, hemen hemen her zaman arayüzü doğru kullanır, çünkü bu en az dirençli yoldur. Bir GUI'de, hemen hemen her zaman doğru simgeye, düğmeye veya menü girişine tıklarlar, çünkü bu yapılması açık ve kolay olan şeydir. Bir API'de, neredeyse her zaman doğru parametreleri doğru değerlerle iletirler, çünkü en doğal olan budur. Doğru kullanımı kolay arayüzler sayesinde *işler yoluna girer.* +- **Yanlış kullanımı zor.** İyi arayüzler, insanların yapabileceği hataları tahmin eder ve bunları gerçekleştirmeyi zor, ideal olarak imkansız hale getirir. Bir GUI, örneğin mevcut bağlamda hiçbir anlam ifade etmeyen komutları devre dışı bırakabilir veya kaldırabilir veya bir API, parametrelerin herhangi bir sırayla iletilmesine izin vererek argüman sıralama sorunlarını ortadan kaldırabilir. + +Doğru kullanımı kolay arayüzler tasarlamanın iyi bir yolu, onları var olmadan önce kullanmaktır. Bir GUI'yi (muhtemelen bir beyaz tahta üzerinde veya bir masadaki dizin kartlarını kullanarak) oluşturun ve herhangi bir temel kod oluşturulmadan önce onunla oynayın. İşlevler bildirilmeden önce çağrıları bir API'ye yazın. Genel kullanım durumlarını gözden geçirin ve arayüzün nasıl davranmasını *istediğinizi* belirtin. Neye tıklayabilmek *istemek* istiyorsunuz? Neyi geçebilmek *istiyorsun*? Kullanımı kolay arayüzler doğal görünüyor çünkü yapmak istediğinizi yapmanıza izin veriyorlar. Bunları bir kullanıcının bakış açısından geliştirirseniz, bu tür arayüzleri bulmanız daha olasıdır. (Bu bakış açısı, önce test programlamanın güçlü yönlerinden biridir.) + +Arayüzlerin yanlış kullanımını zorlaştırmak iki şeyi gerektirir. İlk olarak, kullanıcıların yapabileceği hataları tahmin etmeli ve bunları önlemenin yollarını bulmalısınız. İkinci olarak, erken sürüm sırasında bir arayüzün nasıl kötüye kullanıldığını gözlemlemeli ve arayüzü değiştirmelisiniz. Evet, arayüzü değiştirin! Bu tür hataları önlemek için. Yanlış kullanımı önlemenin en iyi yolu, bu tür bir kullanımı imkansız kılmaktır. Kullanıcılar geri alınamaz bir eylemi geri almak istemeye devam ederse, eylemi geri alınabilir hale getirmeye çalışın. Bir API'ye yanlış değeri aktarmaya devam ederlerse, API'yi, kullanıcıların geçmek istediği değerleri alacak şekilde değiştirmek için elinizden gelenin en iyisini yapın. + +Her şeyden önce, arayüzlerin uygulayıcılarının değil, kullanıcılarının rahatlığı için var olduğunu unutmayın. + +[Scott Meyers](http://programmer.97things.oreilly.com/wiki/index.php/Scott_Meyers) Tarafından \ No newline at end of file diff --git a/tr/thing_56/README.md b/tr/thing_56/README.md new file mode 100644 index 00000000..dd06e891 --- /dev/null +++ b/tr/thing_56/README.md @@ -0,0 +1,19 @@ +# Görünmezi Daha Görünür Hale Getirin + +Görünmezliğin birçok yönü, desteklenmesi gereken yazılım ilkeleri olarak haklı olarak övülür. Terminolojimiz, görünmezlik metaforları bakımından zengindir. Mekanizma şeffaflığı ve bilgi gizleme, bunlardan ikisi. Douglas Adams'ın deyişiyle, yazılım ve onu geliştirme süreci *çoğunlukla görünmez* olabilir: + +- Kaynak kodun doğuştan gelen bir varlığı, doğuştan gelen bir davranışı yoktur ve fizik yasalarına uymaz. Bir düzenleyiciye yüklediğinizde görünür, ancak düzenleyiciyi kapattığınızda kaybolur. Bunu çok uzun süre düşünün ve kimsenin duymadığı bir ağacın devrilmesi gibi, gerçekten var mı diye merak etmeye başlıyorsunuz. +- Çalışan bir uygulamanın varlığı ve davranışı vardır, ancak oluşturulduğu kaynak koddan hiçbir şey göstermez. Google'ın ana sayfası hoş bir şekilde minimaldir; arkasında olup bitenler kesinlikle önemli. +- %90'ını bitirdiysen ve son %10'da hata ayıklamaya çalışırken durmadan takılıp kaldıysan, %90'ını bitirmedin, değil mi? Hataları düzeltmek ilerleme kaydetmiyor. Hata ayıklamak için size ödeme yapılmaz. Hata ayıklama israftır. Atığı daha görünür kılmak iyidir, böylece ne olduğunu görebilir ve ilk etapta onu yaratmamaya çalışmayı düşünmeye başlayabilirsiniz. +- Eğer projeniz yolunda gidiyorsa ve bir hafta sonra altı ay geciktiyse sorunlarınız var, bunların en büyüğü muhtemelen altı ay gecikmiş olması değil, ancak görünmezlik güç alanları altı aylık gecikmeyi gizleyecek kadar güçlü! Görünür ilerleme eksikliği, ilerleme eksikliği ile eş anlamlıdır. + +Görünmezlik tehlikeli olabilir. Düşüncelerinizi bağlayacak somut bir şeyiniz olduğunda daha net düşünürsünüz. Onları gördüğünüzde ve sürekli değiştiğini gördüğünüzde işleri daha iyi yönetirsiniz: + +- Birim testleri yazmak, kod biriminin birim testi için ne kadar kolay olduğuna dair kanıt sağlar. Kodun sergilemesini istediğiniz gelişimsel niteliklerin varlığını (veya yokluğunu) ortaya çıkarmaya yardımcı olur; düşük bağlantı ve yüksek kohezyon gibi nitelikler. +- Çalışan birim testleri, kodun davranışı hakkında kanıt sağlar. Uygulamanın sergilemesini istediğiniz niteliklerin çalışma zamanının varlığını (veya yokluğunu) ortaya çıkarmaya yardımcı olur; sağlamlık ve doğruluk gibi nitelikler. +- Bülten tahtaları ve kartları kullanmak ilerlemeyi görünür ve somut hale getirir. Görevler, gizli bir proje yönetim aracına başvurmadan ve kurgusal durum raporları için programcıları kovalamak zorunda kalmadan *Başlamadı*, *Devam Ediyor* veya *Bitti* olarak görülebilir. +- Kademeli geliştirme yapmak, geliştirme kanıtlarının sıklığını artırarak geliştirme ilerlemesinin (veya eksikliğinin) görünürlüğünü artırır. Serbest bırakılabilir yazılımın tamamlanması gerçeği ortaya çıkarır; tahminler öyle değil. + +Bol miktarda düzenli görünür kanıt içeren bir yazılım geliştirmek en iyisidir. Görünürlük, ilerlemenin gerçek olduğuna ve bir yanılsama olmadığına, kasıtlı ve kasıtsız olmadığına, tekrarlanabilir olduğuna ve tesadüfi olmadığına dair güven verir. + +[Jon Jagger](http://programmer.97things.oreilly.com/wiki/index.php/Jon_Jagger) Tarafından \ No newline at end of file diff --git a/tr/thing_57/README.md b/tr/thing_57/README.md new file mode 100644 index 00000000..8176d8dd --- /dev/null +++ b/tr/thing_57/README.md @@ -0,0 +1,19 @@ +# Mesaj Geçişi, Paralel Sistemlerde Daha İyi Ölçeklenebilirlik Sağlar + +Yazılımcılara, hesaplama çalışmalarının en başından itibaren, eşzamanlılığın ve özellikle eşzamanlılığın özel bir alt kümesi olan paralelliğin zor olduğu, yalnızca en iyilerin onu doğru yapmayı umabileceği ve hatta yanlış anlayabileceği öğretilir. İplikler, semaforlar, monitörler ve iş parçacığı açısından güvenli olmak için değişkenlere eşzamanlı erişim sağlamanın ne kadar zor olduğu konusunda her zaman büyük bir odak vardır. + +Doğru, birçok zor problem var ve çözülmesi çok zor olabilir. Ama sorunun kökü nedir? Paylaşılan hafıza. İnsanların üzerinde durup durduğu hemen hemen tüm eşzamanlılık sorunları, paylaşılan değişebilir belleğin kullanımıyla ilgilidir: yarış koşulları, kilitlenme, canlı kilit, vb. Cevap açık görünüyor: Ya eşzamanlılıktan vazgeç ya da paylaşılan bellekten kaçın! + +Devam eden eşzamanlılık neredeyse kesinlikle bir seçenek değildir. Bilgisayarlar neredeyse üç ayda bir giderek daha fazla çekirdeğe sahip olduğundan, gerçek paralellikten yararlanmak giderek daha önemli hale geliyor. Uygulama performansını iyileştirmek için artık artan işlemci saat hızlarına güvenemeyiz. Yalnızca paralellikten yararlanarak uygulamaların performansı iyileşir. Açıkçası, performansı iyileştirmemek bir seçenektir, ancak kullanıcılar tarafından kabul edilmesi pek olası değildir. + +Öyleyse paylaşılan hafızadan kaçınabilir miyiz? Kesinlikle. + +Programlama modelimiz olarak iş parçacıklarını ve paylaşılan belleği kullanmak yerine, süreçleri ve mesaj geçişini kullanabiliriz. Buradaki işlem, mutlaka bir işletim sistemi işlemi değil, yalnızca yürütme koduyla korunan bağımsız bir durum anlamına gelir. Erlang (ve ondan önceki occam) gibi diller, süreçlerin eşzamanlı ve paralel sistemleri programlamak için çok başarılı bir mekanizma olduğunu göstermiştir. Bu tür sistemler, paylaşılan bellek, çok iş parçacıklı sistemlerin sahip olduğu tüm senkronizasyon streslerine sahip değildir. Ayrıca, bu tür sistemlerin mühendisliğinin bir parçası olarak uygulanabilecek resmi bir model Haberleşme Sıralı Süreçler (CSP - Communicating Sequential Processes) vardır. + +Daha ileri gidebilir ve bir bilgi işlem yolu olarak veri akışı sistemlerini tanıtabiliriz. Bir veri akışı sisteminde, açıkça programlanmış bir kontrol akışı yoktur. Bunun yerine, veri yolları ile bağlanan operatörlerin yönlendirilmiş bir grafiği kurulur ve ardından sisteme veri beslenir. Değerlendirme, sistem içindeki verilerin hazır olup olmadığı ile kontrol edilir. Senkronizasyon sorunu kesinlikle yoktur. + +Tüm bunları söyledikten sonra, C, C++, Java, Python ve Groovy gibi diller sistem geliştirmenin başlıca dilleridir ve bunların hepsi programcılara paylaşımlı bellek, çok kanallı sistemler geliştirme dilleri olarak sunulur. Peki ne yapılabilir? Cevap, paylaşılan değiştirilebilir belleğin tüm kullanımından kaçınarak süreç modelleri ve mesaj geçişi sağlayan kitaplıklar ve çerçeveler kullanmak veya yoksa, oluşturmaktır. + +Sonuç olarak, paylaşılan bellekle programlama değil, bunun yerine mesaj iletimini kullanmak, bilgisayar donanımında yaygın olan paralellikten yararlanan sistemleri uygulamanın en başarılı yolu olabilir. Tuhaf bir şekilde, süreçler bir eşzamanlılık birimi olarak iş parçacıklarından önce gelse de, gelecek süreçleri uygulamak için iş parçacıklarını kullanmak gibi görünüyor. + +[Russel Winder](http://programmer.97things.oreilly.com/wiki/index.php/Russel_Winder) Tarafından \ No newline at end of file diff --git a/tr/thing_58/README.md b/tr/thing_58/README.md new file mode 100644 index 00000000..8688d452 --- /dev/null +++ b/tr/thing_58/README.md @@ -0,0 +1,23 @@ +# Geleceğe Mesaj + +Belki de çoğu zeki insanlar olduğu içindir, ancak programcılarla yan yana ders verdiğim ve çalıştığım tüm yıllar boyunca, görünüşe göre çoğu, mücadele ettikleri problemler zor olduğu için çözümlerin olması gerektiğini düşündüler, herkesin (kod yazıldıktan birkaç ay sonra bile) anlaması ve sürdürmesi aynı derecede zor olabilir. + +Veri yapıları sınıfımdaki bir öğrenci olan ve bana ne yazdığını göstermek için içeri girmek zorunda kalan Joe ile ilgili bir olayı hatırlıyorum. "Betcha ne yaptığını tahmin edemez!" diye öttü. + +"Haklısın," diye kabul ettim örneğine çok fazla zaman harcamadan ve önemli bir mesajı nasıl ileteceğimi merak etmeden. "Eminim bunun üzerinde çok çalışıyorsun. Acaba önemli bir şeyi unutmadıysan merak ediyorum. Söylesene Joe, senin küçük bir erkek kardeşin yok mu?" + +"Evet. Elbette! Phil! O sizin Giriş sınıfınızda. O da programlama öğreniyor!" Joe gururla duyurdu. + +"Bu harika," diye yanıtladım. "Acaba bu kodu okuyabiliyor mu?" + +"Mümkün değil!" dedi Joe. "Bu zor bir şey!" + +"Diyelim ki, bunun gerçek çalışma kodu olduğunu ve birkaç yıl içinde Phil'in bir bakım güncellemesi yapması için tutulduğunu. Onun için ne yaptınız?" diye önerdim. Joe gözlerini kırpıştırarak bana baktı. "Phil'in gerçekten zeki olduğunu biliyoruz, değil mi?" Joe başını salladı. "Bunu söylemekten nefret ediyorum ama ben de oldukça zekiyim!" Joe gülümsedi. "Yani, burada ne yaptığınızı kolayca anlayamazsam ve çok zeki küçük kardeşiniz muhtemelen bunun üzerine kafa yorarsa, bu yazdıklarınız ne anlama geliyor?" Joe koduna bana göründüğünden biraz farklı baktı. "Buna ne dersin, Ben senin arkadaş canlısı akıl hocanım" dedim en iyi sesimle, "Yazdığın her kod satırını gelecekte biri için bir mesaj olarak düşün senin küçük kardeşin olabilecek biri. Bu akıllı kişiye bu zor problemin nasıl çözüleceğini yeniden açıklıyoruz. + +"Hayal etmek istediğiniz bu mu? Gelecekteki akıllı programcının kodunuzu görüp 'Vay! Bu harika! Burada ne yapıldığını çok iyi anlayabiliyorum ve ne kadar zarif bir şey olduğuna hayret ediyorum - hayır, bekle - bu ne güzel bir kod parçası. Ekibimdeki diğer insanlara göstereceğim. Bu bir başyapıt!' + +"Joe, bu zor sorunu çözen ama şarkı söyleyecek kadar güzel olacak bir kod yazabileceğini mi sanıyorsun? Evet, tıpkı akıldan çıkmayan bir melodi gibi. Sanırım senin çok zor çözümünü bulabilen herkes burada da yazabilir. güzel bir şey yaz. Hmm... Acaba güzellik üzerine derecelendirmeye başlamalı mıyım? Ne düşünüyorsun, Joe?" + +Joe işini aldı ve bana baktı, yüzünde küçük bir gülümseme belirdi. "Anladım, prof, dünyayı Phil için daha iyi hale getirmeye gidiyorum. Teşekkürler." + +[Linda Rising](http://programmer.97things.oreilly.com/wiki/index.php/Linda_Rising) Tarafından \ No newline at end of file diff --git a/tr/thing_59/README.md b/tr/thing_59/README.md new file mode 100644 index 00000000..e53443b5 --- /dev/null +++ b/tr/thing_59/README.md @@ -0,0 +1,51 @@ +# Polimorfizm için Kaçırılan Fırsatlar + +Polimorfizm, OO(Object Oriented) için temel olan büyük fikirlerden biridir. Yunancadan gelen sözcük, birçok (*poli*) biçim (*morf*) anlamına gelir. Programlama polimorfizmi bağlamında, belirli bir nesne veya yöntem sınıfının birçok biçimine atıfta bulunur. Ancak polimorfizm sadece alternatif uygulamalarla ilgili değildir. Dikkatli kullanıldığında, polimorfizm, ayrıntılı *if-then-else* bloklarına ihtiyaç duymadan çalışmamıza izin veren küçük yerelleştirilmiş yürütme bağlamları oluşturur. Bir bağlamda olmak, doğru şeyi doğrudan yapmamızı sağlarken, o bağlamın dışında olmak bizi onu yeniden inşa etmeye zorlar, böylece doğru şeyi yapabiliriz. Alternatif uygulamaların dikkatli kullanımıyla, daha okunaklı daha az kod üretmemize yardımcı olabilecek bağlamı yakalayabiliriz. Bu, aşağıdaki (gerçekçi olmayan) basit alışveriş sepeti gibi bazı kodlarla en iyi şekilde gösterilir: + +``` +public class ShoppingCart { + private ArrayList cart = new ArrayList(); + public void add(Item item) { cart.add(item); } + public Item takeNext() { return cart.remove(0); } + public boolean isEmpty() { return cart.isEmpty(); } +} +``` + +Diyelim ki web mağazamız indirilebilecek ürünler ve gönderilmesi gereken ürünler sunuyor. Bu işlemleri destekleyen başka bir nesne oluşturalım: + +``` +public class Shipping { + public boolean ship(Item item, SurfaceAddress address) { ... } + public boolean ship(Item item, EMailAddress address) { ... } +} +``` + +Bir müşteri ödemeyi tamamladığında malları göndermemiz gerekir: + +``` +while (!cart.isEmpty()) { + shipping.ship(cart.takeNext(), ???); +} +``` + +*???* parametresi yeni bir fantezi elvis operatörü değil, öğeyi e-postayla mı göndermeliyim yoksa salyangozla postalamalı mıyım? Bu soruyu cevaplamak için gereken bağlam artık mevcut değil. Sevkiyat yöntemini bir boolean veya enumda yakalayabilir ve ardından eksik parametreyi doldurmak için bir *if-then-else* kullanabilirdik. Başka bir çözüm, her ikisi de Öğeyi genişleten iki sınıf oluşturmak olacaktır. Bunları DownloadableItem ve SurfaceItem olarak adlandıralım. Şimdi biraz kod yazalım. Öğeyi tek bir yöntemi destekleyen bir arayüz olarak tanıtacağım, ship. Sepetin içeriğini göndermek için 'item.ship(shipper)' adını vereceğiz. "DownloadableItem" ve "SurfaceItem" sınıflarının her ikisi de ship'i uygulayacaktır. + +``` +public class DownloadableItem implements Item { + public boolean ship(Shipping shipper) { + shipper.ship(this, customer.getEmailAddress()); + } +} + +public class SurfaceItem implements Item { + public boolean ship(Shipping shipper) { + shipper.ship(this, customer.getSurfaceAddress()); + } +} +``` + +Bu örnekte, `Shipping` ile çalışma sorumluluğunu her bir Öğeye devrettik. Her ürün, en iyi nasıl gönderileceğini bildiğinden, bu düzenleme, bir *if-then-else*'e ihtiyaç duymadan ürünle devam etmemizi sağlar. Kod ayrıca, genellikle birlikte iyi çalışan iki kalıbın kullanımını da gösterir: Komut ve Çift Gönderim. Bu kalıpların etkin kullanımı, polimorfizmin dikkatli kullanımına bağlıdır. Bu olduğunda, kodumuzdaki *if-then-else* bloklarının sayısında bir azalma olacaktır. + +Polimorfizm yerine *if-then-else* kullanmanın çok daha pratik olduğu durumlar olsa da, daha çok polimorfik bir kodlama stilinin daha küçük, daha okunabilir ve daha az kırılgan bir kod tabanı sağlaması daha sık görülür. Kaçırılan fırsatların sayısı, kodumuzdaki *if-then-else* ifadelerinin basit bir sayımıdır. + +[Kirk Pepperdine](http://programmer.97things.oreilly.com/wiki/index.php/Kirk_Pepperdine) Tarafından diff --git a/tr/thing_60/README.md b/tr/thing_60/README.md new file mode 100644 index 00000000..d3a9132c --- /dev/null +++ b/tr/thing_60/README.md @@ -0,0 +1,17 @@ +# Tuhaf Haber: Testçiler Arkadaşlarınızdır + +Kendilerine *Kalite Güvencesi* veya *Kalite Kontrol* desinler, birçok programcı onlara *Sorun* der. Tecrübelerime göre, yazılımcılar genellikle yazılımlarını test eden insanlarla düşmanca bir ilişki içindedir. "Çok seçicidirler" ve "Her şeyin mükemmel olmasını isterler" yaygın şikayetlerdir. Tanıdık geliyor mu? + +Neden olduğundan emin değilim, ama her zaman testçiler hakkında farklı bir görüşüm oldu. Belki de ilk işimdeki "testçi" şirket sekreteri olduğu içindir. Margaret, ofisi çalışır durumda tutan ve birkaç genç yazılımcıya müşterilerin önünde nasıl profesyonelce davranmaları gerektiğini öğretmeye çalışan çok hoş bir kadındı. Ayrıca, ne kadar belirsiz olursa olsun, herhangi bir hatayı sadece anlarda bulma yeteneği vardı. + +O zamanlar kendisini programcı sanan bir muhasebecinin yazdığı bir program üzerinde çalışıyordum. Söylemeye gerek yok, bazı ciddi sorunları vardı. Bir parçamı düzelttiğimi düşündüğümde, Margaret onu kullanmaya çalışırdı ve çoğu zaman birkaç tuşa bastıktan sonra yeni bir şekilde başarısız olurdu. Bazen sinir bozucu ve utanç vericiydi, ama o kadar hoş bir insandı ki, beni kötü gösterdiği için onu suçlamayı hiç düşünmedim. Sonunda Margaret'in programı temiz bir şekilde başlatabildiği, bir fatura girebildiği, yazdırabildiği ve kapatabildiği gün geldi. Heyecanlıydım. Daha da iyisi, müşterimizin makinesine kurduğumuzda her şey işe yaradı. Hiçbir sorun görmediler çünkü Margaret önce onları bulup düzeltmeme yardım etmişti. + +Bu yüzden testçiler sizin arkadaşınızdır diyorum. Testçilerin önemsiz sorunları bildirerek sizi kötü gösterdiğini düşünebilirsiniz. Ancak müşteriler QC'nin düzeltmenizi sağladığı tüm bu "küçük şeyler" tarafından rahatsız edilmedikleri için heyecanlandıklarında harika görünürsünüz. Neyi kastettiğimi anla? + +Şunu hayal edin: Eşzamanlılık sorunlarını bulmak ve düzeltmek için "çığır açan yapay zeka algoritmaları" kullanan bir yardımcı programı test ediyorsunuz. Ateşlersiniz ve açılış ekranında "zeka"yı yanlış yazdıklarını hemen fark edersiniz. Biraz uğursuz, ama bu sadece bir yazım hatası, değil mi? Ardından, yapılandırma ekranının radyo düğmelerinin olması gereken yerlerde onay kutuları kullandığını ve bazı klavye kısayollarının çalışmadığını fark ettiniz. Şimdi, bunların hiçbiri önemli değil, ancak hatalar arttıkça programcıları merak etmeye başlıyorsunuz. Basit şeyleri doğru yapamıyorlarsa, AI'larının eşzamanlılık sorunları gibi zor bir şeyi gerçekten bulma ve düzeltme olasılığı nedir? + +Yapay zekayı delicesine harika yapmaya o kadar odaklanmış dahiler olabilirler ki, bu önemsiz şeyleri fark etmediler. Ve "seçkin testçiler" sorunları belirtmeden, onları bulmaya başladınız. Ve şimdi programcıların yetkinliğini sorguluyorsunuz. + +Kulağa ne kadar garip gelse de, kodunuzdaki her küçük hatayı ortaya çıkarmaya kararlı görünen bu testçiler gerçekten sizin arkadaşlarınızdır. + +[Burk Hufnagel](http://programmer.97things.oreilly.com/wiki/index.php/BurkHufnagel) Tarafından \ No newline at end of file diff --git a/tr/thing_61/README.md b/tr/thing_61/README.md new file mode 100644 index 00000000..159659cd --- /dev/null +++ b/tr/thing_61/README.md @@ -0,0 +1,15 @@ +# Tek İkili + +Yapının, her hedef ortam için özel bir ikili dosya oluşturmak üzere kodun bir bölümünü yeniden yazdığı birkaç proje gördüm. Bu her zaman işleri olması gerekenden daha karmaşık hale getirir ve ekibin her kurulumda tutarlı sürümlere sahip olmama riskini beraberinde getirir. Asgari olarak, her biri daha sonra doğru yere dağıtılması gereken, yazılımın birden çok, neredeyse aynı kopyasının oluşturulmasını içerir. Gerekenden daha fazla hareketli parça anlamına gelir, bu da hata yapmak için daha fazla fırsat anlamına gelir. + +Bir keresinde, her özellik değişikliğinin tam bir inşa döngüsü için kontrol edilmesi gereken bir ekipte çalıştım, bu yüzden testçiler küçük bir ayarlamaya ihtiyaç duyduklarında beklemeye bırakıldılar (inşa etmenin de çok uzun sürdüğünü söylemiş miydim?). Ayrıca sistem yöneticilerinin üretim için sıfırdan yeniden oluşturma konusunda ısrar ettiği bir ekipte de çalıştım (bizimle aynı komut dosyalarını kullanarak), bu da üretimdeki sürümün testten geçen sürüm olduğuna dair hiçbir kanıtımız olmadığı anlamına geliyordu. Ve bunun gibi. + +Kural basittir: *Yayın ardışık düzenindeki tüm aşamalarda tanımlayabileceğiniz ve tanıtabileceğiniz tek bir ikili dosya oluşturun.* Ortama özgü ayrıntıları ortamda tutun. Bu, örneğin bunları bileşen kapsayıcısında, bilinen bir dosyada veya yolda tutmak anlamına gelebilir. + +Ekibiniz bir kod yönetme yapısına sahipse veya tüm hedef ayarları kodla birlikte depoluyorsa, bu, hiç kimsenin tasarımı, uygulamanın özü olan ve platforma özgü özellikleri ayırmak için yeterince dikkatli düşünmediğini gösterir. Ya da daha kötüsü olabilir: Ekip ne yapacağını biliyor ama değişikliği yapma çabasına öncelik veremiyor. + +Elbette istisnalar vardır: Önemli ölçüde farklı kaynak kısıtlamalarına sahip hedefler için inşa ediyor olabilirsiniz, ancak bu, "veritabanını ekrana ve tekrar ekrana" yazan çoğumuz için geçerli değildir. Alternatif olarak, şu anda düzeltmesi çok zor olan bazı eski karışıklıklarla yaşıyor olabilirsiniz. Bu gibi durumlarda, kademeli olarak hareket etmeniz gerekir, ancak mümkün olan en kısa sürede başlayın. + +Ve bir şey daha: Ortam bilgilerini de sürümlü tutun. Bir ortam yapılandırmasını bozmak ve neyin değiştiğini bulamamak kadar kötü bir şey yoktur. Çevresel bilgiler, farklı oranlarda ve farklı nedenlerle değişeceğinden, koddan ayrı olarak versiyonlanmalıdır. Bazı ekipler bunun için dağıtılmış sürüm kontrol sistemleri kullanır (pazar ve git gibi), çünkü üretim ortamlarında yapılan değişiklikleri - kaçınılmaz olarak olduğu gibi - depoya geri göndermeyi kolaylaştırır. + +[Steve Freeman](http://programmer.97things.oreilly.com/wiki/index.php/Steve_Freeman) Tarafından \ No newline at end of file diff --git a/tr/thing_62/README.md b/tr/thing_62/README.md new file mode 100644 index 00000000..d384f60d --- /dev/null +++ b/tr/thing_62/README.md @@ -0,0 +1,13 @@ +# Sadece Kod Gerçeği Söyler + +Bir programın nihai anlamı, çalışan kod tarafından verilir. Bu yalnızca ikili biçimdeyse, okunması zor olacaktır! Bununla birlikte, kaynak kodu sizin programınız, herhangi bir tipik ticari yazılım geliştirme, bir açık kaynak projesi veya dinamik olarak yorumlanan bir dilde kod ise mevcut olmalıdır. Kaynak koduna bakıldığında, programın anlamı açık olmalıdır. Bir programın ne yaptığını bilmek için, baktığınızdan emin olabileceğiniz tek şey kaynaktır. En doğru gereksinimler belgesi bile tüm gerçeği söylemez: Programın gerçekte ne yaptığının ayrıntılı öyküsünü içermez, yalnızca gereksinim analistinin üst düzey niyetlerini içerir. Bir tasarım belgesi, planlanmış bir tasarımı kapsayabilir, ancak uygulamanın gerekli ayrıntılarından yoksun olacaktır. Bu belgeler mevcut uygulama ile senkronizasyonu kaybedilmiş olabilir... veya basitçe kaybolmuş olabilir. Ya da hiç yazılmamış. Kaynak kodu kalan tek şey olabilir. + +Bunu akılda tutarak, kodunuz size veya başka bir programcıya ne yaptığını ne kadar net bir şekilde söylediğini kendinize sorun? + +"Ah, yorumlarım size bilmeniz gereken her şeyi anlatacak" diyebilirsiniz. Ancak yorumların kod çalıştırmadığını unutmayın. Diğer belgeleme biçimleri kadar yanlış olabilirler. Yorumların koşulsuz olarak iyi bir şey olduğunu söyleyen bir gelenek vardır, bu yüzden şüphesiz bazı programcılar daha fazla yorum yazar, hatta kodda zaten açık olan önemsiz şeyleri yeniden ifade edip açıklar. Bu, kodunuzu netleştirmenin yanlış yolu. Kodunuzun yoruma ihtiyacı varsa, olmaması için yeniden düzenlemeyi düşünün. Uzun yorumlar ekran alanını karıştırabilir ve hatta IDE'niz tarafından otomatik olarak gizlenebilir. Bir değişikliği açıklamanız gerekiyorsa, bunu kodda değil sürüm kontrol sistemi giriş mesajında yapın. + +Kodunuzun gerçeği olabildiğince açık bir şekilde söylemesini sağlamak için ne yapabilirsiniz? İyi isimler için çabalayın. Kodunuzu, adlandırmayı da kolaylaştıran uyumlu işlevselliğe göre yapılandırın. Ortogonallik elde etmek için kodunuzu ayırın. Amaçlanan davranışı açıklayan otomatik testler yazın ve arayüzleri kontrol edin. Daha basit ve daha iyi bir çözümü nasıl kodlayacağınızı öğrendiğinizde acımasızca yeniden düzenleme yapın. Kodunuzu okunması ve anlaşılması için mümkün olduğunca basit hale getirin. + +Kodunuza şiir, deneme, herkese açık bir blog veya önemli bir e-posta gibi diğer kompozisyonlar gibi davranın. İfade ettiğiniz şeyi dikkatli bir şekilde oluşturun, böylece yapması gerekeni yapsın ve ne yaptığını mümkün olduğunca doğrudan iletsin, böylece artık etrafta olmadığınızda niyetinizi iletmeye devam etsin. Kullanışlı kodun her zamankinden çok daha uzun süre kullanıldığını unutmayın. Bakım programcıları size teşekkür edecek. Ve bir bakım programcısıysanız ve üzerinde çalıştığınız kod doğruyu kolayca söylemiyorsa, yukarıdaki yönergeleri proaktif bir şekilde uygulayın. Kodda biraz akıl sağlığı oluşturun ve kendi akıl sağlığınızı koruyun. + +[Peter Sommerlad](http://programmer.97things.oreilly.com/wiki/index.php/Peter_Sommerlad) Tarafından \ No newline at end of file diff --git a/tr/thing_63/README.md b/tr/thing_63/README.md new file mode 100644 index 00000000..a57a4a81 --- /dev/null +++ b/tr/thing_63/README.md @@ -0,0 +1,15 @@ +# Yapıya Sahip Olun (ve Yeniden Düzenleyin) + +It is not uncommon for teams that are otherwise highly disciplined about coding practices to neglect build scripts, either out of a belief that they are merely an unimportant detail or from a fear that they are complex and need to be tended to by the cult of release engineering. Unmaintainable build scripts with duplication and errors cause problems of the same magnitude as those in poorly factored code. + +Kodlama uygulamaları konusunda son derece disiplinli olan ekiplerin, bunların yalnızca önemsiz bir ayrıntı oldukları inancıyla veya karmaşık oldukları ve serbest bırakma mühendislik kültü tarafından yönlendirilmeleri gerektiği korkusuyla komut dosyalarını oluşturmayı ihmal etmeleri nadir görülen bir durum değildir. Yinelenen ve hatalar içeren sürdürülemez yapı komut dosyaları, kötü çarpanlara ayrılmış koddakilerle aynı büyüklükte sorunlara neden olur. + +Yanlış deyimler kullanılarak yazılmış derleme komut dosyalarının bakımı ve daha da önemlisi iyileştirmesi zordur. Bir değişiklik yapmanın doğru yolunu anlamak için biraz zaman ayırmaya değer. Bir uygulama bir bağımlılığın yanlış sürümüyle oluşturulduğunda veya derleme zamanı yapılandırması yanlış olduğunda hatalar görünebilir. + +Geleneksel olarak test etme, her zaman "Kalite Güvencesi" ekibine bırakılan bir şey olmuştur. Artık, kod yazarken test etmenin, değeri tahmin edilebilir bir şekilde sunabilmek için gerekli olduğunun farkındayız. Aynı şekilde, oluşturma sürecinin geliştirme ekibine ait olması gerekir. + +Yapıyı anlamak, tüm geliştirme yaşam döngüsünü basitleştirebilir ve maliyetleri azaltabilir. Yürütülmesi kolay bir yapı, yeni bir geliştiricinin hızlı ve kolay bir şekilde başlamasına olanak tanır. Yapıdaki yapılandırmayı otomatikleştirmek, birden fazla kişi bir proje üzerinde çalışırken tutarlı sonuçlar elde etmenizi sağlayabilir ve "benim için çalışıyor" konuşmasından kaçınabilir. Birçok derleme aracı, kod kalitesiyle ilgili raporlar çalıştırmanıza izin vererek olası sorunları erkenden algılamanıza olanak tanır. Yapıyı nasıl kendinize ait yapacağınızı anlamak için zaman harcayarak kendinize ve ekibinizdeki diğer herkese yardımcı olabilirsiniz. Kodlama özelliklerine odaklanabilir, paydaşlarınıza fayda sağlayabilir ve çalışmayı daha keyifli hale getirebilirsiniz. + +Ne zaman ve nasıl değişiklik yapacağınızı bilmek için oluşturma sürecinizi yeterince öğrenin. Derleme komut dosyaları koddur. Uygulama inşa edilene kadar tamamlanmadığı için başka bir nedenden dolayı başka birine bırakılamayacak kadar önemlidirler. Çalışan yazılımı teslim edene kadar programlama işi tamamlanmış sayılmaz. + +[Steve Berczuk](http://programmer.97things.oreilly.com/wiki/index.php/Steve_Berczuk) Tarafından \ No newline at end of file diff --git a/tr/thing_64/README.md b/tr/thing_64/README.md new file mode 100644 index 00000000..0131d9f5 --- /dev/null +++ b/tr/thing_64/README.md @@ -0,0 +1,25 @@ +# Programı Eşleştirin ve Akışı Hissedin + +Yaptığınız şeye tamamen odaklandığınızı, adanmış olduğunuzu ve dahil olduğunuzu hayal edin. Zaman kavramını kaybetmiş olabilirsiniz. Muhtemelen mutlu hissediyorsun. Akış yaşıyorsun. Kolayca bozabilecek çok sayıda kesinti, etkileşim ve diğer dikkat dağıtıcı unsurlar olduğundan, tüm bir geliştirici ekibi için hem akışı sağlamak hem de sürdürmek zordur. + +Eşli programlamayı zaten uyguladıysanız, eşleştirmenin akışa nasıl katkıda bulunduğunu muhtemelen biliyorsunuzdur. Eğer yapmadıysanız, hemen şimdi başlamanız için sizi motive etmek için deneyimlerimizi kullanmak istiyoruz! Eşli programlamada başarılı olmak için hem bireysel ekip üyeleri hem de bir bütün olarak ekip biraz çaba sarf etmelidir. + +Bir ekip üyesi olarak, sizden daha az deneyimli geliştiricilere karşı sabırlı olun. Daha yetenekli geliştiriciler tarafından sindirilme konusundaki korkularınızla yüzleşin. İnsanların farklı olduğunu anlayın ve buna değer verin. Kendi güçlü ve zayıf yönlerinizin yanı sıra diğer ekip üyelerinin de farkında olun. Meslektaşlarınızdan ne kadar öğrenebileceğinize şaşırabilirsiniz. + +Ekip olarak, proje boyunca beceri ve bilginin dağıtımını teşvik etmek için ikili programlamayı tanıtın. Görevlerinizi çiftler halinde çözmeli, ikili ve görevleri sık sık değiştirmelisiniz. Bir rotasyon kuralı üzerinde anlaşın. Kuralı bir kenara koyun veya gerektiğinde ayarlayın. Deneyimlerimiz, bir görevi başka bir çifte döndürmeden önce tamamlamanız gerekmediğidir. Bir görevi başka bir çifte iletmek için kesintiye uğratmak mantıksız gelebilir, ancak işe yaradığını gördük. + +Akışın kesintiye uğrayabileceği, ancak ikili programlamanın akışı korumanıza yardımcı olduğu çok sayıda durum vardır: + +- **"Kamyon faktörünü" azaltın:** Bu biraz hastalıklı bir düşünce deneyi, ancak ekip nihai teslimatı tamamlayamaz hale gelmeden önce kaç ekip üyenize bir kamyon çarpması gerekir? Başka bir deyişle, teslimatınız belirli ekip üyelerine ne kadar bağımlı? Bilgi ayrıcalıklı mıdır yoksa paylaşılır mı? Görevleri çiftler arasında döndürüyorsanız, her zaman bilgiye sahip ve işi tamamlayabilecek başka biri vardır. Takımınızın akışı "kamyon faktöründen" etkilenmez. + +- **Sorunları etkili bir şekilde çözün:** Eşli programlama yapıyorsanız ve zorlu bir sorunla karşılaşırsanız, her zaman tartışabileceğiniz birileri vardır. Bu tür bir diyalog, kendi başınıza sıkışıp kalmanıza kıyasla olasılıkları açma olasılığı daha yüksektir. İş değiştikçe, çözümünüz bir sonraki çift tarafından yeniden gözden geçirilecek ve yeniden değerlendirilecektir, bu nedenle başlangıçta en uygun çözümü seçmemiş olmanız önemli değildir. + +- **Sorunsuz bir şekilde entegre edin:** Mevcut göreviniz başka bir kod parçasını çağırmayı içeriyorsa, yöntemlerin, belgelerin ve testlerin adlarının size ne yaptığına dair bir fikir verecek kadar açıklayıcı olmasını umarsınız. Değilse, o kodu yazmaya dahil olmuş bir geliştiriciyle eşleştirmek size daha iyi bir genel bakış ve kendi kodunuzla daha hızlı entegrasyon sağlayacaktır. Ek olarak, tartışmayı adlandırmayı, belgeleri ve testleri geliştirmek için bir fırsat olarak kullanabilirsiniz. + +- **Kesintileri azaltın:** Biri size bir soru sormak için gelirse veya telefonunuz çalarsa veya acil bir e-postayı yanıtlamanız veya bir toplantıya katılmanız gerekiyorsa, eşli programlama ortağınız kodlamaya devam edebilir. Döndüğünüzde partneriniz hala akıştadır ve çabucak yetişip onlara tekrar katılacaksınız. + +- **Yeni ekip üyelerini hızlı bir şekilde hızlandırın:** Çift programlama ve eşlerin ve görevlerin uygun rotasyonu ile yeni gelenler hem kodu hem de diğer ekip üyelerini hızla tanır. + +Akış sizi inanılmaz derecede üretken kılar. Ama aynı zamanda savunmasızdır. Onu elde etmek için elinizden geleni yapın ve onu elde ettiğinizde ona tutunun! + +[Gudny Hauknes](http://programmer.97things.oreilly.com/wiki/index.php/Gudny_Hauknes), [Ann Katrin Gagnat](http://programmer.97things.oreilly.com/wiki/index.php/Ann_Katrin_Gagnat) ve Kari Røssland Tarafından \ No newline at end of file diff --git a/tr/thing_65/README.md b/tr/thing_65/README.md new file mode 100644 index 00000000..dfadba62 --- /dev/null +++ b/tr/thing_65/README.md @@ -0,0 +1,31 @@ +# Domain Alanına Özgü Türleri İlkel Türlere Tercih Edin + +23 Eylül 1999'da 327,6 milyon dolarlık Mars Climate Orbiter, Dünya'daki bir yazılım hatası nedeniyle Mars'ın yörüngesine girerken kayboldu. Hata daha sonra *metrik karışıklık* olarak adlandırıldı. Uzay aracı Newton'u beklerken yer istasyonu yazılımı pound cinsinden çalışıyordu ve yer istasyonunun uzay aracının iticilerinin gücünü 4,45 kat hafife almasına yol açtı. + +Bu, daha güçlü ve alana özgü yazma uygulanmış olsaydı önlenebilecek birçok yazılım hatası örneğinden biridir. Aynı zamanda, birincil tasarım hedeflerinden biri gömülü güvenlik açısından kritik yazılımı uygulamak olan Ada dilindeki birçok özelliğin ardındaki mantığın bir örneğidir. Ada, hem ilkel türler hem de kullanıcı tanımlı türler için statik denetime sahip güçlü yazmaya sahiptir: + +``` +type Velocity_In_Knots is new Float range 0.0 .. 500.00; + +type Distance_In_Nautical_Miles is new Float range 0.0 .. 3000.00; + +Velocity: Velocity_In_Knots; + +Distance: Distance_In_Nautical_Miles; + +Some_Number: Float; + +Some_Number:= Distance + Velocity; -- Will be caught by the compiler as a type error. +``` + +Daha az talepkar etki alanlarındaki geliştiriciler, aksi takdirde dil tarafından sunulan ilkel veri türlerini ve dizeler ve kayan noktalar gibi kitaplıklarını kullanmaya devam edebilecekleri daha fazla alana özgü yazma uygulamasından da yararlanabilir. Java, C++, Python ve diğer modern dillerde soyut veri türü sınıf olarak bilinir. `Velocity_In_Knots` ve `Distance_In_Nautical_Miles` gibi sınıfların kullanılması, kod kalitesine göre çok fazla değer katar: + +1. Kod, yalnızca Float veya String değil, bir etki alanı kavramlarını ifade ettiği için daha okunabilir hale gelir. +- Kod, kolayca test edilebilir davranışı içine aldığından, kod daha test edilebilir hale gelir. +- Kod, uygulamalar ve sistemler arasında yeniden kullanımı kolaylaştırır. + +Yaklaşım, hem statik hem de dinamik olarak yazılan dillerin kullanıcıları için eşit derecede geçerlidir. Tek fark, statik olarak yazılan dilleri kullanan geliştiricilerin derleyiciden biraz yardım alırken, dinamik olarak yazılan dilleri benimseyenlerin birim testlerine güvenme olasılıklarının daha yüksek olmasıdır. Kontrol tarzı farklı olabilir, ancak motivasyon ve ifade tarzı değildir. + +Buradaki ahlak, kaliteli yazılım geliştirmek amacıyla alana özgü türleri keşfetmeye başlamaktır. + +[Einar Landre](http://programmer.97things.oreilly.com/wiki/index.php/Einar_Landre) Tarafından \ No newline at end of file diff --git a/tr/thing_66/README.md b/tr/thing_66/README.md new file mode 100644 index 00000000..6100ba57 --- /dev/null +++ b/tr/thing_66/README.md @@ -0,0 +1,27 @@ +# Hataları Önle + +Hata mesajları, kullanıcı ile sistemin geri kalanı arasındaki en kritik etkileşimlerdir. Kullanıcı ve sistem arasındaki iletişim kopma noktasına yaklaştığında meydana gelirler. + +Bir hatanın kullanıcıdan gelen yanlış bir girdiden kaynaklandığını düşünmek kolaydır. Ancak insanlar tahmin edilebilir, sistematik yollarla hata yaparlar. Böylece, tıpkı diğer sistem bileşenleri arasında yaptığınız gibi, kullanıcı ile sistemin geri kalanı arasındaki iletişimi 'hata ayıklamak' mümkündür. + +Örneğin, kullanıcının izin verilen bir aralık içinde bir tarih girmesini istediğinizi varsayalım. Kullanıcının herhangi bir tarih girmesine izin vermek yerine, yalnızca izin verilen tarihleri ​​gösteren liste veya takvim gibi bir cihaz sunmak daha iyidir. Bu, kullanıcının aralığın dışında bir tarih girme olasılığını ortadan kaldırır. + +Biçimlendirme hataları başka bir yaygın sorundur. Örneğin, bir kullanıcıya bir Tarih metin alanı sunulur ve "29 Temmuz 2012" gibi açık bir tarih girerse, tercih edilen bir biçimde olmadığı için ("GG/AA/YYYY" gibi) reddetmesi mantıksızdır. "). Fazladan boşluklar içerdiğinden "29 / 07 / 2012"yi reddetmek daha da kötüdür. Bu tür bir sorunu, tarih istenen biçimde göründüğü için özellikle kullanıcıların anlaması zordur. + +Bu hata, tarihi reddetmenin en yaygın üç veya dört tarih biçimini ayrıştırmaktan daha kolay olması nedeniyle oluşur. Bu tür küçük hatalar kullanıcının hayal kırıklığına uğramasına neden olur ve bu da kullanıcı konsantrasyonunu kaybettiği için ek hatalara yol açar. Bunun yerine, kullanıcıların veri değil bilgi girme tercihine saygı gösterin. + +Biçimlendirme hatalarından kaçınmanın bir başka yolu da ipuçları sunmaktır - örneğin, alan içinde istenen biçimi ("GG/AA/YYYY") gösteren bir etiketle. Başka bir ipucu, alanı iki, iki ve dört karakterden oluşan üç metin kutusuna bölmek olabilir. + +İpuçları talimatlardan farklıdır: İpuçları ipucu olma eğilimindedir; talimatlar ayrıntılıdır. Etkileşim noktasında ipuçları oluşur; talimatlar etkileşim noktasından önce görünür. İpuçları bağlam sağlar; talimatlar kullanımı belirler. + +Genel olarak, talimatlar hatayı önlemede etkisizdir. Kullanıcılar, arayüzlerin geçmiş deneyimlerine göre çalışacağını varsayma eğilimindedir ("29 Temmuz 2012"nin ne anlama geldiğini elbette herkes biliyor mu?"). Böylece talimatlar okunmaz. İpuçları, kullanıcıları hatalardan uzaklaştırır. + +Hatalardan kaçınmanın başka bir yolu da varsayılanlar sunmaktır. Örneğin, kullanıcılar genellikle *bugün*, *yarın*, *doğum günüm*, *son teslim tarihim* veya *bu formu en son kullandığımda girdiğim tarihe* karşılık gelen değerleri girerler. Bağlama bağlı olarak, bunlardan birinin akıllı varsayılan olarak iyi bir seçim olması muhtemeldir. + +Sebep ne olursa olsun, sistemler hatalara karşı toleranslı olmalıdır. Bunu, tüm eylemlere ve özellikle de kullanıcıların verilerini yok etme veya değiştirme potansiyeline sahip eylemlere birden fazla *geri alma* düzeyi sağlayarak yapabilirsiniz. + +*Geri al* eylemlerinin günlüğe kaydedilmesi ve analiz edilmesi, arayüzün kullanıcıları sürekli olarak 'yanlış' düğmeye tıklamak gibi bilinçsiz hatalara çektiği yerleri de vurgulayabilir. Bu hatalara genellikle, daha fazla hatayı önlemek için yeniden tasarlayabileceğiniz yanıltıcı ipuçları veya etkileşim dizileri neden olur. + +Hangi yaklaşımı seçerseniz seçin, hataların çoğu sistematiktir - kullanıcı ile yazılım arasındaki yanlış anlamaların sonucudur. Kullanıcıların nasıl düşündüğünü, bilgiyi nasıl yorumladığını, karar verdiğini ve veri girdisini anlamak, yazılımınız ve kullanıcılarınız arasındaki etkileşimlerde hata ayıklamanıza yardımcı olacaktır. + +[Giles Colborne](http://programmer.97things.oreilly.com/wiki/index.php/Giles_Colborne) Tarafından \ No newline at end of file diff --git a/tr/thing_67/README.md b/tr/thing_67/README.md new file mode 100644 index 00000000..819c6c44 --- /dev/null +++ b/tr/thing_67/README.md @@ -0,0 +1,19 @@ +# Profesyonel Yazılımcı + +Profesyonel yazılımcı nedir? + +Profesyonel bir yazılımcının en önemli özelliği *kişisel sorumluluktur*. Profesyonel yazılımcılar kariyerleri, tahminleri, program taahhütleri, hataları ve işçilikleri için sorumluluk alırlar. Profesyonel bir yazılımcı bu sorumluluğu başkalarına devretmez. + +- Eğer bir profesyonelseniz, o zaman kendi kariyerinizden *siz* sorumlusunuz. *Siz* okumaktan ve öğrenmekten sorumlusunuz. Sektör ve teknoloji ile güncel kalmaktan siz sorumlusunuz. Çok fazla yazılımcı, onları eğitmenin işverenlerinin işi olduğunu düşünüyor. Üzgünüm, bu tamamen yanlış. Sizce doktorlar böyle mi davranıyor? Sizce avukatlar böyle mi davranır? Hayır, kendilerini kendi zamanlarına ve kendi nikellerine göre eğitirler. Mesai dışındaki zamanlarının çoğunu günlükleri ve kararları okuyarak geçirirler. Kendilerini güncel tutuyorlar. Biz de öyle yapmalıyız. Sizinle işvereniniz arasındaki ilişki, iş sözleşmenizde güzel bir şekilde belirtilmiştir. Kısacası: Size ödeme yapacaklarına söz veriyorlar ve siz de iyi bir iş çıkaracağınıza söz veriyorsunuz. + +- Profesyoneller yazdıkları kodun sorumluluğunu alırlar. Çalıştığını bilmedikleri sürece kod yayınlamazlar. Bunu bir dakikalığına düşün. Emin olmadığınız bir kodu yayınlamaya istekliyseniz, kendinizi nasıl bir profesyonel olarak kabul edebilirsiniz? Profesyonel yazılımcılar QA'nın *hiçbir şey* bulmasını beklerler çünkü *kodlarını tamamen test edene kadar yayınlamazlar*. Elbette QA bazı problemler bulacaktır çünkü kimse mükemmel değildir. Ancak profesyoneller olarak tavrımız, QA'nın bulması için hiçbir şey bırakmamak olmalıdır. + +- Profesyoneller takım oyuncularıdır. Sadece kendi çalışmalarının değil, tüm ekibin çıktısının sorumluluğunu alırlar. Birbirlerine yardım ederler, birbirlerine öğretirler, birbirlerinden öğrenirler ve hatta gerektiğinde birbirlerini korurlar. Bir takım arkadaşı düştüğünde, diğerleri bir gün korunmaya ihtiyaç duyacaklarını bilerek devreye girer. + +- Profesyoneller büyük hata listelerine tolerans göstermezler. Büyük bir hata listesi özensiz. Sorun izleme veritabanında binlerce sorunu olan sistemler dikkatsizliğin trajedileridir. Gerçekten de, çoğu projede bir sorun takip sistemine duyulan ihtiyaç, dikkatsizliğin bir belirtisidir. Yalnızca en büyük sistemlerin hata listeleri o kadar uzun olmalıdır ki, bunları yönetmek için otomasyon gerekir. + +- Profesyoneller ortalığı karıştırmazlar. İşçiliklerinden gurur duyarlar. Kodlarını temiz, iyi yapılandırılmış ve okunması kolay tutarlar. Üzerinde anlaşmaya varılan standartları ve en iyi uygulamaları takip ederler. Asla, *asla* acele etmezler. Bir doktorun *sizin* üzerinde açık kalp ameliyatı yapmasını izlerken beden dışı bir deneyim yaşadığınızı hayal edin. Bu doktorun bir *son tarihi* var (gerçek anlamda). Kalp-akciğer baypas makinesi kan hücrelerinden çok fazlasına zarar vermeden işini bitirmeli. Nasıl davranmasını istiyorsun? Tipik bir yazılım geliştiricisi gibi davranmasını, acele etmesini ve ortalığı karıştırmasını mı istiyorsunuz? "Geri dönüp bunu daha sonra düzelteceğim" demesini mi istiyorsunuz? Yoksa disiplinlerine dikkatle bağlı kalmasını, zamanını ayırmasını, yaklaşımının makul olarak alabileceği en iyi yaklaşım olduğundan emin olmasını mı istiyorsunuz? Karışıklık mı istiyorsunuz yoksa profesyonellik mi? + +Profesyoneller sorumludur. Kendi kariyerleri için sorumluluk alırlar. Kodlarının düzgün çalıştığından emin olmak için sorumluluk alırlar. İşçiliklerinin kalitesi için sorumluluk alırlar. Son teslim tarihleri yaklaştığında ilkelerinden vazgeçmezler. Gerçekten de, baskı arttığında, profesyoneller doğru olduğunu bildikleri disiplinlere daha da sıkı sarılırlar. + +[Uncle Bob](http://programmer.97things.oreilly.com/wiki/index.php/Uncle_Bob) Tarafından \ No newline at end of file diff --git a/tr/thing_68/README.md b/tr/thing_68/README.md new file mode 100644 index 00000000..263a240f --- /dev/null +++ b/tr/thing_68/README.md @@ -0,0 +1,17 @@ +# Her Şeyi Sürüm Kontrolü Altına Alın + +Tüm projelerinizdeki her şeyi sürüm kontrolü altına alın. İhtiyacınız olan kaynaklar burada: Subversion, Git, Mercurial ve CVS gibi ücretsiz araçlar; bol disk alanı; ucuz ve güçlü sunucular; her yerde ağ; ve hatta proje barındırma hizmetleri. Sürüm kontrol yazılımını kurduktan sonra, çalışmanızı onun deposuna koymak için ihtiyacınız olan tek şey, kodunuzu içeren temiz bir dizinde uygun komutu vermektir. Ve öğrenilecek yalnızca iki yeni temel işlem var: kod değişikliklerinizi depoya *commit* ve projenin çalışma sürümünü deponun sürümüyle güncelliyorsunuz. + +Projeniz sürüm kontrolü altında olduğunda, geçmişini açıkça takip edebilir, kimin hangi kodu yazdığını görebilir ve benzersiz bir tanımlayıcı aracılığıyla bir dosyaya veya proje sürümüne başvurabilirsiniz. Daha da önemlisi, korkmadan cesur kod değişiklikleri yapabilirsiniz. Eski sürüm depoda güvenli bir şekilde bulunduğundan, gelecekte ihtiyaç duymanız durumunda artık yorumlanmış kod yok. Gelecekte müşterinizin çalıştırdığı yazılımın tam sürümünü kolayca yeniden ziyaret edebilmeniz için bir yazılım sürümünü sembolik bir adla etiketleyebilirsiniz (ve gerekir). Paralel geliştirme dalları oluşturabilirsiniz: Çoğu projede etkin bir geliştirme dalı ve yayınlanmış sürümler için aktif olarak desteklenen bir veya daha fazla bakım dalı bulunur. + +Sürüm kontrol sistemi, geliştiriciler arasındaki sürtüşmeyi en aza indirir. Programcılar bağımsız yazılım parçaları üzerinde çalıştıklarında, bunlar neredeyse sihirle bütünleşir. Birbirlerinin ayağına bastıklarında sistem bunu fark eder ve çatışmaları çözmelerine izin verir. Bazı ek kurulumlarla sistem, projenin ilerleyişi hakkında ortak bir anlayış oluşturarak, taahhüt edilen her değişiklik için tüm geliştiricileri bilgilendirebilir. + +Projenizi kurarken cimri olmayın: projenin *tüm* varlıklarını sürüm kontrolü altına alın. Kaynak kodun yanı sıra belgeleri, araçları, derleme komut dosyalarını, test senaryolarını, çizimleri ve hatta kitaplıkları dahil edin. Projenin tamamı (düzenli olarak yedeklenen) depoya güvenli bir şekilde yerleştirildiğinde, disk veya verilerinizi kaybetmenin zararı en aza indirilir. Geliştirme için yeni bir makine kurmak, projeyi depodan kontrol etmeyi içerir. Bu, kodun farklı platformlarda dağıtılmasını, oluşturulmasını ve test edilmesini kolaylaştırır: Her makinede tek bir güncelleme komutu, yazılımın güncel sürüm olmasını sağlar. + +Bir sürüm kontrol sistemiyle çalışmanın güzelliğini gördükten sonra, birkaç kuralı takip etmek sizi ve ekibinizi daha da etkili hale getirecektir: + +- Her mantıksal değişikliği ayrı bir işlemde gerçekleştirin. Birçok değişikliği tek bir işlemde bir araya getirmek, gelecekte bunları çözmeyi zorlaştıracaktır. Bu, diğer değişiklikleri kolayca gizleyebilecek proje çapında yeniden düzenleme veya stil değişiklikleri yaptığınızda özellikle önemlidir. +- Her işleme açıklayıcı bir mesajla eşlik edin. En azından neyi değiştirdiğinizi kısaca açıklayın, ancak değişikliğin mantığını da kaydetmek istiyorsanız, onu saklamak için en iyi yer burasıdır. +- Son olarak, bir projenin yapısını bozacak kodlar kullanmaktan kaçının, aksi takdirde projenin diğer geliştiricileri arasında popüler olmazsınız. + +[Diomidis Spinellis](http://programmer.97things.oreilly.com/wiki/index.php/Diomidis_Spinellis) Tarafından \ No newline at end of file diff --git a/tr/thing_69/README.md b/tr/thing_69/README.md new file mode 100644 index 00000000..a65e5cea --- /dev/null +++ b/tr/thing_69/README.md @@ -0,0 +1,50 @@ +# Fareyi Yere Bırakın ve Klavyeden Uzaklaşın + +Saatlerdir amansız bir soruna odaklandınız ve görünürde bir çözüm yok. Bacaklarınızı uzatmak veya otomatlara çarpmak için ayağa kalkıyorsunuz ve dönüş yolunda cevap aniden ortaya çıkıyor. + +Bu senaryo tanıdık geliyor mu? Neden olduğunu hiç merak ettiniz mi? İşin püf noktası şu ki, kod yazarken beyninizin mantıksal kısmı aktiftir ve yaratıcı taraf kapalıdır. Mantıksal taraf bir mola verene kadar size hiçbir şey sunamaz. + +İşte gerçek hayattan bir örnek: Bazı eski kodları temizliyordum ve 'ilginç' bir yöntemle karşılaştım. *ss:dd:ss xx* biçimini kullanarak bir dizenin geçerli bir zaman içerdiğini doğrulamak için tasarlanmıştır; burada *hh* saati, *mm* dakikayı, *ss* saniyeyi ve *xx* bunlardan birini temsil eder *ÖÖ(AM)* veya *ÖS(PM)*. + +Yöntem, iki karakteri (saati temsil eden) bir sayıya dönüştürmek ve uygun aralıkta olduğunu doğrulamak için aşağıdaki kodu kullandı: + +``` +try { + Integer.parseInt(time.substring(0, 2)); +} catch (Exception x) { + return false; +} + +if (Integer.parseInt(time.substring(0, 2)) > 12) { + return false; +} +``` + +Dakikaları ve saniyeleri test etmek için karakter ofsetinde ve üst limitte uygun değişikliklerle aynı kod iki kez daha ortaya çıktı. Yöntem, AM ve PM'yi kontrol etmek için şu satırlarla sona erdi: + +``` +if (!time.substring(9, 11).equals("AM") & + !time.substring(9, 11).equals("PM")) { + return false; +} +``` + +Bu karşılaştırma dizilerinin hiçbiri başarısız olursa, false döndürülürse, yöntem true değerini döndürür. + +Yukarıdaki kod endişeli ve takip edilmesi zor görünüyorsa, endişelenmeyin. Ben de öyle düşündüm, bu da temizlemeye değer bir şey bulduğum anlamına geliyordu. Yeniden düzenledim ve hala çalıştığından emin olmak için birkaç birim testi yazdım. + +Bitirdiğimde, sonuçlardan memnun hissettim. Orijinal kod saat, dakika ve saniye için yalnızca üst sınırı test ettiğinden, yeni sürümün okunması kolay, yarı boyutunda ve daha doğruydu. + +Ertesi gün işe hazırlanırken kafamda bir fikir belirdi: Neden dizeyi normal bir ifade kullanarak doğrulamıyorsunuz? Birkaç dakika yazdıktan sonra, yalnızca bir kod satırında çalışan bir uygulamam oldu. İşte burada: + +``` +public static boolean validateTime(String time) { + return time.matches("(0[1-9]|1[0-2]):[0-5][0-9]:[0-5][0-9] ([AP]M)"); +} +``` + +Bu hikayenin amacı, sonunda otuzdan fazla kod satırını tek bir kodla değiştirmiş olmam değil. Mesele şu ki, bilgisayardan uzaklaşana kadar ilk denememin soruna en iyi çözüm olduğunu düşündüm. + +Bu yüzden bir daha kötü bir problemle karşılaştığınızda kendinize bir iyilik yapın. Sorunu gerçekten anladığınızda, beyninizin yaratıcı tarafını içeren bir şey yapın - sorunu çizin, biraz müzik dinleyin ya da sadece dışarıda yürüyüşe çıkın. Bazen bir sorunu çözmek için yapabileceğiniz en iyi şey, fareyi bırakıp klavyeden uzaklaşmaktır. + +[BurkHufnagel](http://programmer.97things.oreilly.com/wiki/index.php/BurkHufnagel) Tarafından \ No newline at end of file diff --git a/tr/thing_70/README.md b/tr/thing_70/README.md new file mode 100644 index 00000000..cb7fb8bc --- /dev/null +++ b/tr/thing_70/README.md @@ -0,0 +1,13 @@ +# Kodu Okuyun + +Biz yazılımcılar tuhaf yaratıklarız. Kod yazmayı seviyoruz. Ama iş okumaya gelince genellikle çekiniriz. Sonuçta, kod yazmak çok daha eğlenceli ve kod okumak zor, bazen neredeyse imkansız. Başkalarının kodunu okumak özellikle zordur. Mutlaka diğer insanların kodu kötü olduğu için değil, muhtemelen sorunları sizden farklı şekilde düşündükleri ve çözdükleri için. Ancak başka birinin kodunu okumanın kendinizinkini geliştirebileceğini hiç düşündünüz mü? + +Bir dahaki sefere kod okuduğunuzda, durun ve bir an için düşünün. Kodun okunması kolay mı yoksa zor mu? Okumak zorsa, neden bu? Biçimlendirme kötü mü? Adlandırma tutarsız mı yoksa mantıksız mı? Aynı kod parçasında birkaç endişe birbirine karışmış mı? Belki de dil seçimi kodun okunabilir olmasını engelliyor? Başkalarının hatalarından ders almaya çalışın ki kodunuz aynı hataları içermesin. Birkaç sürprizle karşılaşabilirsiniz. Örneğin, bağımlılık kırma teknikleri düşük bağlantı için iyi olabilir, ancak bazen kodun okunmasını zorlaştırabilir. Ve bazılarının *zarif kod* dediğine, diğerleri *okunamaz* der. + +Kodun okunması kolaysa, ondan öğrenebileceğiniz yararlı bir şey olup olmadığını görmek için durun. Belki de bilmediğiniz veya daha önce uygulamakta zorlandığınız bir tasarım kalıbı kullanılıyor. Belki yöntemler daha kısadır ve isimleri sizinkinden daha anlamlıdır. Bazı açık kaynak projeleri, mükemmel, okunabilir kodun nasıl yazılacağına dair iyi örneklerle doludur - diğerleri ise tam tersi örnekler olarak hizmet eder! Kodlarından bazılarına göz atın ve bir göz atın. + +Şu anda üzerinde çalışmadığınız bir projeden kendi eski kodunuzu okumak da aydınlatıcı bir deneyim olabilir. En eski kodlarınızdan bazılarıyla başlayın ve bugüne kadar ilerleyin. Muhtemelen, okumanın, yazdığınız zamanki kadar kolay olmadığını göreceksiniz. Erken kodunuzun aynı zamanda belirli bir utanç verici eğlence değeri olabilir, tıpkı dün gece barda içki içerken söylediğiniz her şeyin size hatırlatılması gibi. Becerilerinizi yıllar içinde nasıl geliştirdiğinize bir bakın, gerçekten motive edici olabilir. Kodun hangi alanlarının okunmasının zor olduğunu gözlemleyin ve bugün hala aynı şekilde kod yazıp yazmadığınızı düşünün. + +Bu nedenle, bir daha programlama becerilerinizi geliştirme ihtiyacı hissettiğinizde, başka bir kitap okumayın. Kodu okuyun. + +[Karianne Berg](http://programmer.97things.oreilly.com/wiki/index.php/Karianne_Berg) Tarafından \ No newline at end of file diff --git a/tr/thing_71/README.md b/tr/thing_71/README.md new file mode 100644 index 00000000..9a0be408 --- /dev/null +++ b/tr/thing_71/README.md @@ -0,0 +1,13 @@ +# Beşeri Bilimleri Okuyun + +En küçük kalkınma projesinde insanlar insanlarla birlikte çalışır. En soyutlanmış araştırma alanı dışında tüm alanlarda insanlar, belirli bir amaç için onları desteklemek için yazılım yazarlar. İnsanlar insanlar için insanlarla yazılım yazarlar. Bu bir insan işi. Ne yazık ki yazılımcılara çok sık öğretilenler, onları birlikte ve birlikte çalıştıkları insanlarla başa çıkmak için çok zayıf bir şekilde donatıyor. Neyse ki, yardımcı olabilecek bütün bir çalışma alanı var. + +Örneğin, Ludwig Wittgenstein *Felsefi Soruşturmalar*'da (ve başka yerlerde) birbirimizle konuşmak için kullandığımız herhangi bir dilin bir düşünce, fikir veya resim elde etmek için bir serileştirme formatı olmadığını, olamayacağını kişinin kafasına ve bir başkasının kafasına çok iyi bir şekilde ortaya koymaktadır. "Gereksinimleri topladığımızda" yanlış anlaşılmalara karşı şimdiden tetikte olmalıyız. Wittgenstein ayrıca birbirimizi anlama yeteneğimizin paylaşılan tanımlardan kaynaklanmadığını, paylaşılan bir deneyimden, bir yaşam biçiminden kaynaklandığını da gösterir. Bu, sorun alanlarına batmış yazılımcıların, ondan ayrı duranlardan daha iyisini yapma eğiliminde olmasının bir nedeni olabilir. + +Lakoff ve Johnson bize, dilin büyük ölçüde metaforik olduğunu ve bu metaforların dünyayı nasıl anladığımıza dair bir fikir sunduğunu öne süren bir *Yaşadığımız Metaforlar* kataloğunu sunuyor. Bir finansal sistemden bahsederken karşılaşabileceğimiz nakit akışı gibi somut görünen terimler bile mecazi olarak görülebilir: "para bir akışkandır." Bu metafor, parayı idare eden sistemler hakkındaki düşüncelerimizi nasıl etkiler? Veya bir protokol yığınındaki katmanlar hakkında konuşabiliriz, bazıları yüksek seviyeli bazıları düşük seviyeli. Bu güçlü bir metafordur: kullanıcı "yukarı" ve teknoloji "aşağı"dır. Bu, inşa ettiğimiz sistemlerin yapısı hakkındaki düşüncelerimizi ortaya çıkarır. Ayrıca, zaman zaman kırılmaktan fayda sağlayabileceğimiz tembel bir düşünce alışkanlığına da işaret edebilir. + +Martin Heidegger, insanların araçları deneyimleme biçimlerini yakından inceledi. Yazılımcılar araçları inşa eder ve kullanır, biz de araçları düşünür, yaratır, değiştirir ve yeniden yaratırız. Araçlar bizi ilgilendiren nesnelerdir. Ancak Heiddeger'in *Varlık ve Zaman*'da gösterdiği gibi, kullanıcıları için bir araç, yalnızca kullanımda anlaşılan görünmez bir şey haline gelir. Kullanıcılar için araçlar, yalnızca çalışmadıklarında ilgilenilen nesneler haline gelir. Vurgudaki bu farklılık, kullanılabilirlik tartışılırken akılda tutulmaya değerdir. + +Eleanor Rosch, dünya anlayışımızı organize ettiğimiz Aristotelesçi kategori modelini devirdi. Yazılımcılar kullanıcılara bir sistemle ilgili isteklerini sorduğunda, yüklemlerden oluşturulmuş tanımları isteme eğilimindeyiz. Bu bizim için çok uygun. Yüklemlerdeki terimler, bir sınıftaki nitelikler veya bir tablodaki sütunlar haline gelebilir. Bu tür kategoriler net, ayrık ve düzenlidir. Ne yazık ki, Rosch'un "Doğal Kategoriler"de ve sonraki çalışmalarında gösterdiği gibi, insanların genel olarak dünyayı anlama şekli bu değildir. Örneklere dayalı yollarla anlıyorlar. Prototip olarak adlandırılan bazı örnekler diğerlerinden daha iyidir ve bu nedenle ortaya çıkan kategoriler bulanıktır, örtüşürler, zengin iç yapıya sahip olabilirler. Aristotelesçi yanıtlarda ısrar ettiğimiz sürece, kullanıcılara kullanıcının dünyası hakkında doğru soruları soramayız ve ihtiyacımız olan ortak anlayışa ulaşmak için mücadele edeceğiz. + +[Keith Braithwaite](http://programmer.97things.oreilly.com/wiki/index.php/Keith_Braithwaite) Tarafından \ No newline at end of file diff --git a/tr/thing_72/README.md b/tr/thing_72/README.md new file mode 100644 index 00000000..679ce073 --- /dev/null +++ b/tr/thing_72/README.md @@ -0,0 +1,15 @@ +# Tekerleği Sıklıkla Yeniden İcat Edin + +"Var olan bir şeyi kullanın - tekerleği yeniden icat etmek aptalca..." + +Bunu hiç duydunuz mu ya da bunun bir varyasyonunu? Elbette duymuşsunuzdur! Her geliştirici ve öğrenci muhtemelen bu tür yorumları sık sık duyar. Neden? Tekerleği yeniden icat etmek neden bu kadar hoş karşılanmaz? Çünkü çoğu zaman mevcut kod çalışan koddur. Halihazırda bir çeşit kalite kontrolünden, titiz testlerden geçmiştir ve başarıyla kullanılmaktadır. Ek olarak, yeniden icat etmeye harcanan zaman ve çabanın, mevcut bir ürün veya kod tabanını kullanmanın yanı sıra karşılığını vermesi de olası değildir. Tekerleği yeniden icat etmeye zahmet etmeli misiniz? Niye ya? Ne zaman? + +Belki yazılım geliştirmedeki kalıplar hakkında yayınlar veya yazılım tasarımı üzerine kitaplar görmüşsünüzdür. Bu kitaplar, içerdiği bilgiler ne kadar harika olursa olsun, uyuyabilir. Aynı şekilde yelkencilikle ilgili bir film izlemek de yelken açmaktan çok farklıdır, bu yüzden kendi yazılımınızı sıfırdan tasarlamak, test etmek, kırmak, onarmak ve yol boyunca geliştirmek yerine mevcut kodu kullanmak da öyle. + +Tekerleği yeniden icat etmek, yalnızca kod yapılarının nereye yerleştirileceğine dair bir alıştırma değildir: Bu, halihazırda var olan çeşitli bileşenlerin iç işleyişine ilişkin kapsamlı bir bilginin nasıl elde edileceğidir. Bellek yöneticilerinin nasıl çalıştığını biliyor musunuz? Sanal sayfalama? Bunları kendiniz uygulayabilir misiniz? Çift bağlantılı listelere ne dersiniz? Dinamik dizi sınıfları? ODBC istemcileri? Bildiğiniz ve beğendiğiniz popüler bir arayüz gibi çalışan bir grafik kullanıcı arayüzü yazabilir misiniz? Kendi web tarayıcı widget'larınızı oluşturabilir misiniz? Çok iş parçacıklı bir sisteme karşı çoğullamalı bir sistemi ne zaman yazacağınızı biliyor musunuz? Dosya veya bellek tabanlı bir veritabanı arasında nasıl karar verilir? Çoğu geliştirici, bu tür temel yazılım uygulamalarını hiçbir zaman kendileri oluşturmamıştır ve bu nedenle nasıl çalıştıkları konusunda derin bir bilgiye sahip değildir. Sonuç olarak, tüm bu tür yazılımlar, sadece çalışan gizemli kara kutular olarak görülüyor. Suyun sadece yüzeyini anlamak, altındaki gizli tehlikeleri ortaya çıkarmak için yeterli değildir. Yazılım geliştirmedeki daha derin şeyleri bilmemek, mükemmel işler yaratma yeteneğinizi sınırlayacaktır. + +Tekerleği yeniden icat etmek ve yanlış yapmak, onu ilk kez çivilemekten daha değerlidir. Deneme yanılma yoluyla öğrenilen, duygusal bir bileşeni olan ve tek başına teknik bir kitap okumanın sağlayamayacağı dersler vardır! + +Öğrenilmiş gerçekler ve kitap zekası çok önemlidir, ancak harika bir yazılımcı olmak, gerçekleri toplamakla ilgili olduğu kadar deneyim kazanmakla da ilgilidir. Bir vücut geliştiricisi için ağırlık kaldırma ne kadar önemliyse, tekerleği yeniden icat etmek de bir geliştiricinin eğitimi ve becerisi için o kadar önemlidir. + +[Jason P Sage](http://programmer.97things.oreilly.com/wiki/index.php/Jason_P_Sage) Tarafından \ No newline at end of file diff --git a/tr/thing_73/README.md b/tr/thing_73/README.md new file mode 100644 index 00000000..6c42192c --- /dev/null +++ b/tr/thing_73/README.md @@ -0,0 +1,25 @@ +# Singleton Modelin Cazibesine Kapılma + +Singleton modeli, sorunlarınızın çoğunu çözer. Sadece tek bir örneğe ihtiyacınız olduğunu biliyorsunuz. Bu örneğin kullanılmadan önce başlatılacağına dair bir garantiniz var. Küresel bir erişim noktasına sahip olarak tasarımınızı basit tutar. Hepsi iyi. Bu klasik tasarım deseninde sevilmeyen şey nedir? + +Oldukça fazla, ortaya çıkıyor. Cazip olabilirler, ancak deneyimler çoğu singleton'ın gerçekten yarardan çok zarar verdiğini gösteriyor. Test edilebilirliği engeller ve sürdürülebilirliğe zarar verirler. Ne yazık ki, bu ek bilgelik olması gerektiği kadar yaygın değildir ve singleton'lar birçok programcı için karşı konulmaz olmaya devam etmektedir. Ama direnmeye değer: + +- Tek örnek gereksinimi çoğu zaman hayal edilir. Çoğu durumda, gelecekte ek bir örneğe gerek olmayacağı tamamen spekülasyondur. Bir uygulamanın tasarımı boyunca bu tür spekülatif özelliklerin yayınlanması, bir noktada acıya neden olacaktır. Gereksinimler değişecek. İyi tasarım bunu benimser. Singleton'lar yapmaz. + +- Singleton'lar, kavramsal olarak bağımsız kod birimleri arasında örtük bağımlılıklara neden olur. Bu, hem gizli oldukları için hem de birimler arasında gereksiz bağlantı oluşturdukları için sorunludur. Bu kod kokusu, gevşek bağlantıya ve sahte bir uygulamayı gerçek bir uygulamayla seçici olarak değiştirme yeteneğine bağlı olan birim testleri yazmaya çalıştığınızda keskinleşir. Singletons, bu tür basit alaycılığı önler. + +- Singleton'lar ayrıca, birim testini yine engelleyen örtük kalıcı durum taşır. Birim testi, testlerin birbirinden bağımsız olmasına bağlıdır, bu nedenle testler herhangi bir sırada çalıştırılabilir ve program, her birim testinin yürütülmesinden önce bilinen bir duruma ayarlanabilir. Değişken duruma sahip tekilleri tanıttıktan sonra, bunu başarmak zor olabilir. Ek olarak, bu tür küresel olarak erişilebilir kalıcı durum, özellikle çok iş parçacıklı bir ortamda kod hakkında akıl yürütmeyi zorlaştırır. + +- Çoklu iş parçacığı, singleton desene başka tuzaklar getirir. Erişimi doğrudan kilitleme çok verimli olmadığı için, sözde çift kontrol kilitleme modeli (DCLP) popülerlik kazanmıştır. Ne yazık ki, bu ölümcül çekiciliğin başka bir şekli olabilir. DCLP'nin birçok dilde iş parçacığı için güvenli olmadığı ve olduğu yerde bile, onu kurnazca yanlış anlama fırsatları olduğu ortaya çıktı. + +Singletonların temizlenmesi son bir zorluk sunabilir: + +- Bazı bağlamlarda ciddi bir sorun olabilen, Singleton'ları açıkça öldürmek için destek yoktur. Örneğin, bir eklentinin yalnızca tüm nesneleri temizlendikten sonra güvenli bir şekilde kaldırılabileceği bir eklenti mimarisinde. + +- Program çıkışında singleton'ların örtülü temizliğine yönelik bir düzen yoktur. Bu, karşılıklı bağımlılıkları olan tekiller içeren uygulamalar için zahmetli olabilir. Bu tür uygulamaları kapatırken, bir singleton, zaten yok edilmiş olan diğerine erişebilir. + +- Bu eksikliklerin bir kısmı, ek mekanizmalar getirilerek aşılabilir. Ancak bu, alternatif bir tasarım seçerek önlenebilecek ek kod karmaşıklığı pahasına gelir. + +Bu nedenle, Singleton deseni kullanımınızı, gerçekten hiçbir zaman birden çok kez somutlaştırılmaması gereken sınıflarla sınırlayın. Bir singleton'ın global erişim noktasını rastgele koddan kullanmayın. Bunun yerine, singleton'a doğrudan erişim, arayüzü aracılığıyla diğer koda geçirilebileceği yalnızca birkaç iyi tanımlanmış yerden olmalıdır. Bu diğer kod habersizdir ve bu nedenle, bir singleton'un veya başka bir sınıfın arabirimi uygulayıp uygulamadığına bağlı değildir. Bu, birim testini engelleyen bağımlılıkları kırar ve sürdürülebilirliği iyileştirir. Bu nedenle, bir dahaki sefere bir singleton uygulamayı veya ona erişmeyi düşündüğünüzde, umarım durup tekrar düşünürsünüz. + +[Sam Saariste](http://programmer.97things.oreilly.com/wiki/index.php/Sam_Saariste) Tarafından \ No newline at end of file diff --git a/tr/thing_74/README.md b/tr/thing_74/README.md new file mode 100644 index 00000000..d4da7453 --- /dev/null +++ b/tr/thing_74/README.md @@ -0,0 +1,13 @@ +# Performansa Giden Yol Kirli Kod Bombalarıyla Dolu + +Çoğu zaman, bir sistemin performans ayarı, kodu değiştirmenizi gerektirir. Kodu değiştirmemiz gerektiğinde, aşırı karmaşık veya yüksek düzeyde bağlı olan her parça, çabayı raydan çıkarmak için bekleyen kirli bir kod bombasıdır. Kirli kodun ilk zayiatı programınız olacaktır. İleriye giden yol düzgünse, ne zaman bitireceğinizi tahmin etmek kolay olacaktır. Kirli kodla beklenmedik karşılaşmalar, aklı başında bir tahminde bulunmayı çok zorlaştıracaktır. + +Bir yürütme etkin noktası bulduğunuz durumu düşünün. Normal hareket tarzı, temel alınan algoritmanın gücünü azaltmaktır. Diyelim ki yöneticinizin tahmin talebine 3-4 saatlik bir cevapla cevap verdiniz. Düzeltmeyi uygularken, bağımlı bir parçayı kırdığınızı hemen anlarsınız. Yakından ilgili şeyler genellikle zorunlu olarak birleştiğinden, bu kırılma büyük olasılıkla beklenir ve açıklanır. Ancak bu bağımlılığı düzeltmek, diğer bağımlı parçaların kırılmasına neden olursa ne olur? Ayrıca, bağımlılık kökenden ne kadar uzaksa, onu bu şekilde tanımanız ve tahmininizde hesaba katmanız o kadar az olasıdır. 3-4 saatlik tahmininiz birdenbire 3-4 haftaya kolayca uzayabilir. Genellikle programdaki bu beklenmedik şişkinlik, bir seferde 1 veya 2 gün olur. Sonunda tamamlanması birkaç ay süren "hızlı" yeniden düzenlemeleri görmek nadir değildir. Bu durumlarda, sorumlu ekibin güvenilirliğine ve siyasi sermayesine verilen zarar, şiddetli ile ölümcül arasında değişecektir. Keşke bu riski belirlememize ve ölçmemize yardımcı olacak bir aracımız olsaydı. + +Aslında, kodumuzun karmaşıklığını ve bağlantının derecesini ve derinliğini ölçmenin ve kontrol etmenin birçok yolu var. Yazılım ölçümleri, kodumuzdaki belirli özelliklerin oluşumlarını saymak için kullanılabilir. Bu sayıların değerleri kod kalitesiyle ilişkilidir. Bağlantıyı ölçen bir dizi metrikten ikisi, fan-in(bir mantık hücresinin giriş denklemlerini besleyen maksimum giriş sinyali sayısını ifade eder) ve fan-out(bir mantık hücresinin çıkış denklemleri tarafından beslenen maksimum çıkış sinyali sayısını ifade eder). Sınıflar için dağıtmayı düşünün: Bir ilgi sınıfından doğrudan veya dolaylı olarak başvurulan sınıfların sayısı olarak tanımlanır. Bunu, sınıfınız derlenmeden önce derlenmesi gereken tüm sınıfların bir sayısı olarak düşünebilirsiniz. Fan-in ise, ilgilenilen sınıfa bağlı olan tüm sınıfların bir sayısıdır. Fan-out ve fan-in'leri bilerek *I = fo / (fi + fo)* kullanarak bir istikrarsızlık faktörünü hesaplayabiliriz. . *I* 0'a yaklaştıkça paket daha kararlı hale gelir. *I* 1'e yaklaştıkça paket kararsız hale gelir. Kararlı paketler, yeniden kodlama için düşük riskli hedeflerken, kararsız paketlerin kirli kod bombalarıyla doldurulması daha olasıdır. Yeniden düzenlemedeki amaç *I*'yi 0'a yaklaştırmaktır. + +Metrikleri kullanırken, bunların yalnızca temel kurallar olduğu unutulmamalıdır. Tamamen matematikte, fo'yu değiştirmeden *fi* artırmanın *I*'yi 0'a yaklaştıracağını görebiliriz. Ancak, bu sınıfta çok büyük bir fan-in değerinin dezavantajı vardır. bağımlıları kırmadan değiştirmek daha zor olacaktır. Ayrıca, fan-out'u ele almadan risklerinizi gerçekten azaltmıyorsunuz, bu nedenle bir miktar denge uygulanmalıdır. + +Yazılım metriklerinin bir dezavantajı, metrik araçlarının ürettiği çok sayıda sayının tecrübesiz kişiler için göz korkutucu olabilmesidir. Bununla birlikte, yazılım metrikleri temiz kod mücadelemizde güçlü bir araç olabilir. Performans ayarlama alıştırması için ciddi bir risk oluşturmadan önce kirli kod bombalarını belirlememize ve ortadan kaldırmamıza yardımcı olabilirler. + +[Kirk Pepperdine](http://programmer.97things.oreilly.com/wiki/index.php/Kirk_Pepperdine) Tarafından \ No newline at end of file diff --git a/tr/thing_75/README.md b/tr/thing_75/README.md new file mode 100644 index 00000000..ba22ae67 --- /dev/null +++ b/tr/thing_75/README.md @@ -0,0 +1,19 @@ +# Sadelik Azaltmadan Gelir + +"Tekrar yap..." dedi patronum, parmağıyla silme tuşuna sertçe basarken. Kodum satır satır unutulup giderken, bilgisayar ekranını çok tanıdık bir batan duyguyla izledim. + +Patronum Stefan, her zaman insanların arasında en çok ses çıkaran kişi değildi, ama kötü kodu gördüğünde biliyordu. Ve onunla ne yapması gerektiğini çok iyi biliyordu. + +Öğrenci programcı olarak şu anki pozisyonuma bol enerji, bol hevesle gelmiştim ama kodlama hakkında kesinlikle hiçbir fikrim yoktu. Her sorunun çözümünün bir yere başka bir değişken eklemek olduğunu düşünmek gibi korkunç bir eğilimim vardı. Veya başka bir satıra atın. Kötü bir günde, mantığım her revizyonda daha iyi hale gelmek yerine, kodum yavaş yavaş daha büyük, daha karmaşık ve tutarlı bir şekilde çalışmaktan uzaklaştı. + +Özellikle acele ederken, korkunç olsa bile mevcut bir kod bloğunda en az değişiklikleri yapmak istemek doğaldır. Çoğu programcı, yeniden başlamanın, başa dönmekten çok daha fazla çaba gerektireceğinden korkarak hatalı kodu koruyacaktır. Bu, çalışmaya yakın kodlar için doğru olabilir, ancak tüm yardımların ötesinde olan bazı kodlar var. + +Kötü işleri kurtarmaya çalışırken olması gerekenden daha fazla zaman harcanır. Bir şey kaynak havuzuna dönüştüğünde, hızlıca atılması gerekir. + +Tüm bu yazma, adlandırma ve biçimlendirme işlemlerini kolayca bir kenara atmanız gerekmez. Patronumun tepkisi aşırıydı, ancak ikinci (veya bazen üçüncü) denemede beni kodu yeniden düşünmeye zorladı. Yine de, hatalı kodu düzeltmenin en iyi yaklaşımı, kodun acımasızca yeniden yapılandırıldığı, değiştirildiği veya silindiği bir moda geçmektir. + +Kod basit olmalıdır. Minimum sayıda değişken, işlev, bildirim ve diğer sözdizimsel dil gereksinimleri olmalıdır. Fazladan satırlar, fazladan değişkenler... fazladan *herhangi bir şey*, gerçekten temizlenmelidir. Hemen kaldırıldı. Orada ne var, ne kaldı, sadece işi bitirmek, algoritmayı tamamlamak veya hesaplamaları yapmak için yeterli olmalıdır. Diğer her şey, kazayla ortaya çıkan ve akışı engelleyen fazladan istenmeyen gürültüdür. Önemli şeyleri gizlemek. + +Tabii ki, bu işe yaramazsa, hepsini silin ve tekrar yazın. Birinin hafızasından bu şekilde çizim yapmak çoğu zaman gereksiz yere dağınıklığın üstesinden gelmeye yardımcı olabilir. + +[Paul W. Homer](http://programmer.97things.oreilly.com/wiki/index.php/Paul_W._Homer) Tarafından \ No newline at end of file diff --git a/tr/thing_76/README.md b/tr/thing_76/README.md new file mode 100644 index 00000000..5162ec30 --- /dev/null +++ b/tr/thing_76/README.md @@ -0,0 +1,41 @@ +# Tek Sorumluluk İlkesi(The Single Responsibility) + +İyi tasarımın en temel ilkelerinden biri: + +> Aynı nedenle değişenleri bir araya toplayın ve farklı nedenlerle değişenleri ayırın. + +Bu ilke genellikle *Tek Sorumluluk İlkesi* veya SRP olarak bilinir. Kısacası, bir alt sistemin, modülün, sınıfın ve hatta bir fonksiyonun değişmesi için birden fazla nedeni olmaması gerektiğini söylüyor. Klasik örnek, iş kuralları, raporlar ve veritabanıyla ilgilenen yöntemlere sahip bir sınıftır: + +``` +public class Employee { + public Money calculatePay() ... + public String reportHours() ... + public void save() ... +} +``` + +Bazı programcılar, bu üç işlevi aynı sınıfta bir araya getirmenin tamamen uygun olduğunu düşünebilir. Sonuçta, sınıfların ortak değişkenler üzerinde çalışan fonksiyonların koleksiyonları olması gerekiyordu. Ancak sorun, üç işlevin tamamen farklı nedenlerle değişmesidir. `calculatePay` işlevi, ödeme değişikliğini hesaplamak için iş kuralları her değiştiğinde değişecektir. Birisi rapor için farklı bir format istediğinde `reportHours` işlevi değişecektir. DBA'lar veritabanı şemasını her değiştirdiğinde kaydetme işlevi değişecektir. Değişimin bu üç nedeni, `Employee`i çok değişken hale getirmek için birleşir. Bu nedenlerden herhangi biri için değişecektir. Daha da önemlisi, `Employee`ye bağlı tüm sınıflar bu değişikliklerden etkilenecektir. + +İyi sistem tasarımı, sistemi bağımsız olarak dağıtılabilen bileşenlere ayırmamız anlamına gelir. Bağımsız dağıtım, bir bileşeni değiştirirsek diğerlerini yeniden dağıtmamız gerekmediği anlamına gelir. Ancak, `Employee` diğer bileşenlerdeki diğer birçok sınıf tarafından yoğun bir şekilde kullanılıyorsa, o zaman `Employee`de yapılan her değişikliğin diğer bileşenlerin yeniden konuşlandırılmasına neden olması muhtemeldir; böylece bileşen tasarımının (veya daha popüler bir adı tercih ederseniz SOA) büyük bir faydasını reddeder. + +``` +public class Employee { + public Money calculatePay() ... +} + +public class EmployeeReporter { + public String reportHours(Employee e) ... +} + +public class EmployeeRepository { + public void save(Employee e) ... +} +``` + +Yukarıda gösterilen basit bölümleme, sorunları çözer. Bu sınıfların her biri kendi bileşenine yerleştirilebilir. Daha doğrusu, tüm raporlama sınıfları raporlama bileşenine girebilir. Veritabanıyla ilgili tüm sınıflar depo bileşenine girebilir. Ve tüm iş kuralları, iş kuralı bileşenine girebilir. + +Zeki okuyucu, yukarıdaki çözümde hala bağımlılıklar olduğunu görecektir. Bu `Employee` hala diğer sınıflar tarafından bağımlıdır. Dolayısıyla, `Employee` değiştirilirse, diğer sınıfların büyük olasılıkla yeniden derlenmesi ve yeniden konuşlandırılması gerekecektir. Bu nedenle, `Employee` değiştirilemez ve ardından bağımsız olarak konuşlandırılamaz. Ancak, diğer sınıflar değiştirilebilir ve bağımsız olarak dağıtılabilir. Bunlardan birinde yapılacak hiçbir değişiklik, diğerlerini yeniden derlenmeye veya yeniden dağıtılmaya zorlayamaz. `Employee` bile *Bağımlılığı Tersine Çevirme İlkesi(Dependency Inversion Principle)* (DIP) dikkatli bir şekilde kullanılarak bağımsız olarak konuşlandırılabilir, ancak bu [farklı bir kitabın](http://www.amazon.com/dp/0135974445/) konusu. + +Farklı nedenlerle değişen şeyleri ayıran SRP'nin dikkatli bir şekilde uygulanması, bağımsız olarak konuşlandırılabilir bir bileşen yapısına sahip tasarımlar oluşturmanın anahtarlarından biridir. + +[Uncle Bob](http://programmer.97things.oreilly.com/wiki/index.php/Uncle_Bob) Tarafından \ No newline at end of file diff --git a/tr/thing_77/README.md b/tr/thing_77/README.md new file mode 100644 index 00000000..8dc873f4 --- /dev/null +++ b/tr/thing_77/README.md @@ -0,0 +1,23 @@ +# Evet'ten Başlayın + +Geçenlerde bir bakkaldaydım ve "edamame" için yüksek ve düşük arama yapıyordum (bir tür sebze olduğunu sadece belli belirsiz biliyordum). Bunun sebze bölümünde mi, donmuş bölümde mi yoksa konservede mi bulacağımdan emin değildim. Vazgeçtim ve bana yardım etmesi için bir çalışanın izini sürdüm. O da bilmiyordu! + +Çalışan birçok farklı şekilde yanıt verebilirdi. Nereye bakacağımı bilmediğim için beni cahil hissettirebilirdi, ya da bana belirsiz olasılıklar verebilirdi, hatta bana eşyanın onlarda olmadığını söyleyebilirdi. Ancak bunun yerine talebi bir çözüm bulma ve müşteriye yardım etme fırsatı olarak değerlendirdi. Diğer çalışanları aradı ve dakikalar içinde beni donmuş bölümde bulunan tam öğeye yönlendirdi. + +Bu durumda çalışan bir talebe baktı ve sorunu çözeceğimiz ve talebi karşılayacağımız öncülünden yola çıktı. Hayırdan başlamak yerine *evet* ile başladı. + +Teknik bir liderlik rolüne ilk yerleştirildiğimde, işimin güzel yazılımımı ürün yöneticilerinden ve iş analistlerinden gelen gülünç talep akışından korumak olduğunu hissettim. Çoğu sohbete, bir talebi kabul edilecek bir şey değil, yenilecek bir şey olarak görmeye başladım. + +Bir noktada, belki de bakış açımı hayırdan başlayıp *evet* ile başlamayı içeren farklı bir çalışma yolu olduğuna dair bir aydınlanma yaşadım. Aslında, *evet* ile başlamanın aslında teknik bir lider olmanın önemli bir parçası olduğuna inanmaya başladım. + +Bu basit değişiklik, işime nasıl yaklaştığımı kökten değiştirdi. Görünen o ki, *evet* demenin birçok yolu var. Biri size "Hey, tüm pencereleri yuvarlak ve yarı saydam yapsaydık, bu uygulama gerçekten arıların dizleri olurdu!" dediğinde. bunu saçma bularak reddedebilirsin. Ancak genellikle "Neden?" ile başlamak daha iyidir. Bunun yerine. Çoğu zaman, o kişinin ilk etapta yuvarlak yarı saydam pencereler istemesinin bazı gerçek ve zorlayıcı nedenleri vardır. Örneğin, yuvarlak yarı saydam pencereleri zorunlu kılan bir standartlar komitesiyle yeni ve büyük bir müşteriyle anlaşmak üzere olabilirsiniz. + +Genellikle, talebin içeriğini bildiğinizde yeni olasılıkların açıldığını göreceksiniz. İsteğin, mevcut ürünle başka bir şekilde gerçekleştirilmesi, hiç çalışmadan *evet* demenize olanak tanıyan yaygın bir durumdur: "Aslında, kullanıcı tercihlerinde yuvarlak yarı saydam pencere kaplamasını indirebilir ve açabilirsiniz." + +Bazen diğer kişi, ürüne bakışınızla uyumsuz bulduğunuz bir fikre sahip olacaktır. Bunu "Neden?" diye çevirmenin kendinde genellikle yararlı olduğunu düşünüyorum. Bazen sebebi dile getirme eylemi, ilk tepkinizin mantıklı olmadığını açıkça ortaya koyacaktır. Değilse, bir çentik atmanız ve diğer önemli karar vericileri getirmeniz gerekebilir. Unutmayın, tüm bunların amacı karşınızdaki kişiye *evet* demek ve bunu sadece onun için değil sizin ve ekibiniz için de çalıştırmaya çalışmaktır. + +Özellik isteğinin neden mevcut ürünle uyumsuz olduğuna dair ikna edici bir açıklama yapabiliyorsanız, doğru ürünü oluşturup oluşturmadığınız konusunda verimli bir konuşma yapmanız olasıdır. Bu konuşmanın nasıl sonuçlandığına bakılmaksızın, herkes ürünün ne olduğuna ve ne olmadığına daha keskin bir şekilde odaklanacaktır. + +*Evet*'ten başlamak, iş arkadaşlarınızla birlikte çalışmak anlamına gelir, onlara karşı değil. + +By [Alex Miller](http://programmer.97things.oreilly.com/wiki/index.php/Alex_Miller) \ No newline at end of file diff --git a/tr/thing_78/README.md b/tr/thing_78/README.md new file mode 100644 index 00000000..1e371184 --- /dev/null +++ b/tr/thing_78/README.md @@ -0,0 +1,29 @@ +# Geri Adım Atın ve Otomatikleştirin, Otomatikleştirin, Otomatikleştirin + +Bir modülde kod satırlarının sayısını üretmesi istendiğinde, dosyaları bir kelime işlemciye yapıştıran ve onun "satır sayısı" özelliğini kullanan programcılarla çalıştım. Ve haftaya tekrar yaptılar. Ve sonraki hafta. Kötüydü. + +Kod imzalamayı ve sonucu bir sunucuya taşımayı içeren, çok sayıda fare tıklaması gerektiren, hantal bir dağıtım süreci olan bir proje üzerinde çalıştım. Birisi bunu otomatikleştirdi ve komut dosyası, son test sırasında, beklenenden çok daha sık olarak yüzlerce kez çalıştı. İyiydi. + +Öyleyse, neden insanlar geri adım atmak ve otomatikleştirmek için zaman ayırmak yerine aynı görevi tekrar tekrar yapıyorlar? + +## Yaygın yanlış anlama #1: Otomasyon yalnızca test amaçlıdır. + +Elbette, test otomasyonu harika, ama neden orada dursun? Herhangi bir projede tekrarlanan görevler bol miktarda bulunur: sürüm kontrolü, derleme, JAR dosyaları oluşturma, belge oluşturma, dağıtım ve raporlama. Bu görevlerin çoğu için komut dosyası fareden daha güçlüdür. Sıkıcı görevleri yürütmek daha hızlı ve daha güvenilir hale gelir. + +## Yaygın yanlış anlama #2: Bir IDE'm var, bu yüzden otomatikleştirmem gerekmiyor. + +Makinemde hiç "Ama bu (kontrol eder|derlenir|testleri geçer)" oldu mu? takım arkadaşlarınızla tartışır mısınız? Modern IDE'lerin binlerce potansiyel ayarı vardır ve tüm ekip üyelerinin aynı konfigürasyonlara sahip olmasını sağlamak esasen imkansızdır. Ant veya Autotools gibi otomasyon sistemleri oluşturun, size kontrol ve tekrarlanabilirlik sağlar. + +## Yaygın yanlış anlama #3: Otomatikleştirmek için egzotik araçlar öğrenmem gerekiyor. + +İyi bir shell dili (bash veya PowerShell gibi) ve bir yapı otomasyon sistemi ile uzun bir yol kat edebilirsiniz. Web siteleriyle etkileşim kurmanız gerekiyorsa, iMacros veya Selenium gibi bir araç kullanın. + +## Yaygın yanlış anlama #4: Bu dosya formatlarıyla baş edemediğim için bu görevi otomatikleştiremiyorum. + +Sürecinizin bir kısmı Word belgeleri, elektronik tablolar veya resimler gerektiriyorsa, bunu otomatikleştirmek gerçekten zor olabilir. Ama bu gerçekten gerekli mi? Düz metin kullanabilir misiniz? Virgülle ayrılmış değerler? XML? Bir metin dosyasından çizim oluşturan bir araç mı? Çoğu zaman, süreçteki hafif bir ince ayar, sıkıcılıkta önemli bir azalma ile iyi sonuçlar verebilir. + +## Yaygın yanlış anlama #5: Bunu çözecek zamanım yok. + +Başlamak için tüm bash veya Ant'ı öğrenmeniz gerekmez. Gittikçe öğren. Otomatikleştirilebileceğini ve otomatikleştirilmesi gerektiğini düşündüğünüz bir göreviniz olduğunda, bunu yapmak için araçlarınız hakkında yeterince bilgi edinin. Ve bunu, zaman bulmanın genellikle daha kolay olduğu bir projede erken yapın. Başarılı olduğunuzda, siz (ve patronunuz) otomasyona yatırım yapmanın mantıklı olduğunu göreceksiniz. + +[Cay Horstmann](http://programmer.97things.oreilly.com/wiki/index.php/Cay_Horstmann) Tarafından diff --git a/tr/thing_79/README.md b/tr/thing_79/README.md new file mode 100644 index 00000000..5679a495 --- /dev/null +++ b/tr/thing_79/README.md @@ -0,0 +1,13 @@ +# Kod Analiz Araçlarından Yararlanın + +Testin değeri, yazılım geliştiricilere programlama yolculuklarının ilk aşamalarından itibaren dahil edilen bir şeydir. Son yıllarda birim testinin, teste dayalı geliştirmenin ve çevik yöntemlerin yükselişi, geliştirme döngüsünün tüm aşamalarında testten en iyi şekilde yararlanmaya olan ilgide bir artış gördü. Ancak test etme, kodun kalitesini artırmak için kullanabileceğiniz birçok araçtan yalnızca biridir. + +Zamanın sisli zamanlarında, C'nin henüz yeni bir fenomen olduğu zamanlarda, CPU zamanı ve her türlü depolama çok değerliydi. İlk C derleyicileri bunun farkındaydı ve bu nedenle bazı anlamsal analizleri kaldırarak yaptıkları koddan geçiş sayısını azalttı. Bu, derleyicinin, derleme zamanında tespit edilebilecek hataların yalnızca küçük bir alt kümesini kontrol ettiği anlamına geliyordu. Bunu telafi etmek için Stephen Johnson, *lint* adlı, kodunuzdaki tüyleri kaldıran bir araç yazdı ve bu araç, kardeş C derleyicisinden kaldırılan bazı statik analizleri uyguladı. Bununla birlikte, statik analiz araçları, her zaman takip edilmesi gerekmeyen üslup kuralları hakkında çok sayıda yanlış pozitif uyarı ve uyarı vermesiyle ün kazandı. + +Mevcut diller, derleyiciler ve statik analiz araçları manzarası çok farklıdır. Bellek ve CPU zamanı artık nispeten ucuzdur, bu nedenle derleyiciler daha fazla hata olup olmadığını kontrol edebilir. Hemen hemen her dilde, stil kılavuzlarının ihlallerini, yaygın yakalamaları ve bazen potansiyel boş gösterici referansları gibi yakalanması zor olabilecek kurnaz hataları kontrol eden en az bir araç bulunur. Splint for C veya Pylint for Python gibi daha karmaşık araçlar yapılandırılabilir, yani aracın bir yapılandırma dosyasıyla, komut satırı anahtarları aracılığıyla veya IDE'nizde hangi hataları ve uyarıları yayınlayacağını seçebilirsiniz. Splint, programınızın nasıl çalıştığı hakkında daha iyi ipuçları vermek için yorumlarda kodunuza açıklama eklemenize bile izin verir. + +Her şey başarısız olursa ve kendinizi derleyiciniz, IDE veya tiftik araçlarınız tarafından yakalanmayan basit hatalar veya standart ihlalleri ararken bulursanız, o zaman her zaman kendi statik denetleyicinizi çalıştırabilirsiniz. Bu kulağa geldiği kadar zor değil. Çoğu dil, özellikle *dinamik* markalı olanlar, standart kitaplıklarının bir parçası olarak soyut sözdizimi ağaçlarını ve derleyici araçlarını sunar. Kullanmakta olduğunuz dilin geliştirme ekibi tarafından kullanılan standart kitaplıkların tozlu köşelerini tanımaya değer, çünkü bunlar genellikle statik analiz ve dinamik testler için yararlı olan gizli mücevherler içerir. Örneğin, Python standart kitaplığı, derlenmiş bir kod veya kod nesnesi oluşturmak için kullanılan bayt kodunu size söyleyen bir ayrıştırıcı içerir. Bu, python-dev ekibindeki derleyici yazarları için belirsiz bir araç gibi görünüyor, ancak aslında günlük durumlarda şaşırtıcı derecede faydalıdır. Bu kitaplığın parçalarına ayırabileceği bir şey, son yığın izlemenizdir ve tam olarak hangi bayt kodu talimatının yakalanmamış son istisnayı attığı konusunda size geri bildirim verir. + +Bu nedenle, testin kalite güvencenizin sonu olmasına izin vermeyin - analiz araçlarından yararlanın ve kendinizinkini kullanmaktan korkmayın. + +[Sarah Mount](http://programmer.97things.oreilly.com/wiki/index.php/Sarah_Mount) Tarafından \ No newline at end of file diff --git a/tr/thing_80/README.md b/tr/thing_80/README.md new file mode 100644 index 00000000..358fc93f --- /dev/null +++ b/tr/thing_80/README.md @@ -0,0 +1,15 @@ +# Tesadüfi Davranış Değil, Gerekli Davranış Testi + +Test etmedeki yaygın bir tuzak, bir uygulamanın tam olarak ne yaptığını tam olarak test etmek istediğiniz şey olduğunu varsaymaktır. İlk bakışta bu bir tuzaktan çok bir erdem gibi geliyor. Bununla birlikte, başka bir şekilde ifade edilirse, sorun daha açık hale gelir: Testlerdeki yaygın bir tuzak, testleri bir uygulamanın özelliklerine bağlamaktır, burada bu özellikler tesadüfidir ve istenen işlevsellik üzerinde hiçbir etkisi yoktur. + +Testler, uygulama tesadüflerine bağlı olduğunda, gerekli davranışla gerçekten uyumlu olan uygulamada yapılan değişiklikler, testlerin başarısız olmasına ve yanlış pozitiflere yol açmasına neden olabilir. Programcılar genellikle ya testi yeniden yazarak ya da kodu yeniden yazarak yanıt verirler. Yanlış bir pozitifin aslında gerçek bir pozitif olduğunu varsaymak genellikle korku, belirsizlik veya şüphenin bir sonucudur. Tesadüfi davranışın statüsünü istenen davranışa yükseltme etkisine sahiptir. Bir testi yeniden yazarken, programcılar ya testi gerekli davranışa yeniden odaklarlar (iyi) ya da basitçe yeni uygulamaya (iyi değil) bağlarlar. Testlerin yeterince kesin olması gerekir, ancak aynı zamanda doğru olmaları gerekir. + +Örneğin, C'nin `strcmp` veya Java'nın `String.compareTo` gibi üç yönlü bir karşılaştırmada, sonuçtaki gereksinimler, sol taraf sağdan küçükse negatif, sol taraf sağdan büyükse pozitif ve eşit olarak kabul edilirse sıfır olmasıdır. Bu karşılaştırma stili, C'nin `qsort` işlevi için karşılaştırıcı ve Java'nın `Karşılaştırılabilir` arabirimindeki `compareTo` dahil olmak üzere birçok API'de kullanılır. Belirli `-1` ve `+1` değerleri, uygulamalarda sırasıyla *küçüktür* ve *büyüktür* belirtmek için yaygın olarak kullanılsa da, programcılar sıklıkla yanlışlıkla bu değerlerin gerçek gereksinimi temsil ettiğini varsaymakta ve sonuç olarak bunu sağlayan testler yazmaktadır. + +Benzer bir sorun, boşluk, kesin ifadeler ve metinsel biçimlendirme ve sunumun tesadüfi olan diğer yönlerini öne süren testlerde ortaya çıkar. Örneğin, yapılandırılabilir biçimlendirme sunan bir XML oluşturucu yazmıyorsanız, sonuç için boşluk önemli olmamalıdır. Benzer şekilde, düğmelerin ve etiketlerin UI kontrollerine donanım bağlantısıyla yerleştirilmesi, gelecekte bu olası durumları değiştirme ve iyileştirme seçeneğini azaltır. Uygulamadaki küçük değişiklikler ve biçimlendirmedeki önemsiz değişiklikler aniden yapı kesiciler haline gelir. + +Aşırı belirtilmiş testler, genellikle birim testine yönelik beyaz kutu yaklaşımlarıyla ilgili bir sorundur. Beyaz kutu testleri, gereken test senaryolarını belirlemek için kodun yapısını kullanır. Beyaz kutu testinin tipik başarısızlık modu, testlerin sonunda kodun, kodun yaptığını yaptığını iddia etmesidir. Basitçe, koddan zaten bariz olanı yeniden yazmak hiçbir değer katmaz ve yanlış bir ilerleme ve güvenlik duygusuna yol açar. + +Etkili olması için, testlerin papağan uygulamalarından ziyade sözleşme yükümlülüklerini belirtmesi gerekir. Arayüz sözleşmelerini yürütülebilir biçimde çizerek, test edilen birimlerin kara kutu görünümünü almaları gerekir. Bu nedenle, test edilen davranışı gerekli davranışla hizalayın. + +[Kevlin Henney](http://programmer.97things.oreilly.com/wiki/index.php/Kevlin_Henney) Tarafından \ No newline at end of file diff --git a/tr/thing_81/README.md b/tr/thing_81/README.md new file mode 100644 index 00000000..60604e47 --- /dev/null +++ b/tr/thing_81/README.md @@ -0,0 +1,45 @@ +# Kesin ve Somut Test Edin + +Belirli bir uygulamanın tesadüfi davranışını test etmek yerine, bir kod biriminin istenen, temel davranışını test etmek önemlidir. Ancak bu, belirsiz testler için bir bahane olarak alınmamalı veya yanlış anlaşılmamalıdır. Testlerin doğru *ve* kesin olması gerekir. + +Denenmiş, test edilmiş ve test edilmiş klasik sıralama rutinlerinden bir şey açıklayıcı bir örnek sunar. Sıralama algoritması uygulamak, bir programcı için mutlaka günlük bir görev değildir, ancak sıralama o kadar tanıdık bir fikirdir ki, çoğu insan ondan ne bekleyeceğini bildiğine inanır. Ancak bu sıradan aşinalık, geçmiş belirli varsayımları görmeyi zorlaştırabilir. + +Programcılara "Neyi test edersiniz?" diye sorulduğunda açık ara en yaygın yanıt "Sıralamanın sonucu, sıralanmış bir öğe dizisidir." Bu doğru olsa da, gerçeğin tamamı bu değildir. Daha kesin bir koşul istendiğinde, birçok programcı, ortaya çıkan dizinin orijinaliyle aynı uzunlukta olması gerektiğini ekler. Doğru olmasına rağmen, bu hala yeterli değil. Örneğin, aşağıdaki sıra verilir: + +``` +3 1 4 1 5 9 +``` + +Aşağıdaki dizi, azalan düzende sıralanmama ve orijinal diziyle aynı uzunluğa sahip olma son koşulunu karşılar: + +``` +3 3 3 3 3 3 +``` + +Spesifikasyonu karşılasa da, kastedilen kesinlikle bu değil! Bu örnek, gerçek üretim kodundan alınan bir hataya dayanmaktadır (neyse ki yayınlanmadan önce yakalanmıştır), burada verilen dizi basit bir tuş vuruşu kayması veya anlık bir mantık hatası, tüm sonucun ilk öğeyle doldurulması için ayrıntılı bir mekanizmaya yol açmıştır. + +Tam son koşul, sonucun sıralanması ve orijinal değerlerin bir permütasyonuna sahip olmasıdır. Bu, gerekli davranışı uygun şekilde kısıtlar. Sonuç uzunluğunun, yıkamada çıkan giriş uzunluğu ile aynı olması ve yeniden ayarlanmasına gerek olmaması. + +Son koşulu tarif edilen şekilde belirtmek bile size iyi bir test vermek için yeterli değildir. İyi bir test okunabilir olmalıdır. Doğru (ya da değil) olduğunu kolayca görebileceğiniz kadar anlaşılır ve basit olmalıdır. Bir dizinin sıralandığını ve bir dizinin diğerinde bir değer permütasyonu içerdiğini kontrol etmek için halihazırda bir kodunuz yoksa, test kodunun test edilen koddan daha karmaşık olması muhtemeldir. Tony Hoare'nin gözlemlediği gibi: + +> Bir yazılım tasarımı oluşturmanın iki yolu vardır: Bir yol, onu *açıkça* hiçbir eksiklik olmayacak kadar basit hale getirmek, diğeri ise onu bariz eksiklikler olmayacak kadar karmaşık hale getirmektir. + +Somut örnekler kullanmak, bu tesadüfi karmaşıklığı ve kaza olasılığını ortadan kaldırır. Örneğin, aşağıdaki sıra verilir: + +``` +3 1 4 1 5 9 +``` + +Sıralamanın sonucu aşağıdaki gibidir: + +``` +1 1 3 4 5 9 +``` + +Başka hiçbir cevap işe yaramayacak. Yedek kabul etmeyin. + +Somut örnekler, genel davranışı erişilebilir ve açık bir şekilde göstermeye yardımcı olur. Boş bir koleksiyona öğe eklemenin sonucu, yalnızca boş olmaması değildir: Koleksiyonun artık tek bir öğeye sahip olmasıdır. Ve tutulan tek öğe, eklenen öğedir. İki veya daha fazla öğe boş değil olarak nitelendirilir. Ve ayrıca yanlış olurdu. Farklı bir değere sahip tek bir öğe de yanlış olur. Bir tabloya bir satır eklemenin sonucu sadece tablonun bir satır daha büyük olması değildir. Ayrıca, eklenen satırı kurtarmak için satırın anahtarının kullanılabileceğini de gerektirir. Ve benzeri. + +Davranışı belirlerken testler basitçe doğru olmamalıdır: Ayrıca kesin olmalıdırlar. + +[Kevlin Henney](http://programmer.97things.oreilly.com/wiki/index.php/Kevlin_Henney) Tarafından \ No newline at end of file diff --git a/tr/thing_82/README.md b/tr/thing_82/README.md new file mode 100644 index 00000000..0b91e6c6 --- /dev/null +++ b/tr/thing_82/README.md @@ -0,0 +1,15 @@ +# Uyurken (ve Hafta Sonları) Test Edin + +Rahatlayın. Açık deniz geliştirme merkezlerinden, hafta sonları fazla mesaiden veya gece vardiyasında çalışmaktan bahsetmiyorum. Bunun yerine, dikkatinizi elimizde ne kadar bilgi işlem gücüne sahip olduğumuza çekmek istiyorum. Spesifik olarak, programcılar olarak hayatımızı biraz daha kolaylaştırmak için ne kadarını kullanmadığımız. İş günü boyunca yeterli bilgi işlem gücü elde etmekte sürekli olarak zorlanıyor musunuz? Öyleyse, test sunucularınız normal çalışma saatleri dışında ne yapıyor? Çoğu zaman, test sunucuları gece boyunca ve hafta sonu boşta kalıyor. Bunu kendi avantajınıza kullanabilirsiniz. + +- *Tüm testleri çalıştırmadan bir değişiklik yaptığınız için suçlu mu oldunuz?* Programcıların kod işlemeden önce test takımlarını çalıştırmamalarının ana nedenlerinden biri, uzun zaman alabilecekleridir. Son teslim tarihleri yaklaştığında ve zorlama geldiğinde, insanlar doğal olarak köşeleri kesmeye başlar. Bunu çözmenin bir yolu, büyük test takımınızı iki veya daha fazla profile bölmektir. Hızlı çalıştırılabilen daha küçük, zorunlu bir test profili, testlerin her taahhütten önce çalıştırılmasını sağlamaya yardımcı olacaktır. Tüm test profilleri (zorunlu profil dahil - emin olmak için), gece boyunca çalışacak ve sabah sonuçlarını rapor etmeye hazır olacak şekilde otomatikleştirilebilir. + +- *Ürününüzün kararlılığını test etmek için yeterli fırsatınız oldu mu?* Daha uzun süren testler, bellek sızıntılarını ve diğer kararlılık sorunlarını belirlemek için hayati önem taşır. Zaman ve kaynakları bağlayacağı için nadiren gün içinde çalıştırılırlar. Gece boyunca ve hafta sonu boyunca biraz daha uzun süre çalıştırılacak bir ıslatma testini otomatikleştirebilirsiniz. Cuma günü 18:00'den bir sonraki Pazartesi günü saat 18:00'e kadar 60 saatlik potansiyel test süresi vardır. + +- *Performans testi ortamınızda kaliteli zaman alıyor musunuz?* Performans testi ortamında zaman kazanmak için birbirleriyle çekişen takımlar gördüm. Çoğu durumda, her iki takım da gün içinde yeterince kaliteli zaman geçiremezken, ortam saatler sonra neredeyse boşta kalır. Sunucular ve ağ, gece veya hafta sonu o kadar meşgul değil. Bazı kalite performans testleri yapmak için ideal bir zaman. + +- *Manuel olarak test etmek için çok fazla permütasyon var mı?* Çoğu durumda ürününüzün çeşitli platformlarda çalışması hedeflenir. Örneğin, hem 32 bit hem de 64 bit, Linux, Solaris ve Windows'ta veya yalnızca aynı işletim sisteminin farklı sürümlerinde. Daha da kötüsü, birçok modern uygulama kendilerini çok sayıda taşıma mekanizmasına ve protokolüne (HTTP, AMQP, SOAP, CORBA, vb.) Tüm bu permütasyonların manuel olarak test edilmesi çok zaman alıcıdır ve büyük olasılıkla kaynak baskısı nedeniyle bir sürüme yakın bir zamanda yapılır. Ne yazık ki, bazı hataları yakalamak için döngüde çok geç olabilir. + +Geceleri veya hafta sonları yapılan otomatik testler, tüm bu permütasyonların daha sık test edilmesini sağlayacaktır. Biraz düşünme ve biraz komut dosyası bilgisi ile, geceleri ve hafta sonu bazı testleri başlatmak için birkaç *cron* işi planlayabilirsiniz. Ayrıca yardımcı olabilecek birçok test aracı vardır. Hatta bazı kuruluşlar, kaynakların verimli bir şekilde kullanılmasını sağlamak için sunucuları farklı departmanlar ve ekipler arasında bir araya getiren sunucu ızgaralarına bile sahiptir. Bu, kuruluşunuzda mevcutsa, geceleri veya hafta sonları çalıştırılmak üzere testler gönderebilirsiniz. + +[Rajith Attapattu](http://programmer.97things.oreilly.com/wiki/index.php/Rajith_Attapattu) Tarafından \ No newline at end of file diff --git a/tr/thing_83/README.md b/tr/thing_83/README.md new file mode 100644 index 00000000..7004bcfa --- /dev/null +++ b/tr/thing_83/README.md @@ -0,0 +1,11 @@ +# Test, Yazılım Geliştirmenin Mühendislik Zorluğudur + +Geliştiriciler, aile üyelerine, eşlere ve diğer teknik olmayanlara ne yaptıklarını açıklamaya çalışırken işkence görmüş metaforları kullanmayı severler. Sıklıkla köprü inşasına ve diğer "zor" mühendislik disiplinlerine başvururuz. Tüm bu metaforlar, onları çok fazla zorlamaya başladığınızda hızla düşüyor. Yazılım geliştirmenin birçok önemli yönden "zor" mühendislik disiplinlerinin çoğu gibi *olmadığı* ortaya çıktı. + +"Zor" mühendislikle karşılaştırıldığında, yazılım geliştirme dünyası, ortak stratejinin bir köprü inşa etmek ve ardından üzerinde ağır bir şey yuvarlamak olduğu zamanki köprü inşaatçılarının bulunduğu yerdedir. Kalırsa, iyi bir köprüydü. Değilse, çizim tahtasına geri dönme zamanı. Son birkaç bin yılda mühendisler, ne yaptığını görmek için inşa etmek zorunda kalmadan yapısal bir çözüm için kullanabilecekleri matematik ve fizik geliştirdiler. Yazılımda böyle bir şeye sahip değiliz ve belki de asla olmayacak çünkü yazılım aslında çok farklı. Yazılım "mühendisliği" ile normal mühendislik arasındaki karşılaştırmanın derinlemesine bir incelemesi için, ["Yazılım Tasarımı Nedir?"](http://www.developerdotstar.com/mag/articles/reeves_design.html), Jack tarafından yazılmıştır. 1992'de *C++ Journal*'da yayınlanan Reeves, bir klasiktir. Neredeyse yirmi yıl önce yazılmış olmasına rağmen, yine de dikkate değer ölçüde doğrudur. Bu karşılaştırmada kasvetli bir tablo çizdi, ancak 1992'de eksik olan şey, yazılım için güçlü bir test etme anlayışıydı. + +"Zor" şeyleri test etmek zordur çünkü onları test etmek için inşa etmeniz gerekir, bu da sadece ne olacağını görmek için spekülatif yapıyı caydırır. Ancak yazılımdaki yapım süreci gülünç derecede ucuzdur. Bunu yapmayı kolaylaştıran eksiksiz bir araçlar ekosistemi geliştirdik: birim testi, sahte nesneler, test koşum takımları ve daha birçok şey. Diğer mühendisler, bir şeyler inşa etmeyi ve gerçekçi koşullar altında test etmeyi çok isterdi. Yazılım geliştiricileri olarak, yazılımın birincil (ancak tek değil) doğrulama mekanizması olarak testi benimsememiz gerekir. Yazılım için bir tür hesap beklemek yerine, iyi mühendislik uygulamalarını sağlamak için zaten elimizde araçlar var. Bu açıdan bakıldığında, "Test için zamanımız yok" diyen yöneticilere karşı artık mühimmatımız var. Bir köprü inşaatçısı patronundan asla "O bina üzerinde yapısal analiz yapmakla uğraşmayın - son teslim tarihimiz kısıtlı" diye bir şey duymaz. Testin gerçekten de yazılımda tekrarlanabilirlik ve kaliteye giden yol olduğunun kabul edilmesi, geliştiriciler olarak bize, profesyonel olarak sorumsuz olduğu için buna karşı çıkan argümanları geri itmemize izin veriyor. + +Yapısal analizin zaman alması gibi, test etme de zaman alır. Her iki faaliyet de nihai ürünün kalitesini garanti eder. Yazılım geliştiricilerin ürettikleri şeyin sorumluluğunu üstlenmelerinin zamanı geldi. Tek başına test etmek yeterli değildir, ancak gereklidir. * **Test etme** * yazılım geliştirmenin mühendislik titizliğidir. + +[Neal Ford](http://programmer.97things.oreilly.com/wiki/index.php/Neal_Ford) Tarafından \ No newline at end of file diff --git a/tr/thing_84/README.md b/tr/thing_84/README.md new file mode 100644 index 00000000..6e925682 --- /dev/null +++ b/tr/thing_84/README.md @@ -0,0 +1,39 @@ +# Durumlarda Düşünmek + +Gerçek dünyadaki insanların durumla tuhaf bir ilişkisi var. Bu sabah kafeini koda dönüştürmek için başka bir güne hazırlanmak için yerel mağazaya uğradım. Bunu yapmanın en sevdiğim yolu latte içmek olduğundan ve hiç süt bulamadığım için görevliye sordum. + +"Üzgünüm, süper kandırıldık, sütüm bitti." + +Bir programcı için bu garip bir ifade. Ya sütünüz bitmiştir ya da bitmemiştir. Sütün bitmesi söz konusu olduğunda ölçek yoktur. Belki de bana bir hafta sütlerinin biteceğini söylemeye çalışıyordu ama sonuç benim için aynıydı, espresso günü. + +Çoğu gerçek dünya durumunda, insanların duruma karşı rahat tavırları bir sorun değildir. Ne yazık ki, birçok programcı durum konusunda da oldukça belirsizdir ve bu bir problemdir. + +Bu yöntemi içeren bir `Order` sınıfıyla, yalnızca kredi kartlarını kabul eden ve müşterilere fatura kesmeyen basit bir web mağazasını düşünün: + +``` + public boolean isComplete() { + return isPaid() && hasShipped(); + } +``` + +Makul, değil mi? Eh, ifade her yere kopyala yapıştır yerine güzel bir şekilde bir yönteme ayıklansa bile, ifade hiç var olmamalıdır. Gerçek şu ki, bir sorunu vurgular. Niye? Çünkü bir sipariş, ödemesi yapılmadan kargoya verilemez. Bu nedenle, `isPaid` doğru olmadığı sürece `hasShipped` doğru olamaz, bu da ifadenin bir kısmını gereksiz kılar. Yine de kodda netlik için `isComplete` isteyebilirsiniz, ancak o zaman şöyle görünmelidir: + +``` + public boolean isComplete() { + return hasShipped(); + } +``` + +İşimde her zaman hem eksik hem de gereksiz çek görüyorum. Bu örnek küçük, ancak iptal ve geri ödemeyi eklediğinizde, daha karmaşık hale gelecek ve iyi durum işleme ihtiyacı artar. Bu durumda, bir sipariş yalnızca üç farklı durumdan birinde olabilir: + +- *Devam ediyor(In progress):* Öğe ekleyebilir veya kaldırabilir. Gönderilemiyor. +- *Ücretli(Paid):* Öğe eklenemez veya kaldırılamaz. Sevk edilebilir. +- *Gönderildi(Shipped):* Bitti. Daha fazla değişiklik kabul edilmedi. + +Bu durumlar önemlidir ve işlem yapmadan önce beklenen durumda olduğunuzu ve bulunduğunuz yerden sadece yasal bir duruma geçtiğinizi kontrol etmeniz gerekir. Kısacası eşyalarınızı dikkatli bir şekilde, doğru yerlerde korumalısınız. + +Ama durumlarda düşünmeye nasıl başlarsınız? İfadeleri anlamlı yöntemlere çıkarmak çok iyi bir başlangıç, ancak bu sadece bir başlangıç. Temel, durum makinelerini anlamaktır. CS sınıfından kötü anıların olabileceğini biliyorum ama onları geride bırak. Durum makineleri özellikle zor değildir. Kolay anlaşılır ve konuşulması kolay hale getirmek için onları görselleştirin. Geçerli ve geçersiz durumları ve geçişleri ortaya çıkarmak ve bunları doğru tutmak için kodunuzu test edin. Durum modelini inceleyin. Kendinizi rahat hissettiğinizde, Sözleşmeye Göre Tasarım'ı okuyun. Her genel yöntemin giriş ve çıkışında gelen verileri ve nesnenin kendisini doğrulayarak geçerli bir durum sağlamanıza yardımcı olur. + +Durumunuz yanlışsa, bir hata vardır ve iptal etmezseniz verileri çöpe atma riskiniz vardır. Durum kontrollerini parazit olarak bulursanız, bunları gizlemek için bir aracın, kod oluşturmanın, dokumanın veya yönlerin nasıl kullanılacağını öğrenin. Hangi yaklaşımı seçerseniz seçin, durumlar halinde düşünmek kodunuzu daha basit ve daha sağlam hale getirecektir. + +[Niclas Nilsson](http://programmer.97things.oreilly.com/wiki/index.php/Niclas_Nilsson) Tarafından \ No newline at end of file diff --git a/tr/thing_85/README.md b/tr/thing_85/README.md new file mode 100644 index 00000000..4803b7c9 --- /dev/null +++ b/tr/thing_85/README.md @@ -0,0 +1,23 @@ +# İki Kafa Çoğu Zaman Bir Kafadan Daha İyidir + +Programlama derin düşünce gerektirir ve derin düşünce yalnızlık gerektirir. Programcı klişesi de öyle. + +Programlamaya yönelik bu "yalnız kurt" yaklaşımı, yerini daha işbirlikçi bir yaklaşıma bırakıyor ve bunun da programcılar için kaliteyi, üretkenliği ve iş tatminini iyileştirdiğini iddia ediyorum. Bu yaklaşım, geliştiricilerin birbirleriyle ve ayrıca geliştirici olmayanlarla (iş ve sistem analistleri, kalite güvence uzmanları ve kullanıcılar) daha yakın çalışmasına sahiptir. + +Bu geliştiriciler için ne anlama geliyor? Uzman teknoloji uzmanı olmak artık yeterli değil. Başkalarıyla çalışmak konusunda etkili olmalısınız. + +İşbirliği, soru sorup cevaplamak veya toplantılarda oturmakla ilgili değildir. İşe ortaklaşa saldırmak için başka biriyle kolları sıvamakla ilgili. + +Çift programlamanın(pair programming) büyük bir hayranıyım. Buna "aşırı işbirliği" diyebilirsiniz. Bir geliştirici olarak, eşleştirme yaptığımda becerilerim artıyor. Alanda veya teknolojide, partnerimden daha zayıfsam, onun deneyimlerinden açıkça öğrenirim. Bir yönden daha güçlü olduğumda, kendimi açıklamak zorunda kalarak bildiklerim ve bilmediklerim hakkında daha fazla şey öğreniyorum. Her zaman ikimiz de masaya bir şeyler getiriyoruz ve birbirimizden öğreniyoruz. + +Eşleştirirken, her birimiz ortak programlama deneyimlerimizi teknik olduğu kadar etki alanı da eldeki soruna getiriyoruz ve etkin ve verimli bir şekilde yazılım yazmak için benzersiz bir anlayış ve deneyim getirebiliriz. Alan veya teknik bilgide aşırı dengesizlik durumlarında bile, daha deneyimli katılımcı her zaman diğerinden bir şeyler öğrenir, belki yeni bir klavye kısayolu veya yeni bir araç veya kitaplığa maruz kalma. Çiftin daha az deneyimli üyesi için bu, hız kazanmanın harika bir yoludur. + +Eşli programlama, çevik yazılım geliştirme savunucularına özel olmasa da popülerdir. Eşleştirmeye itiraz edenler, "Neden bir programcının işini yapması için iki programcıya para ödeyeyim?" diye soruyor. Benim yanıtım, aslında, yapmamalısın. Eşleştirmenin kaliteyi, etki alanı ve teknolojiyi, teknikleri (IDE hileleri gibi) artırdığını ve piyango riskinin etkisini azalttığını (uzman geliştiricilerinizden biri piyangoyu kazanır ve ertesi gün bırakır) savunuyorum. + +Yeni bir klavye kısayolu öğrenmenin uzun vadeli değeri nedir? Eşleştirmeden kaynaklanan üründeki genel kalite iyileştirmesini nasıl ölçeriz? Ortağınızın zor bir sorunu çözmek için çıkmaz bir yaklaşım izlemenize izin vermemesinin etkisini nasıl ölçeriz? Bir çalışma, etkinlik ve hızda %40'lık bir artış olduğunu belirtiyor (J T Nosek, "The Case for Collaborative Programming", *Communications of the ACM*, Mart 1998). "Piyango riskinizi" azaltmanın değeri nedir? Bu kazanımların çoğunu ölçmek zordur. + +Kim kiminle eşleşmeli? Ekipte yeniyseniz, bilgili bir ekip üyesi bulmak önemlidir. Kişilerarası ve koçluk becerileri iyi olan birini bulmak da aynı derecede önemlidir. Çok fazla alan deneyiminiz yoksa, alan adında uzman bir ekip üyesiyle eşleştirin. + +İkna değilseniz, deneyin: iş arkadaşlarınızla işbirliği yapın. İlginç bir problem üzerinde eşleştirin. Nasıl hissettirdiğini görün. Birkaç kez deneyin. + +[Adrian Wible](http://programmer.97things.oreilly.com/wiki/index.php/Adrian_Wible) Tarafından \ No newline at end of file diff --git a/tr/thing_86/README.md b/tr/thing_86/README.md new file mode 100644 index 00000000..3012c4a0 --- /dev/null +++ b/tr/thing_86/README.md @@ -0,0 +1,23 @@ +# İki Yanlış Bir Doğru Yapabilir (ve Düzeltilmesi Zordur) + +Kod asla yalan söylemez ama kendi kendisiyle çelişebilir. Bazı çelişkiler "Bu nasıl olabilir?" sorusuna yol açar. anlar. + +Bir [röportajda](http://www.netjeff.com/humor/item.cgi?file=ApolloComputer), Apollo 11 Ay Modülü yazılımının baş tasarımcısı Allan Klumpp, motorları kontrol eden yazılımın, iniş aracını kararsız hale getirmesi gereken bir hata içerdiğini açıkladı. Ancak, başka bir hata ilkini telafi etti ve yazılım, hata bulunmadan veya düzeltilmeden önce hem Apollo 11 hem de 12 Ay inişleri için kullanıldı. + +Bir tamamlanma durumu döndüren bir işlev düşünün. true döndürmesi gerektiğinde false döndürdüğünü hayal edin. Şimdi(now) çağıran fonksiyonun dönüş değerini kontrol etmeyi ihmal ettiğini hayal edin. Bir gün biri eksik çeki fark edip onu yerleştirene kadar her şey yolunda gider. + +Veya durumu bir XML belgesi olarak depolayan bir uygulamayı düşünün. Düğümlerden birinin, belgelerin olması gerektiği gibi, `TimeToDie` yerine `TimeToLive` olarak yanlış yazıldığını hayal edin. Hem yazar kodu hem de okuyucu kodu aynı hatayı içeriyorken her şey yolunda görünüyor. Ancak birini düzeltin veya aynı belgeyi okuyan yeni bir uygulama ekleyin ve simetri ve kod bozulur. + +Koddaki iki kusur, tek bir görünür hata oluşturduğunda, hataları düzeltmeye yönelik metodik yaklaşım kendi kendine çökebilir. Geliştirici bir hata raporu alır, hatayı bulur, düzeltir ve yeniden test eder. Bildirilen hata yine de ortaya çıkıyor, çünkü ikinci bir hata çalışıyor. Böylece ilk düzeltme kaldırılır, ikinci temel kusur bulunana kadar kod incelenir ve bunun için bir düzeltme uygulanır. Ancak ilk hata geri döndü, bildirilen hata hala görülüyor ve bu nedenle ikinci düzeltme geri alındı. Süreç tekrar ediyor, ancak şimdi geliştirici iki olası düzeltmeyi reddetti ve asla işe yaramayacak bir üçüncüsü yapmak istiyor. + +Görünür bir hata olarak görünen iki kod hatası arasındaki etkileşim, yalnızca sorunu çözmeyi zorlaştırmakla kalmaz, aynı zamanda geliştiricileri çıkmaz sokaklara sürükler, yalnızca doğru yanıtları erkenden denediklerini bulmak için. + +Bu sadece kodda olmaz: Sorun yazılı gereksinim belgelerinde de mevcuttur. Ve viral olarak bir yerden diğerine yayılabilir. Koddaki bir hata, yazılı açıklamadaki bir hatayı telafi eder. + +İnsanlara da yayılabilir: Kullanıcılar, uygulama Sol dediğinde Sağ anlamına geldiğini öğrenir ve davranışlarını buna göre ayarlar. Hatta bunu yeni kullanıcılara iletiyorlar: "Unutmayın, uygulamalar sol düğmeyi tıklayın diyorsa, bu gerçekten sağdaki düğme anlamına gelir." Hatayı düzeltin ve aniden kullanıcıların yeniden eğitilmesi gerekir. + +Tek bir yanlışın fark edilmesi ve düzeltilmesi kolay olabilir. Çözülmesi daha zor olan, birden çok nedeni olan, birden çok değişikliğe ihtiyaç duyan sorunlardır. Kısmen, kolay problemler o kadar kolay çözülür ki, insanlar onları nispeten hızlı bir şekilde düzeltmeye ve daha zor problemleri daha sonraki bir tarihe saklamaya eğilimlidir. + +Sempatik kusurlardan kaynaklanan arızaların nasıl ele alınacağı konusunda verilecek basit bir tavsiye yoktur. Olasılığın farkında olmak, açık bir kafa ve tüm olasılıkları değerlendirmeye istekli olmak gereklidir. + +[Allan Kelly](http://programmer.97things.oreilly.com/wiki/index.php/Allan_Kelly) Tarafından \ No newline at end of file diff --git a/tr/thing_87/README.md b/tr/thing_87/README.md new file mode 100644 index 00000000..36bc3f44 --- /dev/null +++ b/tr/thing_87/README.md @@ -0,0 +1,15 @@ +# Arkadaşlarınız İçin Ubuntu Kodlama + +Sıklıkla kodu ayrı ayrı yazarız ve kod, çok kişiselleştirilmiş bir çözümün yanı sıra bir soruna ilişkin kişisel yorumumuzu da yansıtır. Ekibin bir parçası olabiliriz, ancak ekip olarak izole edilmiş durumdayız. Ayrı ayrı oluşturulan bu kodun başkaları tarafından yürütüleceğini, kullanılacağını, genişletileceğini ve güvenileceğini çok kolay unutuyoruz. Yazılım oluşturmanın sosyal yönünü gözden kaçırmak kolaydır. Yazılım oluşturmak, sosyal bir alıştırmayla karıştırılmış teknik bir alıştırmadır. Tek başına çalışmadığımızı anlamak için başımızı daha sık kaldırmamız gerekiyor ve sadece geliştirme ekibi için değil herkes için başarı olasılığını artırma konusunda ortak sorumluluğumuz var. + +Kendi içinde kaybolurken, izolasyonda kaliteli kod yazabilirsiniz. Bir perspektiften, bu benmerkezci bir yaklaşımdır (kibirli olduğu gibi *ego* değil, kişisel olduğu gibi *ego*). Aynı zamanda bir Zen görünümüdür ve kod oluşturma anında sizinle ilgilidir. Her zaman anı yaşamaya çalışıyorum çünkü bu benim iyi kaliteye yaklaşmama yardımcı oluyor ama sonra *benim* anımda yaşıyorum. Peki ya ekibimin anı? Benim anım takımın anıyla aynı mı? + +Zulu'da Ubuntu felsefesi, kabaca "Bir kişi (diğer) kişiler aracılığıyla bir kişidir" anlamına gelen "Umuntu ngumuntu ngabantu" olarak özetlenir. İyileşiyorum çünkü beni iyi davranışlarınla iyileştiriyorsun. Diğer tarafı, yaptığım şeyde kötü olduğumda yaptığın şeyde daha da kötüleşiyorsun. Geliştiriciler arasında, bunu "Bir geliştirici (diğer) geliştiriciler aracılığıyla bir geliştiricidir" şeklinde daraltabiliriz. Metale indirirsek, "Kod (diğer) kod aracılığıyla koddur." + +Yazdığım kodun kalitesi yazdığınız kodun kalitesini etkiler. Ya kodum kalitesiz ise? Çok temiz kod yazsanız bile, kodumu kullandığınız noktalar, kod kalitenizin benim kodumun kalitesine yakın düşecektir. Hasarı sınırlamak için birçok desen ve teknik uygulayabilirsiniz, ancak hasar zaten yapılmıştır. Sırf anımı yaşarken seni düşünmediğim için yapman gerekenden fazlasını yapmana sebep oldum. + +Kodumun temiz olduğunu düşünebilirim, ancak yine de sadece Ubuntu kodlamasıyla daha iyi hale getirebilirim. Ubuntu kodu neye benziyor? Sadece iyi temiz kod gibi görünüyor. Bu kodla, yapaylıkla ilgili değil. Bu, o eseri yaratma eylemiyle ilgilidir. Ubuntu ile arkadaşlarınız için kodlama yapmak, ekibinizin değerlerinizi yaşamasına ve ilkelerinizi pekiştirmesine yardımcı olacaktır. Her ne şekilde olursa olsun kodunuza dokunan bir sonraki kişi daha iyi bir insan ve daha iyi bir geliştirici olacaktır. + +Zen bireyle ilgilidir. Ubuntu, bir grup insan için Zen ile ilgilidir. Çok, çok nadiren sadece kendimiz için kod oluşturuyoruz. + +[Aslam Khan](http://programmer.97things.oreilly.com/wiki/index.php/Aslam_Khan) Tarafından \ No newline at end of file diff --git a/tr/thing_88/README.md b/tr/thing_88/README.md new file mode 100644 index 00000000..3af987a0 --- /dev/null +++ b/tr/thing_88/README.md @@ -0,0 +1,31 @@ +# Unix Araçları Arkadaşlarınızdır + +Issız bir adaya sürgüne giderken bir IDE ile Unix araç kutusu arasında seçim yapmak zorunda kalsaydım, hiç düşünmeden Unix araçlarını seçerdim. İşte Unix araçları konusunda uzman olmanız için nedenler. + +Birincisi, IDE'ler belirli dilleri hedeflerken, Unix araçları metin biçiminde görünen her şeyle çalışabilir. Her yıl yeni dillerin ve notasyonların ortaya çıktığı günümüzün geliştirme ortamında, Unix tarzında çalışmayı öğrenmek, her zaman karşılığını verecek bir yatırımdır. + +Ayrıca, IDE'ler yalnızca geliştiricilerinin tasarladığı komutları sunarken, Unix araçlarıyla hayal edebileceğiniz her görevi gerçekleştirebilirsiniz. Bunları (klasik Pre-Bionicle) Lego blokları olarak düşünün: Küçük ama çok yönlü Unix araçlarını birleştirerek kendi komutlarınızı yaratırsınız. Örneğin, aşağıdaki sıra, Cunningham'ın imza analizinin metin tabanlı bir uygulamasıdır, dosyanın içeriği hakkında çok şey ortaya çıkarabilen her dosyanın noktalı virgül, parantez ve tırnaklardan oluşan bir dizi. + +``` +for i in *.java; do + echo -n "$i: " + sed 's/[^"{};]//g' $i | tr -d '\n' + echo +done +``` + +Ayrıca öğrendiğiniz her IDE işlemi o göreve özeldir; örneğin, bir projenin hata ayıklama derleme yapılandırmasına yeni bir adım eklemek. Buna karşılık, Unix araç becerilerinizi geliştirmek sizi her görevde daha etkili kılar. Örnek olarak, birden çok işlemci mimarisinde çapraz derleme için bir projenin yapısını değiştirmek için önceki komut dizisinde kullanılan sed aracını kullandım. + +Unix araçları, çok kullanıcılı bir bilgisayarın 128 kB RAM'e sahip olduğu bir çağda geliştirildi. Tasarımlarındaki ustalık, günümüzde devasa veri kümelerini son derece verimli bir şekilde işleyebilecekleri anlamına geliyor. Çoğu araç, filtreler gibi çalışır ve aynı anda yalnızca tek bir satırı işleyerek işleyebilecekleri veri miktarında bir üst sınır olmadığı anlamına gelir. Yarım terabaytlık İngilizce Wikipedia dökümünde saklanan düzenleme sayısını mı aramak istiyorsunuz? Basit bir çağırma + +``` +grep '' | wc –l +``` + +cevabı ter dökmeden verecektir. Bir komut dizisini genel olarak yararlı bulursanız, verileri döngülere ve koşullara aktarma gibi bazı benzersiz güçlü programlama yapılarını kullanarak onu kolayca bir shell komut dosyasında paketleyebilirsiniz. Daha da etkileyici bir şekilde, önceki gibi ardışık düzen olarak yürütülen Unix komutları, yüklerini modern çok çekirdekli CPU'ların birçok işlem birimi arasında doğal olarak dağıtacaktır. + +Unix araçlarının küçük güzeldir kaynağı ve açık kaynak uygulamaları, set üstü medya oynatıcım veya DSL yönlendiricim gibi kaynakları kısıtlı platformlarda bile onları her yerde kullanılabilir hale getirir. Bu tür cihazların güçlü bir grafik kullanıcı arabirimi sunmaları pek olası değildir, ancak genellikle en yaygın kullanılan araçları sağlayan BusyBox uygulamasını içerirler. Ve Windows üzerinde geliştirme yapıyorsanız, Cygwin ortamı size hem yürütülebilir dosyalar olarak hem de kaynak kodu biçiminde akla gelebilecek tüm Unix araçlarını sunar. + +Son olarak, mevcut araçlardan hiçbiri ihtiyaçlarınızı karşılamıyorsa, Unix araçlarının dünyasını genişletmek çok kolaydır. Sadece birkaç basit kurala göre oynayan bir program yazın (istediğiniz herhangi bir dilde): Programınız sadece tek bir görevi yerine getirmelidir; verileri standart girdisinden metin satırları olarak okumalıdır; ve sonuçlarını standart çıktısında başlıklar ve diğer gürültüler tarafından süslenmeden göstermelidir. Aracın çalışmasını etkileyen parametreler komut satırında verilmiştir. Bu kuralları takip edin ve "Dünya ve içindeki her şey sizindir". + +[Diomidis Spinellis](http://programmer.97things.oreilly.com/wiki/index.php/Diomidis_Spinellis) Tarafından \ No newline at end of file diff --git a/tr/thing_89/README.md b/tr/thing_89/README.md new file mode 100644 index 00000000..067d4243 --- /dev/null +++ b/tr/thing_89/README.md @@ -0,0 +1,37 @@ +# Doğru Algoritmayı ve Veri Yapısını Kullanın + +> Çok sayıda şubesi olan büyük bir banka, veznedarlar için aldığı yeni bilgisayarların çok yavaş olduğundan şikayet etti. Bu, herkesin elektronik bankacılık kullandığı ve ATM'lerin şimdiki kadar yaygın olmadığı zamanlardaydı. İnsanlar bankayı çok daha sık ziyaret ediyorlardı ve yavaş bilgisayarlar insanları sıraya sokuyordu. Sonuç olarak, banka satıcıyla olan sözleşmesini bozmakla tehdit etti. + +> Satıcı, gecikmelerin nedenini belirlemek için bir performans analizi ve ayar uzmanı gönderdi. Kısa süre sonra, terminalde çalışan ve neredeyse tüm CPU kapasitesini tüketen belirli bir program buldu. Bir profil oluşturma aracı kullanarak programı yakınlaştırdı ve suçlu olan işlevi görebildi. Kaynak kodu okuyun: + +> ``` +> for (i=0; i if (... s[i] ...) ... +> } +> ``` + +> Ve string s ortalama olarak binlerce karakter uzunluğundaydı. (Banka tarafından yazılan) kod çabucak değiştirildi ve banka veznedarları sonsuza dek mutlu yaşadılar.... + +Programcının gereksiz yere ikinci dereceden ölçeklenen kodu kullanmaktan daha iyisini yapması gerekmez miydi? +strlen'e yapılan her çağrı, sonlandırıcı boş karakterini bulmak için dizgedeki binlerce karakterin her birini geçti. Ancak dizi hiç değişmedi. Programcı, uzunluğunu önceden belirleyerek, strlen'e binlerce çağrıyı (ve milyonlarca döngü yürütmesini) kaydedebilirdi: + +``` +n=strlen(s); +for (i=0; i allCustomers = new ArrayList(); + // ... + public ArrayList findCustomersThatSpendAtLeast(Money amount) { + ArrayList customersOfInterest = new ArrayList(); + for (Customer customer: allCustomers) { + if (customer.spendsAtLeast(amount)) + customersOfInterest.add(customer); + } + return customersOfInterest; + } +} +``` + +Bu ham koleksiyonu client'lara göstererek, kapsüllemeyi ihlal ettik. Bu, yalnızca yeniden düzenleme yeteneğimizi sınırlamakla kalmaz, kodumuzu kullananların her birinin potansiyel olarak aynı sorguyu yeniden uygulamasını sağlayarak DRY'yi ihlal etmeye zorlar. Bu durum, açıkta kalan ham koleksiyonları API'den kaldırarak kolayca önlenebilir. Bu örnekte, `CustomerList` adlı yeni, alana özgü bir toplu tür tanıtabiliriz. Bu yeni sınıf, alanımızla daha semantik olarak uyumludur. Tüm sorularımız için doğal bir yuva görevi görecek. + +Bu yeni koleksiyon türüne sahip olmak, bu sorguların performans darboğazı olup olmadığını kolayca görmemizi sağlayacaktır. Sorguları sınıfa dahil ederek, `ArrayList` gibi temsil seçeneklerini müşterilerimize gösterme ihtiyacını ortadan kaldırıyoruz. Bu bize, client sözleşmelerini ihlal etme korkusu olmadan bu uygulamaları değiştirme özgürlüğü verir: + +``` +public class CustomerList { + private ArrayList customers = new ArrayList(); + private SortedList customersSortedBySpendingLevel = new SortedList(); + // ... + public CustomerList findCustomersThatSpendAtLeast(Money amount) { + return new CustomerList(customersSortedBySpendingLevel.elementsLargerThan(amount)); + } +} + +public class UsageExample { + public static void main(String[] args) { + CustomerList customers = new CustomerList(); + // ... + CustomerList customersOfInterest = customers.findCustomersThatSpendAtLeast(someMinimalAmount); + // ... + } +} +``` + +Bu örnekte, DRY'ye bağlılık, client'larımıızın harcama düzeyine göre ayarlanmış SortedList ile alternatif bir indeksleme şeması sunmamıza izin verdi. Bu özel örneğin belirli ayrıntılarından daha önemli olan, DRY'yi takip etmek, kodun WET olması durumunda bulunması daha zor olacak bir performans darboğazı bulmamıza ve onarmamıza yardımcı oldu. + +[Kirk Pepperdine](http://programmer.97things.oreilly.com/wiki/index.php/Kirk_Pepperdine) Tarafından \ No newline at end of file diff --git a/tr/thing_92/README.md b/tr/thing_92/README.md new file mode 100644 index 00000000..6a254d2a --- /dev/null +++ b/tr/thing_92/README.md @@ -0,0 +1,13 @@ +# Programcılar ve Test Uzmanları İşbirliği Yaptığında + +Testçiler ve programcılar işbirliği yapmaya başladığında sihirli bir şey olur. Hata izleme sistemi aracılığıyla hataları ileri geri göndermek için daha az zaman harcanır. Bir şeyin gerçekten bir hata mı yoksa yeni bir özellik mi olduğunu anlamaya çalışmak için daha az zaman harcanır ve müşteri beklentilerini karşılamak için iyi bir yazılım geliştirmek için daha fazla zaman harcanır. Kodlama başlamadan önce işbirliğine başlamak için birçok fırsat vardır. + +Test kullanıcıları, Fit (Framework for Integrated Test - Entegre Test için Çerçeve) gibi araçlarla müşterilerin kendi alanlarının dilini kullanarak kabul testleri yazmasına ve otomatikleştirmesine yardımcı olabilir. Bu testler programcılara kodlama başlamadan önce verildiğinde, ekip Kabul Testine Dayalı Geliştirme (Acceptance Test Driven Development - ATDD) uyguluyor. Programcılar testleri çalıştırmak için fikstürleri yazar ve ardından testleri geçmek için kod yazar. Bu testler daha sonra regresyon paketinin bir parçası haline gelir. Bu işbirliği gerçekleştiğinde, işlevsel testler erken tamamlanır ve uç koşullarda veya daha büyük resmin iş akışları aracılığıyla keşif testleri için zaman tanır. + +Bir adım daha ileri götürebiliriz. Bir testçi olarak, test fikirlerimin çoğunu programcılar yeni bir özelliği kodlamaya başlamadan önce sağlayabilirim. Programcılara herhangi bir önerileri olup olmadığını sorduğumda, neredeyse her zaman bana daha iyi test kapsamı konusunda yardımcı olan veya gereksiz testlere çok fazla zaman harcamaktan kaçınmama yardımcı olan bilgileri sağlıyorlar. Testler ilk fikirlerin çoğunu netleştirdiği için genellikle kusurları önledik. Örneğin, üzerinde çalıştığım bir projede, programcılara verdiğim Uyum testleri, bir joker karakter aramasına yanıt vermek için bir sorgunun beklenen sonuçlarını gösteriyordu. Programcı tamamen yalnızca tam kelime aramalarını kodlamayı amaçlamıştı. Kodlamaya başlamadan önce müşteri ile konuşup doğru yorumu tespit edebildik. İşbirliği yaparak, ikimizi de çok fazla zaman kaybından kurtaran kusuru önledik. + +Programcılar, başarılı otomasyon oluşturmak için test uzmanlarıyla da işbirliği yapabilir. İyi kodlama uygulamalarını anlarlar ve test uzmanlarının tüm ekip için çalışan sağlam bir test otomasyon paketi oluşturmasına yardımcı olabilirler. Testler kötü tasarlanmış olduğu için test otomasyon projelerinin başarısız olduğunu sık sık gördüm. Testler çok fazla test etmeye çalışıyor veya testçiler, testleri bağımsız tutabilmek için teknoloji hakkında yeterince bilgi sahibi değiller. Test cihazları genellikle darboğazdır, bu nedenle programcıların otomasyon gibi görevlerde onlarla çalışması mantıklıdır. Neyin erkenden test edilebileceğini anlamak için testçilerle birlikte çalışmak, belki de basit bir araç sağlayarak, programcılara uzun vadede daha iyi kod sunmalarına yardımcı olacak başka bir geri bildirim döngüsü sağlayacaktır. + +Testçiler, tek görevlerinin yazılımı kırmak ve programcıların kodunda hatalar bulmak olduğunu düşünmeyi bıraktığında, programcılar, testçilerin `onları elde etmeye hazır` olduklarını düşünmeyi bırakırlar ve işbirliğine daha açık olurlar. Programcılar, kodlarında kalite oluşturmaktan sorumlu olduklarını fark etmeye başladıklarında, kodun test edilebilirliği doğal bir yan üründür ve ekip birlikte daha fazla regresyon testini otomatikleştirebilir. Başarılı ekip çalışmasının büyüsü başlar. + +[Janet Gregory](http://programmer.97things.oreilly.com/wiki/index.php/Janet_Gregory) Tarafından \ No newline at end of file diff --git a/tr/thing_93/README.md b/tr/thing_93/README.md new file mode 100644 index 00000000..c765b6f0 --- /dev/null +++ b/tr/thing_93/README.md @@ -0,0 +1,13 @@ +# Hayatınız Boyunca Desteklemek Zorundaymışsınız Gibi Kod Yazın + +97 kişiye her programcının ne bilmesi ve yapması gerektiğini sorabilir ve 97 farklı cevap duyabilirsiniz. Bu aynı anda hem ezici hem de korkutucu olabilir. Tüm tavsiyeler iyidir, tüm ilkeler sağlamdır ve tüm hikayeler ikna edicidir, ancak nereden başlamalı? Daha da önemlisi, bir kez başladığınızda, öğrendiğiniz tüm en iyi uygulamalara nasıl ayak uydurursunuz ve bunları programlama uygulamanızın ayrılmaz bir parçası haline nasıl getirirsiniz? + +Bence cevap sizin düşünce yapınızda ya da daha açık bir ifadeyle tavrınızda yatıyor. Diğer geliştiricilerinizi, test uzmanlarınızı, yöneticilerinizi, satış ve pazarlama görevlilerinizi ve son kullanıcıları umursamıyorsanız, örneğin, Test Odaklı Geliştirme kullanmaya veya kodunuza net yorumlar yazmaya yönlendirilmezsiniz. Tutumunuzu ayarlamanın ve her zaman en kaliteli ürünleri sunmaya yönelmenin basit bir yolu olduğunu düşünüyorum: + +> *Hayatınız Boyunca Desteklemek Zorundaymışsınız Gibi Kod Yazın.* + +Bu kadar. Bu fikri kabul ederseniz, birçok harika şey olacak. Önceki veya mevcut işverenlerinizden herhangi birinin gecenin bir yarısı sizi arayıp fooBar yöntemini yazarken yaptığınız seçimleri açıklamanızı isteme hakkına sahip olduğunu kabul etseydiniz, yavaş yavaş uzman bir programcı olma yolunda ilerlersiniz. Doğal olarak daha iyi değişken ve yöntem adları bulmak istersiniz. Yüzlerce satırdan oluşan kod bloklarından uzak durursunuz. Tasarım kalıplarını arar, öğrenir ve kullanırsınız. Sürekli olarak yorum yazar, kodunuzu test eder ve yeniden düzenlersiniz. Hayatınızın geri kalanında yazdığınız tüm kodları desteklemek de ölçeklenebilir bir çaba olmalıdır. Bu nedenle daha iyi, daha akıllı ve daha verimli olmaktan başka seçeneğiniz kalmaz. + +Üzerinde düşünürseniz, yıllar önce yazdığınız kod, beğenseniz de beğenmeseniz de kariyerinizi etkiler. Tasarladığınız ve yazdığınız her yöntem ve sınıf ve modül ile bilginizin, tavrınızın, aziminizin, profesyonelliğinizin, bağlılık seviyenizin ve keyif derecenizin izini bırakıyorsunuz. İnsanlar gördükleri koda göre sizin hakkınızda fikir oluşturacaklar. Bu görüşler sürekli olumsuz ise, kariyerinizden umduğunuzdan daha az şey elde edeceksiniz. Her kod satırıyla kariyerinize, müşterilerinize ve kullanıcılarınıza iyi bakın ve Hayatınız Boyunca Desteklemek Zorundaymışsınız Gibi Kod Yazın. + +[Yuriy Zubarev](http://programmer.97things.oreilly.com/wiki/index.php/Yuriy_Zubarev) Tarafından \ No newline at end of file diff --git a/tr/thing_94/README.md b/tr/thing_94/README.md new file mode 100644 index 00000000..d6592e27 --- /dev/null +++ b/tr/thing_94/README.md @@ -0,0 +1,26 @@ +# Örnekleri Kullanarak Küçük Fonksiyonlar Yazın + +Doğru olan bir kod yazmak istiyoruz ve bunun doğru olduğuna dair elimizde kanıt var. Bir fonksiyonun "boyutu" hakkında düşünmek her iki konuda da yardımcı olabilir. Bir işlevi uygulayan kod miktarı anlamında değil bu ilginç olsa da daha çok kodumuzun gösterdiği matematiksel işlevin boyutu anlamında. + +Örneğin, Go oyununda *atari* adı verilen ve oyuncunun taşlarının rakibi tarafından ele geçirilebileceği bir koşul vardır: Yanında iki veya daha fazla boş alan bulunan bir taş (*liberties* olarak adlandırılır) ataride değildir. Bir taşın ne kadar özgürlüğe sahip olduğunu saymak zor olabilir, ancak bu biliniyorsa atariyi belirlemek kolaydır. Bunun gibi bir fonksiyon yazarak başlayabiliriz: + +``` +boolean atari(int libertyCount) + libertyCount < 2 +``` + +Bu göründüğünden daha büyüktür. Matematiksel bir fonksiyon, bir küme, etki alanı (burada `int`) ve aralık (burada `boolean`) olan kümelerin Kartezyen çarpımının bir alt kümesi olarak anlaşılabilir. Bu değer kümeleri Java'dakiyle aynı boyutta olsaydı, `int×boolean` kümesinde `2L*(Integer.MAX_VALUE+(-1L*Integer.MIN_VALUE)+1L)` veya 8.589.934.592 üye olurdu. Bunların yarısı, işlevimiz olan alt kümenin üyeleridir, bu nedenle işlevimizin doğru olduğuna dair tam kanıt sağlamak için yaklaşık 4,3×109 örneği kontrol etmemiz gerekir. + +Testlerin hataların yokluğunu kanıtlayamayacağı iddiasının özü budur. Yine de testler, özelliklerin varlığını gösterebilir. Ama yine de bu boyut sorunumuz var. + +Sorun alanı bize yardımcı olur. Go'nun doğası, bir taşın özgürlük sayısının herhangi bir int değil, tam olarak {1,2,3,4}'den biri olduğu anlamına gelir. Yani alternatif olarak şunu yazabiliriz: + +``` +LibertyCount = {1,2,3,4} +boolean atari(LibertyCount libertyCount) + libertyCount == 1 +``` + +Bu çok daha izlenebilir: Hesaplanan fonksiyon artık en fazla sekiz üyeden oluşan bir kümedir. Aslında, kontrol edilen dört örnek, işlevin doğru olduğuna dair tam bir kesinlik kanıtı teşkil edecektir. Program yazmak için yerel türler yerine sorun alanıyla yakından ilgili türleri kullanmanın iyi bir fikir olmasının bir nedeni budur. Etki alanından ilham alan türleri kullanmak genellikle işlevlerimizi çok daha küçük hale getirebilir. Bu türlerin ne olması gerektiğini bulmanın bir yolu, işlevi yazmadan önce sorunlu etki alanı terimlerini kontrol etmek için örnekler bulmaktır. + +[Keith Braithwaite](http://programmer.97things.oreilly.com/wiki/index.php/Keith_Braithwaite) Tarafından \ No newline at end of file diff --git a/tr/thing_95/README.md b/tr/thing_95/README.md new file mode 100644 index 00000000..3699d758 --- /dev/null +++ b/tr/thing_95/README.md @@ -0,0 +1,15 @@ +# İnsanlar için Testler Yaz + +Üretim kodunuzun bir kısmı veya tamamı için otomatik testler yazıyorsunuz. Tebrikler! Testlerinizi kodu yazmadan önce mi yazıyorsunuz? Daha iyi!! Bunu yapmak bile sizi yazılım mühendisliği uygulamalarının öncülerinden ilk benimseyenlerden biri yapar. Ama iyi testler mi yazıyorsun? Nasıl söyleyebilirsin? Bunun bir yolu "Testleri kimin için yazıyorum?" diye sormaktır. Cevap "Benim için, hataları düzeltme zahmetinden kurtarmak için" veya "Derleyici için, böylece çalıştırılabilmeleri için" ise, o zaman olası en iyi testleri yazmıyorsunuzdur. Peki testleri *kimin* için yazmalısınız? Kodunuzu anlamaya çalışan kişi için. + +İyi testler, test ettikleri kod için belge görevi görür. Kodun nasıl çalıştığını açıklarlar. Her kullanım senaryosu için test(ler): + +1. Karşılanması gereken bağlamı, başlangıç noktasını veya ön koşulları tanımlayın +2. Yazılımın nasıl çağrıldığını gösterin +3. Beklenen sonuçları veya doğrulanacak son koşulları tanımlayın + +Farklı kullanım senaryoları, bunların her birinin biraz farklı versiyonlarına sahip olacaktır. Kodunuzu anlamaya çalışan kişinin birkaç teste bakabilmesi ve söz konusu testlerin bu üç bölümünü karşılaştırarak yazılımın farklı davranmasına neyin sebep olduğunu görebilmesi gerekir. Her test, bu üç kısım arasındaki neden-sonuç ilişkisini açıkça göstermelidir. Bu, testte görünmeyenlerin görünenler kadar önemli olduğu anlamına gelir. Testte çok fazla kod, okuyucunun önemsiz önemsiz şeylerle dikkatini dağıtır. Mümkün olduğunda, bu tür önemsiz şeyleri anlamlı yöntem çağrılarının arkasına saklayın - Extract Method yeniden düzenleme en iyi arkadaşınızdır. Ve her teste, belirli kullanım senaryosunu açıklayan anlamlı bir ad verdiğinizden emin olun, böylece test okuyucusu, çeşitli senaryoların ne olduğunu anlamak için her testi tersine mühendislik yapmak zorunda kalmaz. Bunların arasında, test sınıfının ve sınıf yönteminin adları, en azından başlangıç ​​noktasını ve yazılımın nasıl çağrıldığını içermelidir. Bu, yöntem adlarının hızlı bir şekilde taranması yoluyla test kapsamının doğrulanmasını sağlar. Ayrıca, isimlerin görülmesi veya okunması çok uzun sürmediği sürece, beklenen sonuçların test yöntemi adlarına dahil edilmesi faydalı olabilir. + +Testlerinizi test etmek de iyi bir fikirdir. Tespit ettiklerini düşündüğünüz hataları, bu hataları üretim koduna ekleyerek doğrulayabilirsiniz (elbette atacağınız kendi özel kopyanız). Hataları yararlı ve anlamlı bir şekilde bildirdiklerinden emin olun. Ayrıca testlerinizin kodunuzu anlamaya çalışan bir kişiyle net bir şekilde konuştuğunu doğrulamanız gerekir. Bunu yapmanın tek yolu, kodunuza aşina olmayan birinin testlerinizi okumasını ve ne öğrendiğini size söylemesini sağlamaktır. Ne dediklerini dikkatlice dinleyin. Bir şeyi net bir şekilde anlamadılarsa, muhtemelen çok parlak olmadıkları için değildir. Çok net olmamanız daha olasıdır. (Devam edin ve testlerini okuyarak rolleri tersine çevirin!) + +by [Gerard Meszaros](http://programmer.97things.oreilly.com/wiki/index.php/Gerard_Meszaros) diff --git a/tr/thing_96/README.md b/tr/thing_96/README.md new file mode 100644 index 00000000..de464009 --- /dev/null +++ b/tr/thing_96/README.md @@ -0,0 +1,23 @@ +# Kodu Önemsemelisiniz + +İyi programcıların iyi kod yazdığını anlamak için Sherlock Holmes'a gerek yok. Kötü programcılar... yapma. Geri kalanımızın temizlemesi gereken canavarlıklar üretiyorlar. İyi şeyler yazmak istiyorsun, değil mi? İyi bir programcı olmak istiyorsun. + +İyi kod birdenbire ortaya çıkmaz. Gezegenler hizalandığında şans eseri olan bir şey değil. İyi kod almak için üzerinde çalışmanız gerekir. Zordur ve yalnızca iyi kodu gerçekten önemsiyorsanız iyi kod alırsınız. + +İyi programlama sadece teknik yeterlilikten doğmaz. Yoğun ve etkileyici algoritmalar üretebilen, dil standartlarını ezbere bilen, ancak en korkunç kodu yazan son derece entelektüel programcılar gördüm. Okuması acı verici, kullanması acı verici ve değiştirmesi acı verici. Çok basit kodlara bağlı kalan, ancak birlikte çalışmaktan zevk alan zarif ve etkileyici programlar yazan daha mütevazı programcılar gördüm. + +Yazılım fabrikasında uzun yıllara dayanan deneyimime dayanarak, yeterli programcılar ile harika programcılar arasındaki gerçek farkın şu olduğu sonucuna vardım: *tutum*. İyi programlama, profesyonel bir yaklaşım benimsemekte ve yazılım fabrikasının Gerçek Dünya kısıtlamaları ve baskıları dahilinde yapabileceğiniz en iyi yazılımı yazmayı istemekte yatar. + +*Cehennemin şifresi iyi niyetlerle döşenmiştir.* Mükemmel bir programcı olmak için iyi niyetlerin üzerine çıkmanız ve aslında kodu *önemsemeniz* gerekir, olumlu bakış açıları geliştirmeniz ve sağlıklı tutumlar geliştirmeniz gerekir. Büyük kod, usta zanaatkarlar tarafından özenle hazırlanır, özensiz programcılar tarafından düşüncesizce hacklenmez veya kendi kendini kanıtlamış kodlama guruları tarafından gizemli bir şekilde dikilmez. + +İyi kod yazmak istiyorsunuz. İyi bir programcı olmak istiyorsun. Yani, kodu önemsiyorsun: + +- Herhangi bir kodlama durumunda, yalnızca işe yarıyor gibi görünen bir şeyi hacklemeyi reddediyorsunuz. Açıkça doğru olan (ve bunun doğru olduğunu gösteren iyi testleri olan) zarif bir kod oluşturmaya çalışıyorsunuz. +- *Keşfedilebilir* (diğer programcıların kolayca alıp anlayabileceği), yani *sürdürülebilir* (sizin veya diğer programcıların gelecekte kolayca değiştirebilecekleri) kod yazarsınız ve bu doğrudur ( sorunu çözdüğünü belirlemek için mümkün olan tüm adımları atarsın, sadece programın çalışıyor gibi görünmesini sağlamakla kalmazsın). +- Diğer programcılarla birlikte iyi çalışıyorsunuz. Hiçbir programcı bir ada değildir. Birkaç programcı tek başına çalışır; çoğu şirket ortamında veya açık kaynaklı bir projede programcılardan oluşan bir ekipte çalışır. Diğer programcıları düşünür ve başkalarının okuyabileceği kodlar oluşturursunuz. Kendinizi zeki göstermek yerine ekibin mümkün olan en iyi yazılımı yazmasını istiyorsunuz. +- Bir kod parçasına her dokunduğunuzda, onu bulduğunuzdan daha iyi bırakmaya çalışırsınız (ya daha iyi yapılandırılmış, daha iyi test edilmiş, daha anlaşılır...). +- Kodlamaya ve programlamaya önem veriyorsunuz, dolayısıyla sürekli yeni diller, deyimler ve teknikler öğreniyorsunuz. Ancak bunları yalnızca uygun olduğunda uygularsınız. + +Neyse ki, bu tavsiye koleksiyonunu okuyorsunuz çünkü koda önem veriyorsunuz. Seni ilgilendiriyor. Bu senin tutkun. İyi programlamalar. Zor problemleri çözmek için kod kesmenin tadını çıkarın. Sizi gururlandıran yazılımlar üretin. + +[Pete Goodliffe](http://programmer.97things.oreilly.com/wiki/index.php/Pete_Goodliffe) Tarafından \ No newline at end of file diff --git a/tr/thing_97/README.md b/tr/thing_97/README.md new file mode 100644 index 00000000..ec9a32b5 --- /dev/null +++ b/tr/thing_97/README.md @@ -0,0 +1,13 @@ +# Müşterileriniz Ne Dediklerini Kastetmez + +Henüz bana ne istediğini söylemekten pek memnun olmayan bir müşteriyle hiç tanışmadım, genellikle çok ayrıntılı. Sorun şu ki, müşteriler size her zaman tüm gerçeği söylemezler. Genellikle yalan söylemezler, ancak geliştirici konuşmasında değil, müşteri konuşmasında konuşurlar. Terimlerini ve bağlamlarını kullanırlar. Önemli detayları atlıyorlar. Tıpkı onlar gibi, 20 yıldır şirketlerinde olduğunuzu varsayıyorlar. Bu, birçok müşterinin en başta ne istediğini bilmemesi gerçeğiyle birleşiyor! Bazıları "büyük resmi" kavrayabilir, ancak vizyonlarının ayrıntılarını nadiren etkili bir şekilde iletebilirler. Diğerleri tam vizyon konusunda biraz daha hafif olabilir, ancak ne istemediklerini biliyorlar. Peki, ne istedikleri hakkında size tüm gerçeği söylemeyen birine bir yazılım projesini nasıl teslim edebilirsiniz? Oldukça basit. Sadece onlarla daha fazla etkileşime geçin. + +Müşterilerinize erken ve sık sık meydan okuyun. Size istediklerini söylediklerini kendi sözleriyle yeniden ifade etmeyin. Unutmayın: Size söylediklerini kastetmediler. Bunu genellikle onlarla konuşurken kelimeleri değiştirerek ve tepkilerini değerlendirerek yaparım. *Müşteri* teriminin kaç kez *müşteri* teriminden tamamen farklı bir anlama sahip olduğuna şaşıracaksınız. Yine de size yazılım projesinde ne istediğini söyleyen adam, terimleri birbirinin yerine kullanacak ve hangisinden bahsettiğini takip etmenizi bekleyecektir. Kafanız karışacak ve yazdığınız yazılım zarar görecek. + +Neye ihtiyaç duyduklarını anladığınıza karar vermeden önce, müşterilerinizle konuları defalarca tartışın. Sorunu onlarla iki veya üç kez yeniden ifade etmeyi deneyin. Daha iyi bir bağlam elde etmek için konuştuğunuz konudan hemen önce veya hemen sonra olan şeyler hakkında onlarla konuşun. Mümkünse, birden fazla kişinin size aynı konuyu ayrı konuşmalarda anlatmasını sağlayın. Neredeyse her zaman size farklı ama birbiriyle ilişkili gerçekleri ortaya çıkaracak farklı hikayeler anlatacaklar. Size aynı konuyu anlatan iki kişi genellikle birbiriyle çelişir. Başarı için en iyi şansınız, ultra karmaşık yazılım oluşturmaya başlamadan önce farklılıkları ortaya çıkarmaktır. + +Görüşmelerinizde görsel araçlar kullanın. Bu, bir toplantıda beyaz tahta kullanmak kadar basit, tasarım aşamasında görsel bir maket oluşturmak kadar kolay veya işlevsel bir prototip hazırlamak kadar karmaşık olabilir. Bir konuşma sırasında görsel yardımcıların kullanılmasının dikkat süremizi uzatmaya yardımcı olduğu ve bilgilerin akılda kalma oranını artırdığı genel olarak bilinmektedir. Bu gerçeği kullanın ve projenizi başarıya hazırlayın. + +Geçmiş hayatımda, gösterişli projeler üreten bir ekipte "multimedya programcısı"ydım. Bir müşterimiz, projenin görünümü ve hissiyatı hakkındaki düşüncelerini çok detaylı bir şekilde anlattı. Tasarım toplantılarında tartışılan genel renk şeması, sunum için siyah bir arka plan gösterdi. Çivilediğimizi sanmıştık. Grafik tasarımcılarından oluşan ekipler, yüzlerce katmanlı grafik dosyasını dağıtmaya başladı. Nihai ürünü kalıplamak için çok zaman harcandı. Müşteriye emeğimizin meyvelerini gösterdiğimiz gün şaşırtıcı bir açıklama yapıldı. Ürünü gördüğünde, arka plan rengiyle ilgili sözleri tam olarak "Siyah derken beyazı kastetmiştim" idi. Yani görüyorsun, asla siyah ve beyaz kadar net değil. + +[Nate Jackson](http://programmer.97things.oreilly.com/wiki/index.php/Icnatejackson) Tarafından